1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

gis: NULL geometries are now allowed (thanks Robert Coup!), field parameter no longer needed for _post_create_sql(), and added extra instance methods for SpatialReference/SRID.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5448 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-06-09 19:55:42 +00:00
parent b962a44a4d
commit 6538a26a47
3 changed files with 39 additions and 20 deletions

View File

@ -5,31 +5,39 @@ from django.contrib.gis.gdal import OGRGeometry, SpatialReference
# Until model subclassing is a possibility, a mixin class is used to add
# the necessary functions that may be contributed for geographic objects.
class GeoMixin:
"The Geographic Mixin class, provides routines for geographic objects."
"The Geographic Mixin class provides routines for geographic objects."
# A subclass of Model is specifically needed so that these geographic
# routines are present for instantiations of the models.
def _get_GEOM_geos(self, field):
"Gets a GEOS Python object for the geometry."
"Returns a GEOS Python object for the geometry."
return GEOSGeometry(getattr(self, field.attname), 'hex')
def _get_GEOM_ogr(self, field, srid):
"Gets an OGR Python object for the geometry."
"Returns an OGR Python object for the geometry."
return OGRGeometry(hex_to_wkt(getattr(self, field.attname)),
SpatialReference('EPSG:%d' % srid))
def _get_GEOM_srid(self, srid):
"Returns the spatial reference identifier (SRID) of the geometry."
return srid
def _get_GEOM_srs(self, srid):
"Returns ane OGR Spatial Reference object of the geometry."
return SpatialReference('EPSG:%d' % srid)
def _get_GEOM_wkt(self, field):
"Gets the WKT of the geometry."
"Returns the WKT of the geometry."
hex = getattr(self, field.attname)
return hex_to_wkt(hex)
def _get_GEOM_centroid(self, field):
"Gets the centroid of the geometry, in WKT."
"Returns the centroid of the geometry, in WKT."
hex = getattr(self, field.attname)
return centroid(hex)
def _get_GEOM_area(self, field):
"Gets the area of the geometry, in projected units."
"Returns the area of the geometry, in projected units."
hex = getattr(self, field.attname)
return area(hex)

View File

@ -33,47 +33,56 @@ class GeometryField(Field):
self._dim = dim
super(GeometryField, self).__init__(**kwargs) # Calling the parent initializtion function
def _add_geom(self, style, db_table, field):
def _add_geom(self, style, db_table):
"""Constructs the addition of the geometry to the table using the
AddGeometryColumn(...) PostGIS (and OGC standard) function.
AddGeometryColumn(...) PostGIS (and OGC standard) stored procedure.
Takes the style object (provides syntax highlighting) as well as the
database table and field.
Takes the style object (provides syntax highlighting) and the
database table as parameters.
"""
sql = style.SQL_KEYWORD('SELECT ') + \
style.SQL_TABLE('AddGeometryColumn') + '(' + \
style.SQL_TABLE(quotename(db_table)) + ', ' + \
style.SQL_FIELD(quotename(field)) + ', ' + \
style.SQL_FIELD(quotename(self.column)) + ', ' + \
style.SQL_FIELD(str(self._srid)) + ', ' + \
style.SQL_COLTYPE(quotename(self._geom)) + ', ' + \
style.SQL_KEYWORD(str(self._dim)) + ');'
if not self.null:
# Add a NOT NULL constraint to the field
sql += '\n' + \
style.SQL_KEYWORD('ALTER TABLE ') + \
style.SQL_TABLE(quotename(db_table, dbl=True)) + \
style.SQL_KEYWORD(' ALTER ') + \
style.SQL_FIELD(quotename(self.column, dbl=True)) + \
style.SQL_KEYWORD(' SET NOT NULL') + ';'
return sql
def _geom_index(self, style, db_table, field,
def _geom_index(self, style, db_table,
index_type='GIST', index_opts='GIST_GEOMETRY_OPS'):
"Creates a GiST index for this geometry field."
sql = style.SQL_KEYWORD('CREATE INDEX ') + \
style.SQL_TABLE(quotename('%s_%s_id' % (db_table, field), dbl=True)) + \
style.SQL_TABLE(quotename('%s_%s_id' % (db_table, self.column), dbl=True)) + \
style.SQL_KEYWORD(' ON ') + \
style.SQL_TABLE(quotename(db_table, dbl=True)) + \
style.SQL_KEYWORD(' USING ') + \
style.SQL_COLTYPE(index_type) + ' ( ' + \
style.SQL_FIELD(quotename(field, dbl=True)) + ' ' + \
style.SQL_FIELD(quotename(self.column, dbl=True)) + ' ' + \
style.SQL_KEYWORD(index_opts) + ' );'
return sql
def _post_create_sql(self, style, db_table, field):
def _post_create_sql(self, style, db_table):
"""Returns SQL that will be executed after the model has been
created. Geometry columns must be added after creation with the
PostGIS AddGeometryColumn() function."""
# Getting the AddGeometryColumn() SQL necessary to create a PostGIS
# geometry field.
post_sql = self._add_geom(style, db_table, field)
post_sql = self._add_geom(style, db_table)
# If the user wants to index this data, then get the indexing SQL as well.
if self._index:
return '%s\n%s' % (post_sql, self._geom_index(style, db_table, field))
return '%s\n%s' % (post_sql, self._geom_index(style, db_table))
else:
return post_sql
@ -83,6 +92,8 @@ class GeometryField(Field):
# Adding needed accessor functions
setattr(cls, 'get_%s_geos' % self.name, curry(cls._get_GEOM_geos, field=self))
setattr(cls, 'get_%s_ogr' % self.name, curry(cls._get_GEOM_ogr, field=self, srid=self._srid))
setattr(cls, 'get_%s_srid' % self.name, curry(cls._get_GEOM_srid, srid=self._srid))
setattr(cls, 'get_%s_srs' % self.name, curry(cls._get_GEOM_srs, srid=self._srid))
setattr(cls, 'get_%s_wkt' % self.name, curry(cls._get_GEOM_wkt, field=self))
setattr(cls, 'get_%s_centroid' % self.name, curry(cls._get_GEOM_centroid, field=self))
setattr(cls, 'get_%s_area' % self.name, curry(cls._get_GEOM_area, field=self))
@ -94,12 +105,12 @@ class GeometryField(Field):
"""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)]
return [value and ("SRID=%d;%s" % (self._srid, value)) or None]
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)
return value and ("SRID=%d;%s" % (self._srid, value)) or None
def get_manipulator_field_objs(self):
"Using the WKTField (defined above) to be our manipulator."

View File

@ -388,7 +388,7 @@ def get_custom_sql_for_model(model):
for f in opts.fields:
if hasattr(f, '_post_create_sql'):
output.append(f._post_create_sql(style, model._meta.db_table, f.column))
output.append(f._post_create_sql(style, model._meta.db_table))
return output