Loading django/contrib/gis/db/models/fields.py +36 −58 Original line number Diff line number Diff line Loading @@ -182,6 +182,25 @@ class BaseSpatialField(Field): else: return connection.ops.Adapter(self.get_prep_value(value)) def get_raster_prep_value(self, value, is_candidate): """ Return a GDALRaster if conversion is successful, otherwise return None. """ from django.contrib.gis.gdal import GDALRaster if isinstance(value, GDALRaster): return value elif is_candidate: try: return GDALRaster(value) except GDALException: pass elif isinstance(value, dict): try: return GDALRaster(value) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % value) def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be Loading @@ -190,9 +209,8 @@ class BaseSpatialField(Field): geometry or raster value properly and preserves any other lookup parameters. """ from django.contrib.gis.gdal import GDALRaster value = super(BaseSpatialField, self).get_prep_value(value) # For IsValid lookups, boolean values are allowed. if isinstance(value, (Expression, bool)): return value Loading @@ -205,20 +223,22 @@ class BaseSpatialField(Field): # When the input is not a geometry or raster, attempt to construct one # from the given string input. if isinstance(obj, (Geometry, GDALRaster)): if isinstance(obj, Geometry): pass elif isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__'): else: # Check if input is a candidate for conversion to raster or geometry. is_candidate = isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__') # With GDAL installed, try to convert the input to raster. raster = False if HAS_GDAL: raster = self.get_raster_prep_value(obj, is_candidate) if raster: obj = raster elif is_candidate: try: obj = Geometry(obj) except (GeometryException, GDALException): try: obj = GDALRaster(obj) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) elif isinstance(obj, dict): try: obj = GDALRaster(obj) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) else: raise ValueError('Cannot use object with type %s for a spatial lookup parameter.' % type(obj).__name__) Loading Loading @@ -295,48 +315,6 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField): """ return connection.ops.get_distance(self, value, lookup_type) def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be converted to) a geometry, or a sequence of lookup values that begins with a geometry. This routine will setup the geometry value properly, and preserve any other lookup parameters before returning to the caller. """ from django.contrib.gis.gdal import GDALRaster value = super(GeometryField, self).get_prep_value(value) if isinstance(value, (Expression, bool)): return value elif isinstance(value, (tuple, list)): geom = value[0] seq_value = True else: geom = value seq_value = False # When the input is not a GEOS geometry, attempt to construct one # from the given string input. if isinstance(geom, (Geometry, GDALRaster)): pass elif isinstance(geom, (bytes, six.string_types)) or hasattr(geom, '__geo_interface__'): try: geom = Geometry(geom) except GeometryException: raise ValueError('Could not create geometry from lookup value.') else: raise ValueError('Cannot use object with type %s for a geometry lookup parameter.' % type(geom).__name__) # Assigning the SRID value. geom.srid = self.get_srid(geom) if seq_value: lookup_val = [geom] lookup_val.extend(value[1:]) return tuple(lookup_val) else: return geom def from_db_value(self, value, expression, connection, context): if value: if not isinstance(value, Geometry): Loading tests/gis_tests/gis_migrations/test_operations.py +5 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from unittest import skipUnless from django.contrib.gis.db.models import fields from django.contrib.gis.gdal import HAS_GDAL from django.core.exceptions import ImproperlyConfigured from django.db import connection, migrations, models from django.db.migrations.migration import Migration Loading Loading @@ -114,6 +117,7 @@ class OperationTests(TransactionTestCase): self.assertSpatialIndexExists('gis_neighborhood', 'heatmap') @skipIfDBFeature('supports_raster') @skipUnless(HAS_GDAL, 'A different error is raised if GDAL is not installed.') def test_create_raster_model_on_db_without_raster_support(self): """ Test creating a model with a raster field on a db without raster support. Loading @@ -123,6 +127,7 @@ class OperationTests(TransactionTestCase): self.set_up_test_model(True) @skipIfDBFeature('supports_raster') @skipUnless(HAS_GDAL, 'A different error is raised if GDAL is not installed.') def test_add_raster_field_on_db_without_raster_support(self): """ Test adding a raster field on a db without raster support. Loading Loading
django/contrib/gis/db/models/fields.py +36 −58 Original line number Diff line number Diff line Loading @@ -182,6 +182,25 @@ class BaseSpatialField(Field): else: return connection.ops.Adapter(self.get_prep_value(value)) def get_raster_prep_value(self, value, is_candidate): """ Return a GDALRaster if conversion is successful, otherwise return None. """ from django.contrib.gis.gdal import GDALRaster if isinstance(value, GDALRaster): return value elif is_candidate: try: return GDALRaster(value) except GDALException: pass elif isinstance(value, dict): try: return GDALRaster(value) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % value) def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be Loading @@ -190,9 +209,8 @@ class BaseSpatialField(Field): geometry or raster value properly and preserves any other lookup parameters. """ from django.contrib.gis.gdal import GDALRaster value = super(BaseSpatialField, self).get_prep_value(value) # For IsValid lookups, boolean values are allowed. if isinstance(value, (Expression, bool)): return value Loading @@ -205,20 +223,22 @@ class BaseSpatialField(Field): # When the input is not a geometry or raster, attempt to construct one # from the given string input. if isinstance(obj, (Geometry, GDALRaster)): if isinstance(obj, Geometry): pass elif isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__'): else: # Check if input is a candidate for conversion to raster or geometry. is_candidate = isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__') # With GDAL installed, try to convert the input to raster. raster = False if HAS_GDAL: raster = self.get_raster_prep_value(obj, is_candidate) if raster: obj = raster elif is_candidate: try: obj = Geometry(obj) except (GeometryException, GDALException): try: obj = GDALRaster(obj) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) elif isinstance(obj, dict): try: obj = GDALRaster(obj) except GDALException: raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) else: raise ValueError('Cannot use object with type %s for a spatial lookup parameter.' % type(obj).__name__) Loading Loading @@ -295,48 +315,6 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField): """ return connection.ops.get_distance(self, value, lookup_type) def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be converted to) a geometry, or a sequence of lookup values that begins with a geometry. This routine will setup the geometry value properly, and preserve any other lookup parameters before returning to the caller. """ from django.contrib.gis.gdal import GDALRaster value = super(GeometryField, self).get_prep_value(value) if isinstance(value, (Expression, bool)): return value elif isinstance(value, (tuple, list)): geom = value[0] seq_value = True else: geom = value seq_value = False # When the input is not a GEOS geometry, attempt to construct one # from the given string input. if isinstance(geom, (Geometry, GDALRaster)): pass elif isinstance(geom, (bytes, six.string_types)) or hasattr(geom, '__geo_interface__'): try: geom = Geometry(geom) except GeometryException: raise ValueError('Could not create geometry from lookup value.') else: raise ValueError('Cannot use object with type %s for a geometry lookup parameter.' % type(geom).__name__) # Assigning the SRID value. geom.srid = self.get_srid(geom) if seq_value: lookup_val = [geom] lookup_val.extend(value[1:]) return tuple(lookup_val) else: return geom def from_db_value(self, value, expression, connection, context): if value: if not isinstance(value, Geometry): Loading
tests/gis_tests/gis_migrations/test_operations.py +5 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from unittest import skipUnless from django.contrib.gis.db.models import fields from django.contrib.gis.gdal import HAS_GDAL from django.core.exceptions import ImproperlyConfigured from django.db import connection, migrations, models from django.db.migrations.migration import Migration Loading Loading @@ -114,6 +117,7 @@ class OperationTests(TransactionTestCase): self.assertSpatialIndexExists('gis_neighborhood', 'heatmap') @skipIfDBFeature('supports_raster') @skipUnless(HAS_GDAL, 'A different error is raised if GDAL is not installed.') def test_create_raster_model_on_db_without_raster_support(self): """ Test creating a model with a raster field on a db without raster support. Loading @@ -123,6 +127,7 @@ class OperationTests(TransactionTestCase): self.set_up_test_model(True) @skipIfDBFeature('supports_raster') @skipUnless(HAS_GDAL, 'A different error is raised if GDAL is not installed.') def test_add_raster_field_on_db_without_raster_support(self): """ Test adding a raster field on a db without raster support. Loading