2

What is the best way to store e.q. rectangles in Django? I was thinking about something like

start_position = models.CommaSeparatedIntegerField(max_length=10,
                                                   blank=True,
                                                   null=True)
heigh = models.IntegerField(blank=True,
                            null=True)
width = models.IntegerField(blank=True,
                            null=True)

in my model, but somehow this don't look correct. Is there a better way doing this? Would there be a way to have also collision detection maybe?

frlan
  • 6,950
  • 3
  • 31
  • 72
  • Possible duplicate of [How do I use Django's MultiWidget?](http://stackoverflow.com/questions/3511855/how-do-i-use-djangos-multiwidget) – Sayse Dec 05 '15 at 21:54
  • Ah, linked the wrong thing... you can make your own field that is made up of multiple fields (finding link) – Sayse Dec 05 '15 at 21:55
  • [Here's a small example of one](https://gist.github.com/elena/3915748) was making a version of an answer but I can't test it right now and it will involve some debugging to get working for your field.. – Sayse Dec 05 '15 at 22:04
  • I'm not sure whether I was really looking for something like the MultiWidget-feature which is cool beyond doubt. I think I had in my mind something like a Django app maybe offering also collision detection between two areas. – frlan Dec 06 '15 at 08:28

2 Answers2

3

You can use GIS for your database, so in settings.py:

DATABASES = {
    'default' : {
        'ENGINE' : 'django.contrib.gis.db.backends.postgis',
        'NAME' : 'geodjango',
    }
}

And for your model.py, first import GeoDjango:

from django.contrib.gis.db import models

Then make your model, for example:

class Feature(models.Model):
    rectangle = models.MultiPolygonField(srid=900913, blank=True, null=True)
approxiblue
  • 6,982
  • 16
  • 51
  • 59
2

GeoDjango should do all you need. In particular, a rectangle is a special case of a polygon, so this works:

from django.contrib.gis.db.models import Model, GeoManager, PolygonField

class MyModel(Model):
    rect = models.PolygonField()

    objects = GeoManager()

# the envelope polygon around two points is a rectangle
from django.contrib.gis.geos import Point, GeometryCollection
rect = GeometryCollection(Point(10, 10), Point(20, 20)).envelope
MyModel.objects.create(rect=rect)

Lookup can be performed directly on the database (possibly making use of spatial indexing):

from django.contrib.gis.geos import Point
p = Point(15, 15)
MyModel.objects.filter(rect__contains=p)

Note that GeoDjango requires additional libraries and --most importantly-- a database backend that supports spatial SQL. See the setup guide for GeoDjango for details, but be wary when using sqlite as the default setup of spatiallite might not work out of the box without special install instructions.

dhke
  • 15,008
  • 2
  • 39
  • 56