Selaa lähdekoodia

Fixed #25636 -- Dropped support for SpatiaLite < 3.0

Sergey Fedoseev 9 vuotta sitten
vanhempi
commit
8ad923b9d0

+ 5 - 33
django/contrib/gis/db/backends/spatialite/operations.py

@@ -1,6 +1,5 @@
 """
 SQL functions reference lists:
-http://www.gaia-gis.it/spatialite-2.4.0/spatialite-sql-2.4.html
 http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-sql-3.0.0.html
 http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.1.html
 """
@@ -16,7 +15,6 @@ from django.contrib.gis.geometry.backend import Geometry
 from django.contrib.gis.measure import Distance
 from django.core.exceptions import ImproperlyConfigured
 from django.db.backends.sqlite3.operations import DatabaseOperations
-from django.db.utils import DatabaseError
 from django.utils import six
 from django.utils.functional import cached_property
 
@@ -37,7 +35,10 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
     distance = 'Distance'
     envelope = 'Envelope'
     extent = 'Extent'
+    geojson = 'AsGeoJSON'
+    gml = 'AsGML'
     intersection = 'Intersection'
+    kml = 'AsKML'
     length = 'GLength'  # OpenGis defines Length, but this conflicts with an SQLite reserved keyword
     num_geom = 'NumGeometries'
     num_points = 'NumPoints'
@@ -110,44 +111,15 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
                 'database (error was "%s").  Was the SpatiaLite initialization '
                 'SQL loaded on this database?') % (self.connection.settings_dict['NAME'], msg)
             six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2])
-        if version < (2, 4, 0):
-            raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions '
-                                       '2.4.0 and above')
+        if version < (3, 0, 0):
+            raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 3.0.0 and above.')
         return version
 
-    @property
-    def _version_greater_2_4_0_rc4(self):
-        if self.spatial_version >= (2, 4, 1):
-            return True
-        else:
-            # Spatialite 2.4.0-RC4 added AsGML and AsKML, however both
-            # RC2 (shipped in popular Debian/Ubuntu packages) and RC4
-            # report version as '2.4.0', so we fall back to feature detection
-            try:
-                self._get_spatialite_func("AsGML(GeomFromText('POINT(1 1)'))")
-            except DatabaseError:
-                return False
-            return True
-
     @cached_property
     def disallowed_aggregates(self):
         disallowed = (aggregates.Extent3D, aggregates.MakeLine)
-        if self.spatial_version < (3, 0, 0):
-            disallowed += (aggregates.Collect, aggregates.Extent)
         return disallowed
 
-    @cached_property
-    def gml(self):
-        return 'AsGML' if self._version_greater_2_4_0_rc4 else None
-
-    @cached_property
-    def kml(self):
-        return 'AsKML' if self._version_greater_2_4_0_rc4 else None
-
-    @cached_property
-    def geojson(self):
-        return 'AsGeoJSON' if self.spatial_version >= (3, 0, 0) else None
-
     def convert_extent(self, box, srid):
         """
         Convert the polygon data received from Spatialite to min/max values.

+ 1 - 2
django/contrib/gis/db/models/query.py

@@ -113,8 +113,7 @@ class GeoQuerySet(QuerySet):
         """
         backend = connections[self.db].ops
         if not backend.geojson:
-            raise NotImplementedError('Only PostGIS 1.3.4+ and SpatiaLite 3.0+ '
-                                      'support GeoJSON serialization.')
+            raise NotImplementedError('Only PostGIS and SpatiaLite support GeoJSON serialization.')
 
         if not isinstance(precision, six.integer_types):
             raise TypeError('Precision keyword must be set with an integer.')

+ 2 - 2
docs/ref/contrib/gis/db-api.txt

@@ -345,8 +345,8 @@ support any of these aggregates, and is thus excluded from the table.
 =======================  =======  ======  ==========
 Aggregate                PostGIS  Oracle  SpatiaLite
 =======================  =======  ======  ==========
-:class:`Collect`         X                (from v3.0)
-:class:`Extent`          X        X       (from v3.0)
+:class:`Collect`         X                X
+:class:`Extent`          X        X       X
 :class:`Extent3D`        X
 :class:`MakeLine`        X
 :class:`Union`           X        X       X

+ 2 - 2
docs/ref/contrib/gis/geoquerysets.txt

@@ -1251,7 +1251,7 @@ Example::
 
 .. class:: Collect(geo_field)
 
-*Availability*: PostGIS, Spatialite (≥3.0)
+*Availability*: PostGIS, Spatialite
 
 Returns a ``GEOMETRYCOLLECTION`` or a ``MULTI`` geometry object from the geometry
 column. This is analogous to a simplified version of the :class:`Union`
@@ -1264,7 +1264,7 @@ not caring about dissolving boundaries.
 
 .. class:: Extent(geo_field)
 
-*Availability*: PostGIS, Oracle, Spatialite (≥3.0)
+*Availability*: PostGIS, Oracle, Spatialite
 
 Returns the extent of all ``geo_field`` in the ``QuerySet`` as a four-tuple,
 comprising the lower left coordinate and the upper right coordinate.

+ 1 - 2
docs/ref/contrib/gis/install/geolibs.txt

@@ -13,7 +13,7 @@ Program                   Description                           Required
 :doc:`GDAL <../gdal>`     Geospatial Data Abstraction Library   Yes (SQLite only)                 2.0, 1.11, 1.10, 1.9, 1.8, 1.7
 :doc:`GeoIP <../geoip>`   IP-based geolocation library          No                                1.4
 `PostGIS`__               Spatial extensions for PostgreSQL     Yes (PostgreSQL only)             2.1, 2.0
-`SpatiaLite`__            Spatial extensions for SQLite         Yes (SQLite only)                 4.1, 4.0, 3.0, 2.4
+`SpatiaLite`__            Spatial extensions for SQLite         Yes (SQLite only)                 4.1, 4.0, 3.0
 ========================  ====================================  ================================  ============================
 
 Note that older or more recent versions of these libraries *may* also work
@@ -31,7 +31,6 @@ totally fine with GeoDjango. Your mileage may vary.
     GDAL 1.11.0 2014-04-25
     PostGIS 2.0.0 2012-04-03
     PostGIS 2.1.0 2013-08-17
-    Spatialite 2.4.0 2010-11-14
     Spatialite 3.0.0 2011-12-30
     Spatialite 4.0.0 2012-11-25
     Spatialite 4.1.0 2013-06-04

+ 1 - 1
docs/ref/contrib/gis/install/index.txt

@@ -61,7 +61,7 @@ Database            Library Requirements            Supported Versions  Notes
 PostgreSQL          GEOS, PROJ.4, PostGIS           9.1+                Requires PostGIS.
 MySQL               GEOS                            5.5+                Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`.
 Oracle              GEOS                            11.2+               XE not supported.
-SQLite              GEOS, GDAL, PROJ.4, SpatiaLite  3.6.+               Requires SpatiaLite 2.4+, pysqlite2 2.5+
+SQLite              GEOS, GDAL, PROJ.4, SpatiaLite  3.6.+               Requires SpatiaLite 3.0+, pysqlite2 2.5+
 ==================  ==============================  ==================  =========================================
 
 See also `this comparison matrix`__ on the OSGeo Wiki for

+ 4 - 0
docs/releases/1.10.txt

@@ -297,6 +297,10 @@ Miscellaneous
 * The ``repr()`` of a ``QuerySet`` is wrapped in ``<QuerySet >`` to
   disambiguate it from a plain list when debugging.
 
+:mod:`django.contrib.gis`
+~~~~~~~~~~~~~~~~~~~~~~~~~
+* Support for SpatiaLite < 3.0 is dropped.
+
 .. _deprecated-features-1.10:
 
 Features deprecated in 1.10

+ 4 - 5
tests/gis_tests/distapp/tests.py

@@ -10,7 +10,7 @@ from django.db.models import F, Q
 from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
 from django.utils.deprecation import RemovedInDjango20Warning
 
-from ..utils import no_oracle, oracle, postgis, spatialite
+from ..utils import no_oracle, oracle, postgis
 from .models import (
     AustraliaCity, CensusZipcode, Interstate, SouthTexasCity, SouthTexasCityFt,
     SouthTexasInterstate, SouthTexasZipcode,
@@ -123,7 +123,7 @@ class DistanceTest(TestCase):
         # with different projected coordinate systems.
         dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point').order_by('id')
         dist2 = SouthTexasCity.objects.distance(lagrange).order_by('id')  # Using GEOSGeometry parameter
-        if spatialite or oracle:
+        if oracle:
             dist_qs = [dist1, dist2]
         else:
             dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt).order_by('id')  # Using EWKT string parameter.
@@ -247,9 +247,8 @@ class DistanceTest(TestCase):
             point__distance_lte=(self.stx_pnt, D(km=20)),
         )
 
-        # Can't determine the units on SpatiaLite from PROJ.4 string, and
         # Oracle 11 incorrectly thinks it is not projected.
-        if spatialite or oracle:
+        if oracle:
             dist_qs = (qs1,)
         else:
             qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(
@@ -513,7 +512,7 @@ class DistanceFunctionsTests(TestCase):
         # Testing using different variations of parameters and using models
         # with different projected coordinate systems.
         dist1 = SouthTexasCity.objects.annotate(distance=Distance('point', lagrange)).order_by('id')
-        if spatialite or oracle:
+        if oracle:
             dist_qs = [dist1]
         else:
             dist2 = SouthTexasCityFt.objects.annotate(distance=Distance('point', lagrange)).order_by('id')

+ 1 - 7
tests/gis_tests/geoapp/test_functions.py

@@ -27,7 +27,7 @@ class GISFunctionsTests(TestCase):
     fixtures = ['initial']
 
     def test_asgeojson(self):
-        # Only PostGIS and SpatiaLite 3.0+ support GeoJSON.
+        # Only PostGIS and SpatiaLite support GeoJSON.
         if not connection.ops.geojson:
             with self.assertRaises(NotImplementedError):
                 list(Country.objects.annotate(json=functions.AsGeoJSON('mpoly')))
@@ -108,12 +108,6 @@ class GISFunctionsTests(TestCase):
                 r'<gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ '
                 r'</gml:coordinates></gml:Point>'
             )
-        elif spatialite and connection.ops.spatial_version < (3, 0, 0):
-            # Spatialite before 3.0 has extra colon in SrsName
-            gml_regex = re.compile(
-                r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." '
-                r'cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>'
-            )
         else:
             gml_regex = re.compile(
                 r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>'

+ 4 - 14
tests/gis_tests/geoapp/tests.py

@@ -149,9 +149,6 @@ class GeoModelTest(TestCase):
 
         # If the GeometryField SRID is -1, then we shouldn't perform any
         # transformation if the SRID of the input geometry is different.
-        if spatialite and connection.ops.spatial_version < (3, 0, 0):
-            # SpatiaLite < 3 does not support missing SRID values.
-            return
         m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
         m1.save()
         self.assertEqual(-1, m1.geom.srid)
@@ -272,10 +269,9 @@ class GeoLookupTest(TestCase):
         self.assertEqual('Texas', tx.name)
         self.assertEqual('New Zealand', nz.name)
 
-        # Spatialite 2.3 thinks that Lawrence is in Puerto Rico (a NULL geometry).
-        if not (spatialite and connection.ops.spatial_version < (3, 0, 0)):
-            ks = State.objects.get(poly__contains=lawrence.point)
-            self.assertEqual('Kansas', ks.name)
+        # Testing `contains` on the states using the point for Lawrence.
+        ks = State.objects.get(poly__contains=lawrence.point)
+        self.assertEqual('Kansas', ks.name)
 
         # Pueblo and Oklahoma City (even though OK City is within the bounding box of Texas)
         # are not contained in Texas or New Zealand.
@@ -558,7 +554,7 @@ class GeoQuerySetTest(TestCase):
 
     def test_geojson(self):
         "Testing GeoJSON output from the database using GeoQuerySet.geojson()."
-        # Only PostGIS and SpatiaLite 3.0+ support GeoJSON.
+        # Only PostGIS and SpatiaLite support GeoJSON.
         if not connection.ops.geojson:
             self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly')
             return
@@ -625,12 +621,6 @@ class GeoQuerySetTest(TestCase):
                 r'<gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ '
                 r'</gml:coordinates></gml:Point>'
             )
-        elif spatialite and connection.ops.spatial_version < (3, 0, 0):
-            # Spatialite before 3.0 has extra colon in SrsName
-            gml_regex = re.compile(
-                r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." '
-                r'cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>'
-            )
         else:
             gml_regex = re.compile(
                 r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>'