Fixed #25655 -- Dropped support for GEOS < 3.3
This commit is contained in:
parent
06627ef2ca
commit
b78226cd3d
|
@ -1,11 +1,11 @@
|
||||||
from django.contrib.gis.db.backends.base.features import BaseSpatialFeatures
|
from django.contrib.gis.db.backends.base.features import BaseSpatialFeatures
|
||||||
from django.contrib.gis.geos import geos_version_info
|
|
||||||
from django.db.backends.sqlite3.features import \
|
from django.db.backends.sqlite3.features import \
|
||||||
DatabaseFeatures as SQLiteDatabaseFeatures
|
DatabaseFeatures as SQLiteDatabaseFeatures
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
|
||||||
class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures):
|
class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures):
|
||||||
|
supports_3d_storage = True
|
||||||
supports_distance_geodetic = False
|
supports_distance_geodetic = False
|
||||||
# SpatiaLite can only count vertices in LineStrings
|
# SpatiaLite can only count vertices in LineStrings
|
||||||
supports_num_points_poly = False
|
supports_num_points_poly = False
|
||||||
|
@ -16,7 +16,3 @@ class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures):
|
||||||
# which can result in a significant performance improvement when
|
# which can result in a significant performance improvement when
|
||||||
# creating the database.
|
# creating the database.
|
||||||
return self.connection.ops.spatial_version >= (4, 1, 0)
|
return self.connection.ops.spatial_version >= (4, 1, 0)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def supports_3d_storage(self):
|
|
||||||
return geos_version_info()['version'] >= '3.3'
|
|
||||||
|
|
|
@ -373,8 +373,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def ewkt(self):
|
def ewkt(self):
|
||||||
"""
|
"""
|
||||||
Returns the EWKT (SRID + WKT) of the Geometry. Note that Z values
|
Returns the EWKT (SRID + WKT) of the Geometry.
|
||||||
are only included in this representation if GEOS >= 3.3.0.
|
|
||||||
"""
|
"""
|
||||||
if self.get_srid():
|
if self.get_srid():
|
||||||
return 'SRID=%s;%s' % (self.srid, self.wkt)
|
return 'SRID=%s;%s' % (self.srid, self.wkt)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
from .base import GEOSBase
|
from .base import GEOSBase
|
||||||
from .error import GEOSException
|
|
||||||
from .libgeos import geos_version_info
|
|
||||||
from .prototypes import prepared as capi
|
from .prototypes import prepared as capi
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,29 +36,17 @@ class PreparedGeometry(GEOSBase):
|
||||||
def intersects(self, other):
|
def intersects(self, other):
|
||||||
return capi.prepared_intersects(self.ptr, other.ptr)
|
return capi.prepared_intersects(self.ptr, other.ptr)
|
||||||
|
|
||||||
# Added in GEOS 3.3:
|
|
||||||
|
|
||||||
def crosses(self, other):
|
def crosses(self, other):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
raise GEOSException("crosses on prepared geometries requires GEOS >= 3.3.0")
|
|
||||||
return capi.prepared_crosses(self.ptr, other.ptr)
|
return capi.prepared_crosses(self.ptr, other.ptr)
|
||||||
|
|
||||||
def disjoint(self, other):
|
def disjoint(self, other):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
raise GEOSException("disjoint on prepared geometries requires GEOS >= 3.3.0")
|
|
||||||
return capi.prepared_disjoint(self.ptr, other.ptr)
|
return capi.prepared_disjoint(self.ptr, other.ptr)
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
raise GEOSException("overlaps on prepared geometries requires GEOS >= 3.3.0")
|
|
||||||
return capi.prepared_overlaps(self.ptr, other.ptr)
|
return capi.prepared_overlaps(self.ptr, other.ptr)
|
||||||
|
|
||||||
def touches(self, other):
|
def touches(self, other):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
raise GEOSException("touches on prepared geometries requires GEOS >= 3.3.0")
|
|
||||||
return capi.prepared_touches(self.ptr, other.ptr)
|
return capi.prepared_touches(self.ptr, other.ptr)
|
||||||
|
|
||||||
def within(self, other):
|
def within(self, other):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
raise GEOSException("within on prepared geometries requires GEOS >= 3.3.0")
|
|
||||||
return capi.prepared_within(self.ptr, other.ptr)
|
return capi.prepared_within(self.ptr, other.ptr)
|
||||||
|
|
|
@ -47,23 +47,10 @@ wkt_writer_write = GEOSFuncFactory(
|
||||||
'GEOSWKTWriter_write', argtypes=[WKT_WRITE_PTR, GEOM_PTR], restype=geos_char_p, errcheck=check_string
|
'GEOSWKTWriter_write', argtypes=[WKT_WRITE_PTR, GEOM_PTR], restype=geos_char_p, errcheck=check_string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
wkt_writer_get_outdim = GEOSFuncFactory(
|
||||||
class WKTOutputDim(GEOSFuncFactory):
|
|
||||||
def get_func(self, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
return super(WKTOutputDim, self).get_func(*args, **kwargs)
|
|
||||||
except AttributeError:
|
|
||||||
# GEOSWKTWriter_get/setOutputDimension has been introduced in GEOS 3.3.0
|
|
||||||
# Always return 2 if not available
|
|
||||||
return {
|
|
||||||
'GEOSWKTWriter_getOutputDimension': lambda ptr: 2,
|
|
||||||
'GEOSWKTWriter_setOutputDimension': lambda ptr, dim: None,
|
|
||||||
}.get(self.func_name)
|
|
||||||
|
|
||||||
wkt_writer_get_outdim = WKTOutputDim(
|
|
||||||
'GEOSWKTWriter_getOutputDimension', argtypes=[WKT_WRITE_PTR], restype=c_int
|
'GEOSWKTWriter_getOutputDimension', argtypes=[WKT_WRITE_PTR], restype=c_int
|
||||||
)
|
)
|
||||||
wkt_writer_set_outdim = WKTOutputDim(
|
wkt_writer_set_outdim = GEOSFuncFactory(
|
||||||
'GEOSWKTWriter_setOutputDimension', argtypes=[WKT_WRITE_PTR, c_int]
|
'GEOSWKTWriter_setOutputDimension', argtypes=[WKT_WRITE_PTR, c_int]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,9 @@ class PreparedPredicate(GEOSFuncFactory):
|
||||||
prepared_contains = PreparedPredicate('GEOSPreparedContains')
|
prepared_contains = PreparedPredicate('GEOSPreparedContains')
|
||||||
prepared_contains_properly = PreparedPredicate('GEOSPreparedContainsProperly')
|
prepared_contains_properly = PreparedPredicate('GEOSPreparedContainsProperly')
|
||||||
prepared_covers = PreparedPredicate('GEOSPreparedCovers')
|
prepared_covers = PreparedPredicate('GEOSPreparedCovers')
|
||||||
prepared_intersects = PreparedPredicate('GEOSPreparedIntersects')
|
|
||||||
|
|
||||||
# Functions added in GEOS 3.3
|
|
||||||
prepared_crosses = PreparedPredicate('GEOSPreparedCrosses')
|
prepared_crosses = PreparedPredicate('GEOSPreparedCrosses')
|
||||||
prepared_disjoint = PreparedPredicate('GEOSPreparedDisjoint')
|
prepared_disjoint = PreparedPredicate('GEOSPreparedDisjoint')
|
||||||
|
prepared_intersects = PreparedPredicate('GEOSPreparedIntersects')
|
||||||
prepared_overlaps = PreparedPredicate('GEOSPreparedOverlaps')
|
prepared_overlaps = PreparedPredicate('GEOSPreparedOverlaps')
|
||||||
prepared_touches = PreparedPredicate('GEOSPreparedTouches')
|
prepared_touches = PreparedPredicate('GEOSPreparedTouches')
|
||||||
prepared_within = PreparedPredicate('GEOSPreparedWithin')
|
prepared_within = PreparedPredicate('GEOSPreparedWithin')
|
||||||
|
|
|
@ -160,11 +160,6 @@ WKB / EWKB ``buffer``
|
||||||
GeoJSON ``str`` or ``unicode``
|
GeoJSON ``str`` or ``unicode``
|
||||||
============= ======================
|
============= ======================
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The new 3D/4D WKT notation with an intermediary Z or M (like
|
|
||||||
``POINT Z (3, 4, 5)``) is only supported with GEOS 3.3.0 or later.
|
|
||||||
|
|
||||||
Properties
|
Properties
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -748,36 +743,16 @@ For example::
|
||||||
|
|
||||||
.. method:: crosses(other)
|
.. method:: crosses(other)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
GEOS 3.3 is *required* to use this predicate.
|
|
||||||
|
|
||||||
.. method:: disjoint(other)
|
.. method:: disjoint(other)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
GEOS 3.3 is *required* to use this predicate.
|
|
||||||
|
|
||||||
.. method:: intersects(other)
|
.. method:: intersects(other)
|
||||||
|
|
||||||
.. method:: overlaps(other)
|
.. method:: overlaps(other)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
GEOS 3.3 is *required* to use this predicate.
|
|
||||||
|
|
||||||
.. method:: touches(other)
|
.. method:: touches(other)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
GEOS 3.3 is *required* to use this predicate.
|
|
||||||
|
|
||||||
.. method:: within(other)
|
.. method:: within(other)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
GEOS 3.3 is *required* to use this predicate.
|
|
||||||
|
|
||||||
Geometry Factories
|
Geometry Factories
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ geospatial libraries:
|
||||||
======================== ==================================== ================================ ============================
|
======================== ==================================== ================================ ============================
|
||||||
Program Description Required Supported Versions
|
Program Description Required Supported Versions
|
||||||
======================== ==================================== ================================ ============================
|
======================== ==================================== ================================ ============================
|
||||||
:doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.4, 3.3, 3.2
|
:doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.4, 3.3
|
||||||
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.9, 4.8, 4.7, 4.6, 4.5, 4.4
|
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.9, 4.8, 4.7, 4.6, 4.5, 4.4
|
||||||
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 2.0, 1.11, 1.10, 1.9, 1.8, 1.7
|
: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
|
:doc:`GeoIP <../geoip>` IP-based geolocation library No 1.4
|
||||||
|
@ -21,7 +21,6 @@ totally fine with GeoDjango. Your mileage may vary.
|
||||||
|
|
||||||
..
|
..
|
||||||
Libs release dates:
|
Libs release dates:
|
||||||
GEOS 3.2.0 2009-12-14
|
|
||||||
GEOS 3.3.0 2011-05-30
|
GEOS 3.3.0 2011-05-30
|
||||||
GEOS 3.4.0 2013-08-11
|
GEOS 3.4.0 2013-08-11
|
||||||
GDAL 1.7.1 2010-02-08
|
GDAL 1.7.1 2010-02-08
|
||||||
|
|
|
@ -299,7 +299,7 @@ Miscellaneous
|
||||||
|
|
||||||
:mod:`django.contrib.gis`
|
:mod:`django.contrib.gis`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
* Support for SpatiaLite < 3.0 is dropped.
|
* Support for SpatiaLite < 3.0 and GEOS < 3.3 is dropped.
|
||||||
|
|
||||||
.. _deprecated-features-1.10:
|
.. _deprecated-features-1.10:
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,7 @@ import re
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.contrib.gis.db.models import functions
|
from django.contrib.gis.db.models import functions
|
||||||
from django.contrib.gis.geos import (
|
from django.contrib.gis.geos import LineString, Point, Polygon, fromstr
|
||||||
LineString, Point, Polygon, fromstr, geos_version_info,
|
|
||||||
)
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
@ -375,8 +373,6 @@ class GISFunctionsTests(TestCase):
|
||||||
|
|
||||||
@skipUnlessDBFeature("has_SymDifference_function")
|
@skipUnlessDBFeature("has_SymDifference_function")
|
||||||
def test_sym_difference(self):
|
def test_sym_difference(self):
|
||||||
if geos_version_info()['version'] < '3.3.0':
|
|
||||||
self.skipTest("GEOS >= 3.3 required")
|
|
||||||
geom = Point(5, 23, srid=4326)
|
geom = Point(5, 23, srid=4326)
|
||||||
qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom))
|
qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom))
|
||||||
for country in qs:
|
for country in qs:
|
||||||
|
|
|
@ -13,7 +13,7 @@ from django.contrib.gis.gdal import HAS_GDAL
|
||||||
from django.contrib.gis.geos import (
|
from django.contrib.gis.geos import (
|
||||||
HAS_GEOS, GeometryCollection, GEOSException, GEOSGeometry, LinearRing,
|
HAS_GEOS, GeometryCollection, GEOSException, GEOSGeometry, LinearRing,
|
||||||
LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
|
LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
|
||||||
fromfile, fromstr, geos_version_info,
|
fromfile, fromstr,
|
||||||
)
|
)
|
||||||
from django.contrib.gis.geos.base import GEOSBase
|
from django.contrib.gis.geos.base import GEOSBase
|
||||||
from django.contrib.gis.shortcuts import numpy
|
from django.contrib.gis.shortcuts import numpy
|
||||||
|
@ -77,7 +77,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
|
||||||
"Testing WKT output."
|
"Testing WKT output."
|
||||||
for g in self.geometries.wkt_out:
|
for g in self.geometries.wkt_out:
|
||||||
geom = fromstr(g.wkt)
|
geom = fromstr(g.wkt)
|
||||||
if geom.hasz and geos_version_info()['version'] >= '3.3.0':
|
if geom.hasz:
|
||||||
self.assertEqual(g.ewkt, geom.wkt)
|
self.assertEqual(g.ewkt, geom.wkt)
|
||||||
|
|
||||||
def test_hex(self):
|
def test_hex(self):
|
||||||
|
@ -1014,15 +1014,14 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
|
||||||
self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt))
|
self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt))
|
||||||
self.assertEqual(c, prep.covers(pnt))
|
self.assertEqual(c, prep.covers(pnt))
|
||||||
|
|
||||||
if geos_version_info()['version'] > '3.3.0':
|
self.assertTrue(prep.crosses(fromstr('LINESTRING(1 1, 15 15)')))
|
||||||
self.assertTrue(prep.crosses(fromstr('LINESTRING(1 1, 15 15)')))
|
self.assertTrue(prep.disjoint(Point(-5, -5)))
|
||||||
self.assertTrue(prep.disjoint(Point(-5, -5)))
|
poly = Polygon(((-1, -1), (1, 1), (1, 0), (-1, -1)))
|
||||||
poly = Polygon(((-1, -1), (1, 1), (1, 0), (-1, -1)))
|
self.assertTrue(prep.overlaps(poly))
|
||||||
self.assertTrue(prep.overlaps(poly))
|
poly = Polygon(((-5, 0), (-5, 5), (0, 5), (-5, 0)))
|
||||||
poly = Polygon(((-5, 0), (-5, 5), (0, 5), (-5, 0)))
|
self.assertTrue(prep.touches(poly))
|
||||||
self.assertTrue(prep.touches(poly))
|
poly = Polygon(((-1, -1), (-1, 11), (11, 11), (11, -1), (-1, -1)))
|
||||||
poly = Polygon(((-1, -1), (-1, 11), (11, 11), (11, -1), (-1, -1)))
|
self.assertTrue(prep.within(poly))
|
||||||
self.assertTrue(prep.within(poly))
|
|
||||||
|
|
||||||
# Original geometry deletion should not crash the prepared one (#21662)
|
# Original geometry deletion should not crash the prepared one (#21662)
|
||||||
del mpoly
|
del mpoly
|
||||||
|
|
Loading…
Reference in New Issue