Konvertieren von KML-Dateien zur Verwendung mit der Python-Bibliothek Shapely

8

Ich versuche eine KML-Datei ( wijken.kml ) in Shapely zu bekommen . Die KML-Datei wird anhand des richtigen XML-Schemas validiert, daher denke ich, dass die Eingabe korrekt ist.

Routen, die ich versucht habe:

1) Konvertieren in das WKT- oder WKB-Format und Einlesen mit integrierten Funktionen

Umwandlung:

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

In Form:

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

Welches gibt (das gleiche für wkt()):

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

Da es keine weiteren Informationen enthält und der Python-Code andere (C?) Bibliotheken umschließt, weiß ich nicht, was mit dem Format nicht stimmt. Die CSV-Datei enthält mehrere Spalten, vielleicht stimmt dort etwas nicht, aber ich habe kein vergleichbares Online-WKT-Beispiel zum Testen gefunden.

2) Konvertieren in GeoJSON und Verwenden der eingebauten Shapely- asShapeFunktion

ogr2ogr2 -f GeoJSON wijken.json wijken.kml

In Shapely:

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

Welches gibt:

ValueError: Unknown geometry type: featurecollection

Dieser Fehler ist für ein minimales, gültiges GeoJSON-Beispiel gleich. Beim Betrachten des Shapley-Codes besteht das Problem darin, dass grundlegende GeoJSON-Typen wie "Feature" und "FeatureCollection" nicht erkannt werden. Es ist nicht klar, welchen Weg Sie von GeoJSON-Funktionen zu Funktionen gehen müssen, die Shapely versteht.

3) Lesen Sie KML mit fastkml ein , das Shapely-Objekte zurückgibt

Dies funktioniert, aber es scheint, dass die Eigenschaften / ExtendedData-Werte in der KML verloren gehen (oder zumindest nicht an die Shapely-Objekte übergeben werden).

Ich habe das Gefühl, dass mir etwas fehlt. Es kann nicht so schwer sein, Daten in Shapely zu bekommen. Kann mich jemand auf die robusteste / funktionierende Lösung hinweisen?

Mhermans
quelle

Antworten:

8

Behandelt formschön geometrische Objekte, keine Features oder Feature-Sammlungen. Siehe das Handbuch zu Form () .

Ihr Code (mit JSON) könnte sein:

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'])
    ...
sgillies
quelle
1

Um einige Linien und Polygone in Form zu bringen, habe ich My Maps unter maps.google.com verwendet, als KML exportiert und dann diese kleine Funktion verwendet:

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: Ich sehe keine Möglichkeit, Seans Antwort mit einem Kommentar zu versehen, frage mich aber, warum er Keytree nicht erwähnt hat, den ich über eine andere ähnliche Frage gefunden habe: Wie finde ich heraus, ob sich ein bestimmtes Lat Lon in einem linearen KML-Ring befindet? mit formschön?

TomGoBravo
quelle