diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index 19cf2eaa06c..a57ee16161f 100644 --- a/django/contrib/gis/db/backends/oracle/operations.py +++ b/django/contrib/gis/db/backends/oracle/operations.py @@ -15,8 +15,7 @@ from django.contrib.gis.db.backends.base.operations import ( from django.contrib.gis.db.backends.oracle.adapter import OracleSpatialAdapter from django.contrib.gis.db.backends.utils import SpatialOperator from django.contrib.gis.db.models import aggregates -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.geos.geometry import GEOSGeometryBase +from django.contrib.gis.geos.geometry import GEOSGeometry, GEOSGeometryBase from django.contrib.gis.geos.prototypes.io import wkb_r from django.contrib.gis.measure import Distance from django.db.backends.oracle.operations import DatabaseOperations @@ -119,7 +118,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations): # Generally, Oracle returns a polygon for the extent -- however, # it can return a single point if there's only one Point in the # table. - ext_geom = Geometry(memoryview(clob.read())) + ext_geom = GEOSGeometry(memoryview(clob.read())) gtype = str(ext_geom.geom_type) if gtype == 'Polygon': # Construct the 4-tuple from the coordinates in the polygon. diff --git a/django/contrib/gis/db/backends/postgis/adapter.py b/django/contrib/gis/db/backends/postgis/adapter.py index 7f855889dd6..39867ebc61f 100644 --- a/django/contrib/gis/db/backends/postgis/adapter.py +++ b/django/contrib/gis/db/backends/postgis/adapter.py @@ -5,7 +5,7 @@ from psycopg2 import Binary from psycopg2.extensions import ISQLQuote from django.contrib.gis.db.backends.postgis.pgraster import to_pgraster -from django.contrib.gis.geometry.backend import Geometry +from django.contrib.gis.geos import GEOSGeometry class PostGISAdapter: @@ -13,7 +13,7 @@ class PostGISAdapter: """ Initialize on the spatial object. """ - self.is_geometry = isinstance(obj, (Geometry, PostGISAdapter)) + self.is_geometry = isinstance(obj, (GEOSGeometry, PostGISAdapter)) # Getting the WKB (in string form, to allow easy pickling of # the adaptor) and the SRID from the geometry or raster. diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index c0ee23124d8..3fb821d94e9 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -9,8 +9,7 @@ from django.contrib.gis.db.backends.base.operations import ( from django.contrib.gis.db.backends.spatialite.adapter import SpatiaLiteAdapter from django.contrib.gis.db.backends.utils import SpatialOperator from django.contrib.gis.db.models import aggregates -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.geos.geometry import GEOSGeometryBase +from django.contrib.gis.geos.geometry import GEOSGeometry, GEOSGeometryBase from django.contrib.gis.geos.prototypes.io import wkb_r, wkt_r from django.contrib.gis.measure import Distance from django.core.exceptions import ImproperlyConfigured @@ -107,7 +106,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): """ if box is None: return None - shell = Geometry(box).shell + shell = GEOSGeometry(box).shell xmin, ymin = shell[0][:2] xmax, ymax = shell[2][:2] return (xmin, ymin, xmax, ymax) diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index d1653134683..8278f712669 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -3,10 +3,9 @@ from collections import defaultdict, namedtuple from django.contrib.gis import forms, gdal from django.contrib.gis.db.models.proxy import SpatialProxy from django.contrib.gis.gdal.error import GDALException -from django.contrib.gis.geometry.backend import Geometry, GeometryException from django.contrib.gis.geos import ( - GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, - Point, Polygon, + GeometryCollection, GEOSException, GEOSGeometry, LineString, + MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, ) from django.core.exceptions import ImproperlyConfigured from django.db.models.fields import Field @@ -170,7 +169,7 @@ class BaseSpatialField(Field): obj = super().get_prep_value(value) # When the input is not a geometry or raster, attempt to construct one # from the given string input. - if isinstance(obj, Geometry): + if isinstance(obj, GEOSGeometry): pass else: # Check if input is a candidate for conversion to raster or geometry. @@ -182,8 +181,8 @@ class BaseSpatialField(Field): obj = raster elif is_candidate: try: - obj = Geometry(obj) - except (GeometryException, GDALException): + obj = GEOSGeometry(obj) + except (GEOSException, 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__) @@ -248,7 +247,7 @@ class GeometryField(BaseSpatialField): super().contribute_to_class(cls, name, **kwargs) # Setup for lazy-instantiated Geometry object. - setattr(cls, self.attname, SpatialProxy(Geometry, self)) + setattr(cls, self.attname, SpatialProxy(GEOSGeometry, self)) def formfield(self, **kwargs): defaults = {'form_class': self.form_class, diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index d24f16947fb..3dea6cbd13b 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -2,7 +2,7 @@ from decimal import Decimal from django.contrib.gis.db.models.fields import BaseSpatialField, GeometryField from django.contrib.gis.db.models.sql import AreaField, DistanceField -from django.contrib.gis.geometry.backend import Geometry +from django.contrib.gis.geos import GEOSGeometry from django.core.exceptions import FieldError from django.db.models import ( BooleanField, FloatField, IntegerField, TextField, Transform, @@ -31,7 +31,7 @@ class GeoFuncMixin: except FieldError: output_field = None geom = expr.value - if not isinstance(geom, Geometry) or output_field and not isinstance(output_field, GeometryField): + if not isinstance(geom, GEOSGeometry) or output_field and not isinstance(output_field, GeometryField): raise TypeError("%s function requires a geometric argument in position %d." % (self.name, pos + 1)) if not geom.srid and not output_field: raise ValueError("SRID is required for all geometries.") diff --git a/django/contrib/gis/geometry/backend/__init__.py b/django/contrib/gis/geometry/backend/__init__.py deleted file mode 100644 index 5830e482f9f..00000000000 --- a/django/contrib/gis/geometry/backend/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -from importlib import import_module - -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured - -geom_backend = getattr(settings, 'GEOMETRY_BACKEND', 'geos') - -try: - module = import_module('django.contrib.gis.geometry.backend.%s' % geom_backend) -except ImportError: - try: - module = import_module(geom_backend) - except ImportError: - raise ImproperlyConfigured('Could not import user-defined GEOMETRY_BACKEND ' - '"%s".' % geom_backend) - -try: - Geometry = module.Geometry - GeometryException = module.GeometryException -except AttributeError: - raise ImproperlyConfigured('Cannot import Geometry from the "%s" ' - 'geometry backend.' % geom_backend) diff --git a/django/contrib/gis/geometry/backend/geos.py b/django/contrib/gis/geometry/backend/geos.py deleted file mode 100644 index 02ca3dd29e9..00000000000 --- a/django/contrib/gis/geometry/backend/geos.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.contrib.gis.geos import ( - GEOSException as GeometryException, GEOSGeometry as Geometry, -) - -__all__ = ['Geometry', 'GeometryException'] diff --git a/tests/gis_tests/relatedapp/tests.py b/tests/gis_tests/relatedapp/tests.py index 11a9bd99563..8d6b793ce28 100644 --- a/tests/gis_tests/relatedapp/tests.py +++ b/tests/gis_tests/relatedapp/tests.py @@ -1,5 +1,4 @@ from django.contrib.gis.db.models import Collect, Count, Extent, F, Union -from django.contrib.gis.geometry.backend import Geometry from django.contrib.gis.geos import GEOSGeometry, MultiPoint, Point from django.db import connection from django.test import TestCase, skipUnlessDBFeature @@ -177,8 +176,8 @@ class RelatedGeoModelTest(TestCase): for m, d, t in zip(gqs, gvqs, gvlqs): # The values should be Geometry objects and not raw strings returned # by the spatial database. - self.assertIsInstance(d['point'], Geometry) - self.assertIsInstance(t[1], Geometry) + self.assertIsInstance(d['point'], GEOSGeometry) + self.assertIsInstance(t[1], GEOSGeometry) self.assertEqual(m.point, d['point']) self.assertEqual(m.point, t[1]) diff --git a/tests/gis_tests/tests.py b/tests/gis_tests/tests.py index 2f55406f56a..20b66cd39be 100644 --- a/tests/gis_tests/tests.py +++ b/tests/gis_tests/tests.py @@ -8,16 +8,6 @@ try: HAS_POSTGRES = True except ImportError: HAS_POSTGRES = False -except ImproperlyConfigured as e: - # If psycopg is installed but not geos, the import path hits - # django.contrib.gis.geometry.backend which will "helpfully" convert - # an ImportError into an ImproperlyConfigured. - # Here, we make sure we're only catching this specific case and not another - # ImproperlyConfigured one. - if e.args and e.args[0].startswith('Could not import user-defined GEOMETRY_BACKEND'): - HAS_POSTGRES = False - else: - raise if HAS_POSTGRES: