Mengonversi file KML untuk digunakan dengan pustaka Python Shapely

8

Saya mencoba untuk mendapatkan KML file ( wijken.kml ) ke Shapely . File KML divalidasi terhadap skema XML yang tepat, jadi saya kira input sudah benar.

Rute yang saya coba:

1) Konversi ke format WKT atau WKB, dan membaca dengan fungsi built in

Konversi:

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

Dalam bentuk:

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

Yang memberi (sama untuk wkt()):

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

Karena tidak memberikan info lebih lanjut, dan kode Python membungkus perpustakaan lain (C?), Saya tidak tahu apa yang salah dengan format. File CSV berisi banyak kolom, mungkin ada yang salah di sana, tetapi saya belum menemukan contoh WKT online yang dapat diuji.

2) Konversi ke GeoJSON dan menggunakan membangun di Shapely asShapefungsi

ogr2ogr2 -f GeoJSON wijken.json wijken.kml

Dalam Bentuk:

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

Pemberian yang mana:

ValueError: Unknown geometry type: featurecollection

Kesalahan ini sama dengan contoh GeoJSON yang minimal dan valid. Melihat kode Shapley, masalahnya adalah tipe GeoJSON dasar seperti "Fitur" dan "FeatureCollection" tidak dikenali. Tidak jelas rute mana yang harus diambil untuk mendapatkan dari fitur GeoJSON ke fitur yang dimengerti oleh Shapely.

3) Baca dalam KML dengan fastkml , yang mengembalikan objek Shapely

Ini berfungsi, tetapi tampaknya kehilangan properti / nilai ExtendedData di KML (atau setidaknya tidak meneruskannya ke objek Shapely).

Saya merasa bahwa saya kehilangan sesuatu, tidak mungkin begitu sulit untuk mendapatkan data ke Shapely. Bisakah seseorang mengarahkan saya ke solusi yang paling kuat / bekerja?

mansher
sumber

Jawaban:

9

Berurusan dengan objek geometris, bukan fitur atau kumpulan fitur. Lihat manual pada bentuk () .

Kode Anda (dengan JSON) dapat berupa:

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
sumber
1

Untuk mendapatkan garis dan poligon dalam bentuk, saya menggunakan Petaku di maps.google.com, mengekspornya sebagai KML dan kemudian menggunakan fungsi kecil ini:

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: Saya tidak melihat cara untuk menambahkan komentar pada jawaban Sean tetapi bertanya-tanya mengapa dia tidak menyebutkan Keytree, yang saya temukan melalui pertanyaan lain yang serupa: Bagaimana saya mencari tahu apakah lat lat yang diberikan ada dalam cincin KML Linear menggunakan rupawan?

TomGoBravo
sumber