mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +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:
parent
b962a44a4d
commit
6538a26a47
@ -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)
|
||||
|
||||
|
@ -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."
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user