如何用SimpleKML和Python在Google Earth绘制圆形?代码问题排查
KML圆形显示为椭圆形的问题原因及解决方法
核心问题原因
- 坐标顺序不符合KML规范:KML要求坐标格式为
(经度, 纬度),但你的代码中将纬度放在前、经度放在后,这会导致图形严重错位变形,尤其在高纬度地区(你的中心点接近南极,该问题被放大)。 - 模块导入错误:main.py中导入的
kml模块实际是你编写的KMY.py,需修正导入语句。 - 高纬度投影特性:接近极地时,Google Earth的墨卡托投影会让真实圆形看起来略有椭圆,但修复坐标顺序后,图形会准确对应3000英尺的实际半径。
修正后的代码
修正后的KMY.py
import math def calc_angular_distance(radius): '''(number) -> float Return the angular distance from radius Precondition: radius is measure in feet >>>calc_angular_distance(1500) 7.176267461936767e-05 >>>calc_angular_distance(3000) 0.00014352534923873535 >>>calc_angular_distance(5000) 0.00023920891539789223 ''' earth_radius_ft = 20902230.971129 return radius / earth_radius_ft def generate_circle(lat_deg, lon_deg, radius): angular_distance = calc_angular_distance(radius) lat_rad = math.radians(lat_deg) lon_rad = math.radians(lon_deg) # 生成圆周点角度,步长5度,最后闭合图形 angles = [float(x) for x in range(0, 360, 5)] angles.append(0.0) coordinates = [] for angle in angles: 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)) new_lat = math.degrees(new_lat) new_lon = math.degrees(new_lon) # 修正KML坐标顺序:(经度, 纬度) coordinates.append((new_lon, new_lat)) return coordinates
修正后的main.py
import KMY as kml import simplekml # 生成3000英尺半径的圆周坐标 collection = kml.generate_circle(lat_deg=-88.88155337981863, lon_deg=30.442919411754943, radius=3000) kml_obj = simplekml.Kml() pol = kml_obj.newpolygon() pol.tessellate = 1 pol.altitudemode = simplekml.AltitudeMode.clamptoground # 开启测地线,确保球面图形准确 pol.geodesic = True pol.outerboundaryis.coords = collection kml_obj.save("CorrectCircle.kml")
更简便的实现方式
使用Google Earth扩展的gx:Circle元素,无需手动计算圆周点,直接指定中心点和半径即可:
import simplekml # 英尺转米(gx:Circle半径单位为米) radius_ft = 3000 radius_m = radius_ft * 0.3048 kml = simplekml.Kml() # 创建gx:Circle,坐标格式为(经度, 纬度) circle = kml.newgxcircle( name="3000英尺半径圆", coords=[(30.442919411754943, -88.88155337981863)], radius=radius_m ) # 设置贴合地面 circle.altitudemode = simplekml.AltitudeMode.clamptoground # 可选:设置半透明样式 style = kml.newstyle() style.polystyle.color = simplekml.Color.changealphaint(100, simplekml.Color.blue) circle.style = style kml.save("SimpleCircle.kml")
内容的提问来源于stack exchange,提问作者J.R. Woodcock
相关产品推荐
相关产品推荐

