【问题标题】:How to plot data from a .kml file using matplotlib on python 3.7 and Windows 10"?如何在 python 3.7 和 Windows 10 上使用 matplotlib 从 .kml 文件中绘制数据?
【发布时间】:2022-07-08 04:05:36
【问题描述】:

我将首先为我的问题提供一些背景信息。

我在网站上获得了世界各地领海的 .kml 文件:https://www.marineregions.org/downloads.php,我想不在 Google 地球上显示它,而是在 matplotlib.pyplot 图上显示(如果可能的话,附上地图也)。 .kml 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<NetworkLink>
    <name>Territorial Seas (12NM) v3</name>
    <description><![CDATA[Flanders Marine Institute (2019). Maritime Boundaries Geodatabase: Territorial Seas (12NM), version 3. Available online at <a href="http://www.marineregions.org">http://www.marineregions.org</a> https://doi.org/10.14284/387. Consulted on YYYY-MM-DD.]]></description>
    <Link>
        <href>http://geo.vliz.be/geoserver/gwc/service/kml/MarineRegions:eez_12nm.png.kml</href>
    </Link>
</NetworkLink>
</kml>

为此,我在另一个 stackoverflow 问题 (Reading KML Files Using Fastkml) 上看到使用 fastkml 读取文件是可能的。

这是我正在尝试运行的 test.py 代码(它来自使用指南https://fastkml.readthedocs.io/en/latest/usage_guide.html#read-a-kml-file-string):

from fastkml import  kml

filename = "C:\\Users\\dumasal\\Documents\\GOOGLE_EARTH\\MarineRegions-eez_12nm.kml"
with open(filename, 'rt', encoding="utf-8") as myfile:
    doc=myfile.read()
    print(doc)
    
    # Create the KML object to store the parsed result
    k = kml.KML()
    
    # Read in the KML string
    k.from_string(doc)
    print('k = ', k)
    
    ### Next we perform some simple sanity checks ###
    
    # Check that the number of features is correct
    # This corresponds to the single ``Document``
    features = list(k.features())
    print(len(features))
    
    # Check that we can access the features as a generator
    # (The two Placemarks of the Document)
    print(features[0].features())
    f2 = list(features[0].features())
    print(len(f2))
    
    # Check specifics of the first Placemark in the Document
    print(f2[0])
    print(f2[0].description)
    print(f2[0].name)
    
    # Check specifics of the second Placemark in the Document
    print(f2[1].name)
    f2[1].name = "ANOTHER NAME"
    
    # Verify that we can print back out the KML object as a string
    print(k.to_string(prettyprint=True))

当我运行它时,我得到了错误:“ValueError: Unicode strings with encoding declaration is not supported. Please use bytes input or XML fragment without declaration.”。

我在 google 上查找了错误并找到了这个 git-hub 页面 (https://github.com/cleder/fastkml/issues/57),他们说“from_string()”函数只需要字节,所以我的代码的开头可以更改为:

from fastkml import  kml

filename = "C:\\Users\\dumasal\\Documents\\GOOGLE_EARTH\\MarineRegions-eez_12nm.kml"
with open(filename, 'r') as myfile:
    doc=myfile.read().encode('UTF-8')
    print(doc)
    
    # Create the KML object to store the parsed result
    k = kml.KML()
    
    # Read in the KML string
    k.from_string(doc)
    print('k = ', k)

    ### Next we perform some simple sanity checks ###
    
    # Check that the number of features is correct
    # This corresponds to the single ``Document``
    features = list(k.features())
    print(len(features))

奇怪的是,ValueError 停止出现了。但是现在我得到了错误:

IndexError: list index out of range

这是因为我的变量 features = [],我不知道为什么。

那么您能否向我解释一下为什么 features 变量为空,或者用 python 和 matplotlib 绘制 .kml 文件的更直接的方法?

非常感谢!

【问题讨论】:

  • 嘿,正如我所见,您还可以将所有数据集作为 shapefile 获取……为什么不直接使用它们呢? (你可以简单地用 geopandas 阅读它们)

标签: python-3.x matplotlib windows-10 kml valueerror


【解决方案1】:

您的源 KML 文件具有 Networklinks,而 fastkml 尚未实现 NetworkLinks。

pyKML 包解析 KML 文件并遍历网络链接中引用的 KML 层。

您可以这样做来枚举 NetworkLinks 和 KML 内容。

import requests
from pykml import parser
import re

count = 0

def walk(elt):
    global count
    for elt in elt.getchildren():
        tag = re.sub(r'^.*\}', '', elt.tag)
        if tag in ['Folder', 'Document']:
            walk(elt)
        elif tag == 'NetworkLink':
            print(tag)
            print(elt.Link.href)
            if count == 10:
                # for debugging stop after 10 links
                raise Exception("too many links")
            count += 1
            response = requests.get(elt.Link.href)
            walk(parser.fromstring(response.content))
        else:
            print(">>", tag)

with open("MarineRegions-eez_12nm.kml", 'rb') as myfile:
    root = parser.parse(myfile).getroot()
walk(root)

但请注意,MarineRegions KML 递归地细分为较小的区域,因此尝试在所有级别绘制 GroundOverlay 将用较小的高分辨率覆盖覆盖较大的低分辨率覆盖。您需要决定是否只需要高分辨率地面覆盖层或低分辨率覆盖层。例如,如果 KML 没有任何 NetworkLink,则它处于最低级别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 2017-07-11
    • 2012-11-12
    相关资源
    最近更新 更多