Fixed #25655 -- Dropped support for GEOS < 3.3

This commit is contained in:
Sergey Fedoseev 2015-11-01 01:28:46 +05:00 committed by Claude Paroz
parent 06627ef2ca
commit b78226cd3d
10 changed files with 18 additions and 83 deletions

View File

@ -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'

View File

@ -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)

View File

@ -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)

View File

@ -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]
) )

View File

@ -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')

View File

@ -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
================== ==================

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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