GeoDjango Import Data from KML File
There are some cases, you need to import the KML data to a Django project. Share and collaborate on KML has a complex folder structure (many sub-folders in sub-folder). If a KML is the flat-folder structure, you could use LayerMapping to extract all the features and place them in the database. This is my foolish code to accomplish it.
# My Project Structure
.
├── my_env
├── my_proj
├── manage.py
├── my_app
└── static
# my_app Structure
.
├── admin.py
├── apps.py
├── data
├── __init__.py
├── load_lines.py
├── migrations
├── models
├── __pycache__
├── tests.py
├── urls.py
└── views
# my_line Model
class Line(models.Model):
"""
Model representing a geometry line string
"""
name = models.CharField(max_length=254)
geom = models.LineStringField(srid=4326, null=True, blank=True,)
layer_name = models.CharField(max_length=254, blank=True, null=True,)
description = models.TextField(max_length=1000, blank=True,null=True,)
Place your KML file into the data
app folder:
# my_app/data
.
├── metro.kml
Create a load_lines.py
in my_app
for extract the LineString geometry from KML.
Copy and paste code in each section into your load_lines.py
Import Modules
import os
from django.contrib.gis.gdal import DataSource
from django.contrib.gis.geos import GEOSGeometry, LineString, WKTWriter
from my_app.models import Line
Reading Data
kml_file = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'data', 'metro.kml'),
)
# Reading Data by DataSource
source = DataSource(kml_file)
Make a get_feat_property()
Function
def get_feat_property(feat):
# Get the feature property.
property = {
'name': feat.get('Name'),
'description': feat.get('description'),
}
return property
Make a run()
function
# Writes the Well-Known Text representation of a Geometry.
wkt_w = WKTWriter()
def run(verbose=True):
# Iterating Over Layers
for layer in source:
for feat in layer:
if(feat.geom.geom_type.name.startswith('Line')):
# Get the feature geometry.
geom = feat.geom
# get the feature property
property = get_feat_property(feat)
if (len(geom.coords) >= 2 ):
line = Line.objects.create(
name = property['name'],
description = property['description'],
layer_name = feat.layer_name,
# Make a GeosGeometry object
geom = GEOSGeometry(wkt_w.write(geom.geos)),
)
Import the Spatial Data into GeoDjango models
$ python manage.py shell
>>> from my_app import load_lines
>>> load_lines.run()