diff --git a/django/contrib/gis/db/models/fields/__init__.py b/django/contrib/gis/db/models/fields/__init__.py index 7b4423bdc1..e2aedbcdb3 100644 --- a/django/contrib/gis/db/models/fields/__init__.py +++ b/django/contrib/gis/db/models/fields/__init__.py @@ -1,12 +1,9 @@ -from django.db import models +# The Django base Field class. from django.db.models.fields import Field -#from GeoTypes import Point +from django.contrib.gis.db.models.postgis import POSTGIS_TERMS -# Creates the SQL to add the model to the database. Defaults to using an -# SRID of 4326 (WGS84 Datum -- 'normal' lat/lon coordinates) +# Creates the SQL to add the model to the database. def _add_geom(geom, srid, style, model, field, dim=2): - from django.db import backend - # Constructing the AddGeometryColumn(...) command -- the style # object is passed in from the management module and is used # to syntax highlight the command for 'sqlall' @@ -15,16 +12,38 @@ def _add_geom(geom, srid, style, model, field, dim=2): style.SQL_TABLE(model) + "', '" + \ style.SQL_FIELD(field) + "', " + \ style.SQL_FIELD(str(srid)) + ", '" + \ - style.SQL_KEYWORD(geom) + "', " + \ + style.SQL_COLTYPE(geom) + "', " + \ style.SQL_KEYWORD(str(dim)) + \ ');' return sql +# Creates an index for the given geometry. +def _geom_index(geom, style, model, field, + index_type='GIST', + index_opts='GIST_GEOMETRY_OPTS'): + sql = style.SQL_KEYWORD('CREATE INDEX ') + \ + style.SQL_FIELD(field + '_idx') + \ + style.SQL_KEYWORD(' ON ') + \ + style.SQL_TABLE(model) + \ + style.SQL_KEYWORD(' USING ') + \ + style.SQL_COLTYPE(index_type) + ' ( ' + \ + style.SQL_FIELD(field) + ' ' + \ + style.SQL_KEYWORD(index_opts) + ' );' + return sql + class GeometryField(Field): - """The base GIS field -- maps to an OpenGIS Geometry type.""" - + "The base GIS field -- maps to the OpenGIS Geometry type." + + # The OpenGIS Geometry name. _geom = 'GEOMETRY' - _srid = 4326 + + def __init__(self, srid=4326, index=False, **kwargs): + # 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" @@ -32,44 +51,43 @@ 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.""" - return _add_geom(self._geom, self._srid, *args, **kwargs) + post_sql = _add_geom(self._geom, self._srid, *args, **kwargs) + 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 + else: + return post_sql def get_db_prep_lookup(self, lookup_type, value): - "Returns field's value prepared for database lookup." - if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search', 'overlaps'): - return [value] - elif lookup_type in ('range', 'in'): - return value - elif lookup_type in ('contains', 'icontains'): - return ["%%%s%%" % prep_for_like_query(value)] - elif lookup_type == 'iexact': - return [prep_for_like_query(value)] - elif lookup_type in ('startswith', 'istartswith'): - return ["%s%%" % prep_for_like_query(value)] - elif lookup_type in ('endswith', 'iendswith'): - return ["%%%s" % prep_for_like_query(value)] - elif lookup_type == 'isnull': - return [] - elif lookup_type == 'year': - try: - value = int(value) - except ValueError: - raise ValueError("The __year lookup type requires an integer argument") - return ['%s-01-01 00:00:00' % value, '%s-12-31 23:59:59.999999' % value] + """Returns field's value prepared for database lookup; the SRID of the geometry is + included by default in these queries.""" + if lookup_type in POSTGIS_TERMS: + return ['SRID=%d;%s' % (self._srid, value)] raise TypeError("Field has invalid lookup: %s" % lookup_type) def get_db_prep_save(self, value): + "Making sure the SRID is included before saving." return 'SRID=%d;%s' % (self._srid, value) - +# The OpenGIS Geometry Type Fields class PointField(GeometryField): _geom = 'POINT' +class LineString(GeometryField): + _geom = 'LINESTRING' + class PolygonField(GeometryField): _geom = 'POLYGON' +class MultiPointField(GeometryField): + _geom = 'MULTIPOINT' + +class MultiLineStringField(GeometryField): + _geom = 'MULTILINESTRING' + class MultiPolygonField(GeometryField): _geom = 'MULTIPOLYGON' -class GeometryManager(models.Manager): - pass +class GeometryCollectionField(GeometryField): + _geom = 'GEOMETRYCOLLECTION'