KML 中的圆形多边形仅在预览中显示
Circular polygon in KML only showing in preview
背景:
由于 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 后,文件本身和多边形在 'My Places' 中可见,但多边形不会出现在地图上 - 而是默认为 0,0 位置。
据我所知,KML 对于以逆时针顺序列出的多边形的坐标顺序非常讲究,我尝试重新格式化我的 KML 文件以允许这样做 - 但同样的事情再次发生并且多边形仍然没有显示。除此之外,GE 属性框中的不透明度将多边形显示为具有 100% 的不透明度,因此多边形应该绝对可见。
我对 KML 还是比较陌生,很想学习如何通过生成坐标点而不是简单地使用可用的在线 KML 圆生成器工具来创建圆。我发现关于此问题的文档非常少(如果有的话),因此将不胜感激!
您的 KML 文件在每个坐标对的逗号后都有一个额外的 space。如果你删除那些 spaces,多边形就会出现(在印度洋)。在这种情况下看起来像椭圆形,这可能是投影问题?
坐标应如下所示:51.15743964817757,-0.18433
逗号后(坐标对内)不应有 space,但可以有 space(或行 return 就像你一样)分离坐标对。我对 Python 了解不多,但我认为您只需更改一行即可删除 space,如下所示:
# 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
表示 100 米高)。您可以为每个坐标对添加高度数字,或者只需将 altitudeMode 更改为 "clampToGround",这是默认设置,会将要素放在陆地上的地形或水面上的海面上。
背景:
由于 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 后,文件本身和多边形在 'My Places' 中可见,但多边形不会出现在地图上 - 而是默认为 0,0 位置。
据我所知,KML 对于以逆时针顺序列出的多边形的坐标顺序非常讲究,我尝试重新格式化我的 KML 文件以允许这样做 - 但同样的事情再次发生并且多边形仍然没有显示。除此之外,GE 属性框中的不透明度将多边形显示为具有 100% 的不透明度,因此多边形应该绝对可见。
我对 KML 还是比较陌生,很想学习如何通过生成坐标点而不是简单地使用可用的在线 KML 圆生成器工具来创建圆。我发现关于此问题的文档非常少(如果有的话),因此将不胜感激!
您的 KML 文件在每个坐标对的逗号后都有一个额外的 space。如果你删除那些 spaces,多边形就会出现(在印度洋)。在这种情况下看起来像椭圆形,这可能是投影问题?
坐标应如下所示:51.15743964817757,-0.18433
逗号后(坐标对内)不应有 space,但可以有 space(或行 return 就像你一样)分离坐标对。我对 Python 了解不多,但我认为您只需更改一行即可删除 space,如下所示:
# 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
表示 100 米高)。您可以为每个坐标对添加高度数字,或者只需将 altitudeMode 更改为 "clampToGround",这是默认设置,会将要素放在陆地上的地形或水面上的海面上。