使用 Python 在 KML 中的 LineString 线周围创建以米为单位的缓冲区空间

Creating buffer spaces in meters around LineString line in KML using Python

关于使用 python 在 kml 线串上创建缓冲区 spaces 有什么建议吗?我尝试了几个库..

geojson
shapely
kml2geojson

此处,将 kml 转换为 geojson 并在线串上添加缓冲区 space,输出应为多边形


import kml2geojson
import json

from shapely.geometry import shape
from geojson import Point, Feature, FeatureCollection, dump

filename = "filekml"
direction = "left"
numbers = 5
kml2geojson.main.convert(filename + '.kml', '')
features = []
try:

    with open(filename + '.geojson') as geojson_file:
        data = json.load(geojson_file)
        for feat in data['features']:
            if direction == "left":
                result = shape(feat['geometry']).buffer(numbers, single_sided=True)
            if direction == "right":
                result = shape(feat['geometry']).buffer(-numbers, single_sided=True)
            if direction == "both":
                result = shape(feat['geometry']).buffer(numbers)
            features.append(Feature(geometry=result))
        feature_collection = FeatureCollection(features)
        with open(filename + '.geojson', 'w') as f:
            dump(feature_collection, f)
        f.close()
except Exception as e:
    print(e)

下面是kml

<?xml version="1.0" encoding="utf-8" ?>
<kml>
<Document id="root_doc">
<Folder><name>Test</name>
  <Placemark>
    <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
      <MultiGeometry><LineString><coordinates>-93.3367092468336,30.4822077397353 -93.3367001199999,30.482718171</coordinates></LineString></MultiGeometry>
  </Placemark>
</Folder>
</Document></kml>

下面是输出 (Geojson)

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -93.3367,
              30.482718
            ],
            [
              -93.336709,
              30.482208
            ],
            [
              -93.336722,
              30.482208
            ],
            [
              -93.336713,
              30.482718
            ],
            [
              -93.3367,
              30.482718
            ]
          ]
        ]
      },
      "properties": {}
    }
  ]
}

请提出任何创建缓冲区 space 行或点的建议。

使用 python 在 kml 中创建缓冲区空间对我来说有点复杂,所以我尝试将 kml 转换为 geojson 并能够在其上添加缓冲区空间,..使用以下库,

kml2geojson

使用 kml2geojson 库将 kml 或 kmz 文件转换为 geojson.. 和

shapely

使用形状库为所有线和点添加了缓冲空间.. 阅读上述库的一些文档以避免任何疑问..

谢谢

要在 WGS84 坐标中缓冲一条线并将其延长一段距离(以米为单位),您可以使用 shapely 和 pyproj 进行重投影,然后使用 simplekml 将形状导出到 KML。

方位角等距投影(又名 aeqd)是一种方位角地图投影,它在地图上提供与中心点成比例正确距离的点。在 aeqd 坐标 space 中创建缓冲线,然后重新投影到 WGS-84。

from shapely.geometry import LineString, CAP_STYLE
from pyproj import Transformer
from shapely.ops import transform
import simplekml

# pick 2 end points of a line with longitude and latitude
pt1 = [-0.14062046656000524, 51.501870264040775]
pt2 = [-0.12901012017525443, 51.50659618852008]

# buffer length in meters
width = 100

lons = [pt1[0], pt2[0]]
lats = [pt1[1], pt2[1]]

# create Azimuthal Equidistant (aeqd) projection with units in meters
# with the center of projection at the center of the line
local_azimuthal_projection = "+proj=aeqd +R=6371000 +units=m +lat_0={} +lon_0={}".format(
    (lats[0] + lats[1]) / 2, (lons[0] + lons[1]) / 2
)
wgs84_to_aeqd = Transformer.from_proj('+proj=longlat +datum=WGS84 +no_defs',
                                      local_azimuthal_projection)
aeqd_to_wgs84 = Transformer.from_proj(local_azimuthal_projection,
                                      '+proj=longlat +datum=WGS84 +no_defs')

line_transformed = transform(wgs84_to_aeqd.transform,
                             LineString([pt1, pt2]))

buffer = line_transformed.buffer(width, cap_style=CAP_STYLE.square)
line_wgs84 = transform(aeqd_to_wgs84.transform, buffer)

# Next export as KML

kml = simplekml.Kml()
# add start and end points to the KML to show the points
kml.newpoint(coords=[(lons[0], lats[0])])
kml.newpoint(coords=[(lons[1], lats[1])])
ls = kml.newlinestring(tessellate=1,
                       coords=list(line_wgs84.exterior.coords),
                       altitudemode=simplekml.AltitudeMode.clamptoground)
ls.style.linestyle.color = 'ffff00aa'  # purple
ls.style.linestyle.width = 3
kml.save("line.kml")

输出:

这条线被缓冲了 100 米的长度添加到线的端点,这样每条边的长度都是 200 米。

或者,您可以使用 Google 地球专业版中的标尺工具测量一条线的起点和终点的距离 n-meters,然后手动在其周围绘制边界并保存地标作为 KML 文件。