3

In GeoDjango I found that I can use WKT to insert geometry such as:

pnt = GEOSGeometry('POINT(5 23)')

but it doesn't show how to do it if the data is KML, as my data is in KML format, so my plan is to convert KML -> WKT -> GEOSGeometry.

Is there a way to convert KML to WKT using GeoDjango or using any Python library?

1
  • You are probably asking a wrong question for solving your problem. I believe that WKT is an unnecessary step and you can ask directly how to convert KML into geodjango. This may give a partial answer stackoverflow.com/questions/8000033/….
    – user30184
    Commented Sep 24, 2014 at 6:16

3 Answers 3

3

Here is a working solution, that assumes you have your KML data in a string. If its in a file, you can skip the first step where a temp file is created. The KML driver from ogr only reads from file as far as I know.

Tthere might be some more elegant ways of converting the ogr feature to a GEOSGeometry (without converting it to json and back). But this is the first solution that I could come up with.

import tempfile, json
from StringIO import StringIO
from osgeo import ogr
from django.contrib.gis.geos import GEOSGeometry

# Set testdata string
testdata = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Placemark>
    <name>Simple placemark</name>
    <description>Attached to the ground. Intelligently places itself 
       at the height of the underlying terrain.</description>
    <Point>
      <coordinates>-122.0822035425683,37.42228990140251</coordinates>
    </Point>
  </Placemark>
</kml>"""

# Create tempfile for ogr driver read
temp = tempfile.NamedTemporaryFile()
temp.write(testdata)
temp.flush()

# Read XML file into python
driver = ogr.GetDriverByName('KML')
datasource = driver.Open(temp.name)
layer = datasource.GetLayer()
feat = layer.GetNextFeature()

# Convert ogr feature to GEOSGeometry
feat_json = json.loads(feat.ExportToJson())
feat_json['geometry']['coordinates'] = feat_json['geometry']['coordinates'][0:2]
geom = json.dumps(feat_json['geometry'])
pnt = GEOSGeometry(geom)

Then you get

print pnt
POINT (-122.0822035425682941 37.4222899014025074)
2
  • at line feat_json = json.loads(x.ExportToJson()) where do you define x, got an error NameError: name 'x' is not defined ? thanks Commented Sep 29, 2014 at 2:38
  • Sorry that was stil in there from when I was playing around with it in the shell. The x should have been feat. I edited my answer to fix this.
    – yellowcap
    Commented Sep 29, 2014 at 6:51
2

Also you can do it by GDAL/OGR:

ogr2ogr -overwrite -f CSV -dsco GEOMETRY=AS_WKT output.csv input.kml

0

With fastkml you can do it quite easily:

from fastkml.utils import find_all
from fastkml import KML
from fastkml import Placemark
k = KML.parse("docs/Document-clean.kml")
placemarks = find_all(k, of_type=Placemark)
for p in placemarks:
    print(p.geometry)  

POINT Z (-123.93563168 49.16716103 5.0)
POLYGON Z ((-123.940449937288 49.16927524669021 17.0, ...

more in the documentation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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