PythonライブラリShapelyで使用するためのKMLファイルの変換


8

KMLファイル(wijken.kml)をShapelyに取得しようとしています。KMLファイルは適切なXMLスキーマに対して検証されるので、入力は正しいと思います。

私が試したルート:

1)WKTまたはWKB形式に変換し、組み込み関数で読み込む

変換:

ogr2ogr -f CSV wijken.csv wijken.kml -lco GEOMETRY=AS_WKT
ogr2ogr -f SQLite wijken.wkb wijken.kml

形に:

from shapely import wkt, wkb
f = open('../kml/wijken.wkb')
wkb.load(f) 

これは(と同じwkt())を与えます:

ReadingError: Could not create geometry because of errors while reading input.

それはそれ以上の情報を提供せず、Pythonコードは他の(C?)ライブラリをラップするため、フォーマットの何が問題なのかわかりません。CSVファイルには複数の列が含まれていますが、おそらくそこに何か問題がありますが、テストできる同等のオンラインWKTの例が見つかりません。

2)GeoJSONに変換し、Shapely asShape関数でビルドを使用する

ogr2ogr2 -f GeoJSON wijken.json wijken.kml

形に:

import json
from shapely.geometry import asShape
f = open('wijken.json', 'r')
js = json.load(f)
f.close()
asShape(js)

それは与える:

ValueError: Unknown geometry type: featurecollection

このエラーは、最小限の有効なGeoJSONの例でも同じです。Shapleyコードを見ると、問題は「Feature」や「FeatureCollection」などの基本的なGeoJSONタイプが認識されないことです。GeoJSONの機能からShapelyが理解できる機能にたどり着くためのルートは明確ではありません。

3)とKMLで読み出さfastkml格好の良いオブジェクトを返し、

これは機能しますが、KMLのプロパティ/ ExtendedData値が失われるようです(または少なくともShapelyオブジェクトに渡されません)。

何か不足しているように感じます。Shapelyにデータを取り込むのはそれほど難しくありません。誰かが私を最も堅牢で実用的なソリューションに向けることができますか?

回答:


8

Shapelyは、フィーチャやフィーチャのコレクションではなく、幾何学的オブジェクトを扱います。shape()のマニュアルを参照してください。

(JSONを使用した)コードは次のようになります。

import json
from shapely.geometry import shape
f = open('wijken.json', 'r')
js = json.load(f)
f.close()

for f in js['features']:    
    s = shape(f['geometry'])
    ...

1

線とポリゴンを形の良いものにするには、maps.google.comでマイマップを使用し、KMLとしてエクスポートしてから、次の小さな関数を使用しました。

def ExtractPoints(kml):
  rv = {}
  ns = "{http://earth.google.com/kml/2.2}"
  tree = ElementTree()
  tree.parse(kml)
  for placemark in tree.findall(".//" + ns + "Placemark"):
    name = placemark.findtext(ns + "name")
    print "Found %s" % name
    coordinates_text = placemark.findtext(ns + "LineString/" + ns + "coordinates")
    coordinates = []
    for point_text in coordinates_text.split():
      floats = point_text.split(",")
      coordinates.append((float(floats[0]), float(floats[1])))
    if coordinates[0] == coordinates[-1]:
      rv[name] = Polygon(coordinates)
    else:
      rv[name] = LineString(coordinates)
  return rv

PS:Seanの回答にコメントを追加する方法はわかりませんが、なぜ彼がKeytreeに言及しなかったのか疑問に思います。これは、別の同様の質問で見つかりました:特定の緯度経度がKML線形リングにあるかどうかを調べる方法かっこいい

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.