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 have a big interrogation about how it could be possible to have a GeoDjango app that can store in database the uploaded shapefiles (or other geospatial files) from users. When you load shapefiles in GeoDjango, you have to create a new model that matches the fields of the shapefile. How could it be possible to create a new model automatically each time a user uploads a files? You can't append the new model definition to your models.py each time? For me, that does not make any sense.

Does it means the best way is to use a generic model definition and only allow files upload that match this definition,and then to create a new instance of this generic model? Can someone explain me what is the best practice to create an app that can store users uploaded spatial files?

share|improve this question
add comment

1 Answer

You are right, adding a new model to models.py each time is impossible. And, if it where, you would end up with a lot of unmanageable tables.

One option is to use a schema-less datastore (i.e. a NoSQL database) but then you'd loose the spaial capabilities of PostGIS (or have to use both PostGIS and a NoSQL db, no fun!). And then there's the concept of "hstore" in PostgreSQL which allows you to store a set of key/value pairs in a single column. Unfortunately, the django-hstore lib requires its own db.backend definition, this would result in a conflict with the geodjango-backend.

This means that the solution I would recommend is one described in the book "Python Geospatial Development". I'll just outline the approach here, either you get the idea or you could get yourself a copy of the book for a more thourough explaination.

In brief:

Model your app like this:

class Shapefile(models.Model):
    filename = models.CharField(max_length=255)
    srs = models.CharField(max_length=255)
    geom_type = models.CharField(max_length=50)
    encoding = models.CharField(max_length=20)

class Attribute(models.Model):
    shapefile = models.ForeignKey(Shapefile)
    name = models.CharField(max_length=255)
    type = models.IntegerField()
    width = models.IntegerField()
    precision = models.IntegerField()

class Feature(models.Model):
    shapefile = models.ForeignKey(Shapefile)
    geom_point = models.PointField(srid=4326, blank=True, null=true)
    geom_multipoint = models.MultiPointField(srid=4326, blank=True, null=true)
    geom_multilinestring = models.MultiLineStringField(srid=4326, blank=True, null=true)
    geom_multipolygon = models.MultiPolygonField(srid=4326, blank=True, null=true)
    geom_geometrycollection = models.GeometryCollectionField(srid=4326, blank=True, null=true)

    objects = models.GeoManager()

class AttributeValue(models.Model):
    feature = models.ForeignKey(Feature)
    attribute = models.ForeignKey(Attribute)
    value = models.CharField(max_length=255, blank=True, null=true)

In this way the shapefile schema is modeled in a set of relations

share|improve this answer
    
you can combine django-hstore backend with geodjango backend easily: follow this groups.google.com/forum/?fromgroups#!topic/django-users/… . The problem with this kind of generic models is the slowness when you upload table with many features. You can also take a look at dynamic models. –  Below the Radar Jun 1 '13 at 14:19
1  
Thank you for your answer! However, I think that the real solution for this issue is not yet created. We need a plugin in geodjango that will connect to uploaded tables in database maybe without model definition. –  Below the Radar Jun 1 '13 at 14:36
add comment

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.