Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to get a KML-file (wijken.kml) into Shapely. The KML-file is validated against the proper XML schema, so I guess the input is correct.

Routes I have tried:

1) Converting to WKT or WKB format, and reading in with build in functions

Conversion:

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

In shapely:

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

Which gives (same for wkt()):

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

As it provides no further info, and the Python code wraps other (C?) libraries, I do not know what is wrong with the format. The CSV-file contains multiple columns, perhaps something is wrong there, but I have not found a comparable online WKT-example to test.

2) Converting to GeoJSON and using the build in Shapely asShape function

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)

Which gives:

ValueError: Unknown geometry type: featurecollection

This error is the same for a minimal, valid GeoJSON example. Looking at the Shapley code, the problem is that basic GeoJSON types such as "Feature" and "FeatureCollection" are not recognised. It is not clear which route to take to get from GeoJSON features to features Shapely understands.

3) Read in KML with fastkml, which returns Shapely objects

This works, but it seems to lose the properties/ExtendedData values in the KML (or at least does not pass it to the Shapely objects).

I feel that I'm missing something, it can't be so hard to get data into Shapely. Can someone point me towards the most robust/a working solution?

share|improve this question

2 Answers 2

up vote 6 down vote accepted

Shapely deals with geometric objects, not features or collections of features. See the manual on shape().

Your code (with JSON) could be:

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'])
    ...
share|improve this answer

To get some line and polygons into shapely I used My Maps at maps.google.com, exported it as KML and then used this little function:

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: I don't see a way to add a comment to Sean's answer but wonder why he didn't mention Keytree, which I found via another similar question: How do I find out if a given lat lon is in a KML Linear ring using shapely?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.