| 1 | | from geos import geomFromWKT, geomToWKT |
|---|
| 2 | | from decimal import Decimal |
|---|
| 3 | | from django.db import models |
|---|
| 4 | | from django.db.models.query import QuerySet |
|---|
| 5 | | |
|---|
| 6 | | |
|---|
| 7 | | class GeoQuerySet(QuerySet): |
|---|
| 8 | | # The list of valid query terms |
|---|
| 9 | | # override the local QUERY_TERMS in the namespace |
|---|
| 10 | | # not sure how to do that locals() hackery |
|---|
| 11 | | # possibly in the init change its locals() variables |
|---|
| 12 | | # not sure if that will work |
|---|
| 13 | | |
|---|
| 14 | | QUERY_TERMS = ( |
|---|
| 15 | | 'exact', 'iexact', 'contains', 'icontains', 'overlaps', |
|---|
| 16 | | 'gt', 'gte', 'lt', 'lte', 'in', |
|---|
| 17 | | 'startswith', 'istartswith', 'endswith', 'iendswith', |
|---|
| 18 | | 'range', 'year', 'month', 'day', 'isnull', 'search', |
|---|
| 19 | | ) |
|---|
| 20 | | |
|---|
| 21 | | |
|---|
| 22 | | def dprint(arg): |
|---|
| 23 | | import re |
|---|
| 24 | | import inspect |
|---|
| 25 | | print re.match("^\s*dprint\(\s*(.+)\s*\)", inspect.stack()[1][4][0]).group(1) + ": " + repr(arg) |
|---|
| 26 | | |
|---|
| 27 | | |
|---|
| 28 | | |
|---|
| 29 | | class GeometryManager(models.Manager): |
|---|
| 30 | | #def filter(self, *args, **kwargs): |
|---|
| 31 | | # super(Manager, self).filter(*args, **kwargs) |
|---|
| 32 | | # return self.get_query_set().filter(*args, **kwargs) |
|---|
| 33 | | |
|---|
| 34 | | def get_query_set(self): |
|---|
| 35 | | return GeoQuerySet(self.model) |
|---|
| 36 | | |
|---|
| 37 | | |
|---|
| 38 | | |
|---|
| 39 | | |
|---|
| 40 | | class BoundingBox: |
|---|
| 41 | | |
|---|
| 42 | | def _geom(self): |
|---|
| 43 | | return geomToWKT(self._g) |
|---|
| 44 | | |
|---|
| 45 | | geom = property(_geom) |
|---|
| 46 | | |
|---|
| 47 | | def _area(self): |
|---|
| 48 | | return self._g.area() |
|---|
| 49 | | |
|---|
| 50 | | area = property(_area) |
|---|
| 51 | | |
|---|
| 52 | | |
|---|
| 53 | | def __init__(self, ne, sw): |
|---|
| 54 | | """ |
|---|
| 55 | | Create a bounding box using two points |
|---|
| 56 | | This points come from a JSON request, so they are strings |
|---|
| 57 | | """ |
|---|
| 58 | | ne = [Decimal(i.strip(' ')) for i in ne[1:-1].split(',')] |
|---|
| 59 | | sw = [Decimal(i.strip(' ')) for i in sw[1:-1].split(',')] |
|---|
| 60 | | ne_lat = ne[0] |
|---|
| 61 | | ne_lng = ne[1] |
|---|
| 62 | | sw_lat = sw[0] |
|---|
| 63 | | sw_lng = sw[1] |
|---|
| 64 | | bb = 'POLYGON((' |
|---|
| 65 | | bb += str(ne_lng) + " " + str(ne_lat) + "," |
|---|
| 66 | | bb += str(ne_lng) + " " + str(sw_lat) + "," |
|---|
| 67 | | bb += str(sw_lng) + " " + str(sw_lat) + "," |
|---|
| 68 | | bb += str(sw_lng) + " " + str(ne_lat) + "," |
|---|
| 69 | | bb += str(ne_lng) + " " + str(ne_lat) |
|---|
| 70 | | bb += '))' |
|---|
| 71 | | self._g = geomFromWKT(bb) |
|---|