summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/gis/db/models/__init__.py2
-rw-r--r--django/contrib/gis/db/models/fields/__init__.py51
-rw-r--r--django/contrib/gis/db/models/postgis.py18
3 files changed, 49 insertions, 22 deletions
diff --git a/django/contrib/gis/db/models/__init__.py b/django/contrib/gis/db/models/__init__.py
index cffa6e9b61..5117ac60f6 100644
--- a/django/contrib/gis/db/models/__init__.py
+++ b/django/contrib/gis/db/models/__init__.py
@@ -6,7 +6,7 @@ from django.contrib.gis.db.models.manager import GeoManager
# The various PostGIS/OpenGIS enabled fields.
from django.contrib.gis.db.models.fields import \
- GeometryField, PointField, LineString, PolygonField, \
+ GeometryField, PointField, LineStringField, PolygonField, \
MultiPointField, MultiLineStringField, MultiPolygonField, \
GeometryCollectionField
diff --git a/django/contrib/gis/db/models/fields/__init__.py b/django/contrib/gis/db/models/fields/__init__.py
index e2aedbcdb3..50c8bb6ef0 100644
--- a/django/contrib/gis/db/models/fields/__init__.py
+++ b/django/contrib/gis/db/models/fields/__init__.py
@@ -1,6 +1,10 @@
# The Django base Field class.
from django.db.models.fields import Field
+from django.oldforms import LargeTextField
from django.contrib.gis.db.models.postgis import POSTGIS_TERMS
+from geos import geomToWKT, geomFromHEX
+
+#TODO: add db.quotename.
# Creates the SQL to add the model to the database.
def _add_geom(geom, srid, style, model, field, dim=2):
@@ -20,17 +24,26 @@ def _add_geom(geom, srid, style, model, field, dim=2):
# Creates an index for the given geometry.
def _geom_index(geom, style, model, field,
index_type='GIST',
- index_opts='GIST_GEOMETRY_OPTS'):
+ index_opts='GIST_GEOMETRY_OPS'):
sql = style.SQL_KEYWORD('CREATE INDEX ') + \
- style.SQL_FIELD(field + '_idx') + \
+ style.SQL_TABLE('"%s_%s_id"' % (model, field)) + \
style.SQL_KEYWORD(' ON ') + \
- style.SQL_TABLE(model) + \
+ style.SQL_TABLE('"%s"' % model) + \
style.SQL_KEYWORD(' USING ') + \
style.SQL_COLTYPE(index_type) + ' ( ' + \
- style.SQL_FIELD(field) + ' ' + \
+ style.SQL_FIELD('"%s"' % field) + ' ' + \
style.SQL_KEYWORD(index_opts) + ' );'
return sql
+class WKTField(LargeTextField):
+ "An oldforms LargeTextField for editing WKT text in the admin."
+
+ def render(self, data):
+ # PostGIS uses EWKBHEX to store its values internally, converting
+ # to WKT for the admin first.
+ wkt = geomToWKT(geomFromHEX(data))
+ return super(WKTField, self).render(wkt)
+
class GeometryField(Field):
"The base GIS field -- maps to the OpenGIS Geometry type."
@@ -38,12 +51,19 @@ class GeometryField(Field):
_geom = 'GEOMETRY'
def __init__(self, srid=4326, index=False, **kwargs):
+ #TODO: SRID a standard, or specific to postgis?
+ # Whether or not index this field, defaults to False
+ # Why can't we just use db_index?
+ # TODO: Move index creation (and kwarg lookup, and...)
+ # into Field rather than core.management and db.models.query.
+ self._index = index
+
+ # The SRID for the geometry, defaults to 4326.
+ self._srid = srid
+
# Calling the Field initialization function first
super(GeometryField, self).__init__(**kwargs)
- # The SRID for the geometry, defaults to 4326
- self._srid = srid
- self._index = index
def get_internal_type(self):
return "NoField"
@@ -51,11 +71,16 @@ class GeometryField(Field):
def _post_create_sql(self, *args, **kwargs):
"""Returns SQL that will be executed after the model has been created. Geometry
columns must be added after creation with the PostGIS AddGeometryColumn() function."""
+
+ #TODO: clean up *args/**kwargs.
+
+ # Getting the AddGeometryColumn() SQL necessary to create a PostGIS
+ # geometry field.
post_sql = _add_geom(self._geom, self._srid, *args, **kwargs)
+
+ # If the user wants to index this data, then get the indexing SQL as well.
if self._index:
- # Creating geometry indices doesn't yet work.
- #return '%s\n%s' % (post_sql, _geom_index(self._geom, *args, **kwargs))
- return post_sql
+ return '%s\n%s' % (post_sql, _geom_index(self._geom, *args, **kwargs))
else:
return post_sql
@@ -69,12 +94,16 @@ class GeometryField(Field):
def get_db_prep_save(self, value):
"Making sure the SRID is included before saving."
return 'SRID=%d;%s' % (self._srid, value)
+
+ def get_manipulator_field_objs(self):
+ "Using the WKTField (defined above) to be our manipulator."
+ return [WKTField]
# The OpenGIS Geometry Type Fields
class PointField(GeometryField):
_geom = 'POINT'
-class LineString(GeometryField):
+class LineStringField(GeometryField):
_geom = 'LINESTRING'
class PolygonField(GeometryField):
diff --git a/django/contrib/gis/db/models/postgis.py b/django/contrib/gis/db/models/postgis.py
index e4fd492dbf..34455dc85c 100644
--- a/django/contrib/gis/db/models/postgis.py
+++ b/django/contrib/gis/db/models/postgis.py
@@ -2,33 +2,31 @@
# django.db.models.query objects to be customized for PostGIS.
from copy import copy
from django.db import backend
-from django.db.models.query import \
- LOOKUP_SEPARATOR, QUERY_TERMS, \
- find_field, FieldFound, get_where_clause
+from django.db.models.query import LOOKUP_SEPARATOR, find_field, FieldFound
from django.utils.datastructures import SortedDict
# PostGIS-specific operators. The commented descriptions of these
# operators come from Section 6.2.2 of the official PostGIS documentation.
POSTGIS_OPERATORS = {
# The "&<" operator returns true if A's bounding box overlaps or is to the left of B's bounding box.
- 'overlapsleft' : '&< %s',
+ 'overlaps_left' : '&< %s',
# The "&>" operator returns true if A's bounding box overlaps or is to the right of B's bounding box.
- 'overlapsright' : '&> %s',
+ 'overlaps_right' : '&> %s',
# The "<<" operator returns true if A's bounding box is strictly to the left of B's bounding box.
'left' : '<< %s',
# The ">>" operator returns true if A's bounding box is strictly to the right of B's bounding box.
'right' : '>> %s',
# The "&<|" operator returns true if A's bounding box overlaps or is below B's bounding box.
- 'overlapsbelow' : '&<| %s',
+ 'overlaps_below' : '&<| %s',
# The "|&>" operator returns true if A's bounding box overlaps or is above B's bounding box.
- 'overlapsabove' : '|&> %s',
+ 'overlaps_above' : '|&> %s',
# The "<<|" operator returns true if A's bounding box is strictly below B's bounding box.
- 'strictlybelow' : '<<| %s',
+ 'strictly_below' : '<<| %s',
# The "|>>" operator returns true if A's bounding box is strictly above B's bounding box.
- 'strictlyabove' : '|>> %s',
+ 'strictly_above' : '|>> %s',
# The "~=" operator is the "same as" operator. It tests actual geometric equality of two features. So if
# A and B are the same feature, vertex-by-vertex, the operator returns true.
- 'sameas' : '~= %s',
+ 'same_as' : '~= %s',
# The "@" operator returns true if A's bounding box is completely contained by B's bounding box.
'contained' : '@ %s',
# The "~" operator returns true if A's bounding box completely contains B's bounding box.