[GIS] Load multipolygons from GeoJSON into GeoDjango model

geodjangogeojsongeos

I have a simple model:

from django.contrib.gis.db import models

class CountryShapes(models.Model):
    geonameid = models.PositiveIntegerField(primary_key=True)
    geom = models.MultiPolygonField()

and a GeoJSON file from here:
http://download.geonames.org/export/dump/shapes_simplified_low.json.zip

I am attempting to load the data into my model using this:

        import json
        from django.contrib.gis.geos import GEOSGeometry

        with open('shapes_simplified_low.json', 'r') as fd:
            data = json.load(fd)
            for feature in data['features']:

                geom = GEOSGeometry(str(feature['geometry']))
                geonameid = feature['properties']['geoNameId']

                country = CountryShapes( # throws error here
                    geonameid=geonameid,
                    geom=GEOSGeometry(geom))
                country.save()

and I get this error:

TypeError: Cannot set CountryShapes SpatialProxy (MULTIPOLYGON) with
value of type: class 'django.contrib.gis.geos.polygon.Polygon'

GEOSGeometry seems to create the geometry fine, its when I pass the geom argument to my model it throws the error.

Best Answer

The issue: You're trying to save a feature of type 'Polygon' to a field defined for MultiPolygons. (You'll notice a list of geojson features often have both Polygons and MultiPolygons.)

I'm using this hack: If a feature is type Polygon, change it to type MultiPolygon by changing type and putting the coordinates within an array.

    geom = GEOSGeometry(str(feature['geometry']))
    if geom.type == 'Polygon':
      geom['type'] = 'MultiPolygon'
      geom['coordinates'] = [feature['geometry']['coordinates']]

    geonameid = feature['properties']['geoNameId']

    country = CountryShapes( # throws error here
        geonameid=geonameid,
        geom=GEOSGeometry(geom))
    country.save()

PS: I have almost no experience in Python.