python - KML 中的圆形多边形仅在预览中显示

标签 python kml google-earth

背景:

由于 GE 没有内置的圆函数,我在 Python 中生成了一些代码来创建围绕中心点的坐标列表(以十进制度为单位)——这应该形成一个圆。在同一个 Python 脚本中,我创建了一个 KML 文件(恰本地命名为“circles”),其中生成的坐标点以某种格式写入,该格式应允许它们成为我尝试创建的圆形多边形的顶点.

这是生成圆的坐标点并将其导出到 KML 文件的 Python 脚本:

import math

# opens a file for writing/ creates it if it does not exist
file = open ('circles.kml', 'w+')


def generate_circle(file, lat_deg, lon_deg, radius_km):

    # Mean Earth radius (needed for calculation).
    earth_radius_km = 6371
    earth_radius_m = earth_radius_km * 1000

    # Distance is entered in km, convert to meters.
    radius_m = radius_km * 1000
    angular_distance = radius_m/earth_radius_m

    # Convert coordinates from degrees to radians.
    lat_rad = math.radians(lat_deg)
    lon_rad = math.radians(lon_deg)

    # start generating KML code in file
    file.write ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" )
    file.write ("<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\">")
    file.write ("\n<Document>\n\t<Placemark>\n\t\t<name>Circle</name>\n" )
    file.write ("\t\t<Polygon>\n\t\t\t<extrude>1</extrude>\n\t\t\t<altitudeMode>relativeToGround</altitudeMode>\n\t\t\t<outerBoundaryIs>\n\t\t\t\t<LinearRing>\n\t\t\t\t\t<coordinates>\n")

    # Create a list of angles at which to create points (how many points will the circle consist of).
    numPoints = range(0, 360, 10)
    angles = []
    for x in numPoints:
        angles.append(float(x))
    angles.append(float(0))

    # Calculate and file.write out the list of coordinates.
    for angle in angles:

        # Convert bearing to radians and calculates new lat/lon values
        bearing = math.radians(angle)

        new_lat = math.asin(math.sin(lat_rad) * math.cos(angular_distance) + math.cos(lat_rad) * math.sin(angular_distance) * math.cos(bearing))

        new_lon = lon_rad + math.atan2(math.sin(bearing) * math.sin(angular_distance) * math.cos(lat_rad), math.cos(angular_distance) - math.sin(lat_rad) * math.sin(new_lat))

        # Convert new lat and lon to degrees
        new_lat_deg = math.degrees(new_lat)
        new_lon_deg = math.degrees(new_lon)

        # Print them out
        file.write ('\t\t\t\t\t\t{0}, {1}\n'.format (str(new_lat_deg), str(new_lon_deg)))

    # generates KML code to end file
    file.write ("\n\t\t\t\t\t</coordinates>\n\t\t\t\t</LinearRing>\n\t\t\t</outerBoundaryIs>\n\t\t</Polygon>")
    file.write ("\n\t</Placemark>\n</Document>\n</kml>")
    file.close ()

generate_circle(file, 51.13046, -0.18433, 3)

然后,该脚本使用以下代码生成“circles.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">
<Document>
    <Placemark>
        <name>Circle</name>
        <Polygon>
            <extrude>1</extrude>
            <altitudeMode>relativeToGround</altitudeMode>
            <outerBoundaryIs>
                <LinearRing>
                    <coordinates>
                        51.15743964817757, -0.18433
                        51.15702952889536, -0.17686020516372258
                        51.155811653802246, -0.16961776449158056
                        51.15382308927849, -0.1628230771806833
                        51.15112435160843, -0.15668284950397615
                        51.14779755677011, -0.15138378358603402
                        51.14394391134279, -0.14708688836809072
                        51.13968062247034, -0.14392258756569956
                        51.13513732257409, -0.14198677322557574
                        51.1304521191404, -0.14133792278558727
                        51.12576739098043, -0.1419953635060592
                        51.121225459580394, -0.1439387320133288
                        51.11696426736606, -0.14710863972615704
                        51.11311319387112, -0.1514085183214467
                        51.10978913602661, -0.15670758424327305
                        51.10709297028997, -0.16284482854858487
                        51.105106502425905, -0.16963390895039396
                        51.1038899958304, -0.176868795451506
                        51.10348035182245, -0.18433
                        51.1038899958304, -0.191791204548494
                        51.105106502425905, -0.19902609104960603
                        51.10709297028997, -0.20581517145141515
                        51.10978913602661, -0.21195241575672694
                        51.11311319387112, -0.2172514816785533
                        51.11696426736606, -0.22155136027384292
                        51.121225459580394, -0.2247212679866712
                        51.12576739098043, -0.22666463649394078
                        51.1304521191404, -0.22732207721441272
                        51.13513732257409, -0.22667322677442425
                        51.13968062247034, -0.22473741243430043
                        51.14394391134279, -0.22157311163190926
                        51.14779755677011, -0.21727621641396597
                        51.15112435160843, -0.21197715049602384
                        51.15382308927849, -0.20583692281931668
                        51.155811653802246, -0.19904223550841943
                        51.15702952889536, -0.1917997948362774
                        51.15743964817757, -0.18433
                    </coordinates>
                </LinearRing>
            </outerBoundaryIs>
        </Polygon>
    </Placemark>
</Document>
</kml>

问题:

将 KML 文件导入 GE 后,文件本身和多边形在“我的地点”中可见,但多边形不会出现在 map 上 - 而是默认为 0,0 位置。

据我所知,KML 对于按逆时针顺序列出的多边形的坐标顺序非常特殊,因此我尝试重新格式化我的 KML 文件以允许这种情况 - 但同样的事情再次发生,并且多边形仍然存在没有被显示。除此之外,GE 属性框中的不透明度显示多边形具有 100% 的不透明度,因此多边形应该是可见的。

我对 KML 还比较陌生,很想了解如何通过生成坐标点来创建圆,而不是简单地使用可用的在线 KML 圆生成器工具。我发现关于这个问题的文档很少(如果有的话),因此我们将不胜感激!!

最佳答案

您的 KML 文件在每个坐标对中的逗号后面都有一个额外的空格。如果删除这些空间,多边形就会出现(在印度洋中)。在这种情况下看起来像椭圆形,这可能是投影问题?

坐标应如下所示:51.15743964817757,-0.18433逗号后面(坐标对内部)不应有空格,但可以有空格(或像您一样的换行符)分隔坐标对。我对 Python 不太了解,但我认为你只需要更改一行即可删除空格,如下所示:

# Print them out    
file.write ('\t\t\t\t\t\t{0},{1}\n'.format (str(new_lat_deg), str(new_lon_deg)))

另外,请注意您有 <altitudeMode>设置为“relativeToGround”,通常用于将要素提升到地面以上...但您的坐标不包含任何高度值(这将是每个坐标中的第三项,例如: 51.15743,-0.18433,100 表示 100m 高) 。您可以向每个坐标对添加海拔高度数字,或者仅将海拔模式更改为“clampToGround”,这是默认设置,会将要素放置在陆地地形上或水面上的海面上。

关于python - KML 中的圆形多边形仅在预览中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52963887/

相关文章:

gis - 我如何获得矩形所有四个角的坐标?

kml - 定期加载 kml 文件以更新谷歌地球中的位置

google-maps - 如何将 Google 地球数据与 Google map 同步?

python - 结束 ssh session 后在后台运行 python/matplotlib 的问题

python - PySide 的 MVVM 模式

kml - 如何使用 NetworkLinkControl 和 Java API for KML (JAK) 正确更新 Google Earth KML?

c# - geckofx 的 Google 地球插件

linux - Linux 上的谷歌地球 API?

python - 最接近 Python 语法的语言是更底层的语言!

python - 无法在 matplotlib 中保存带注释的图像