diff --git a/django/contrib/gis/geos/__init__.py b/django/contrib/gis/geos/__init__.py index 70b73fad8b..d5fe479dae 100644 --- a/django/contrib/gis/geos/__init__.py +++ b/django/contrib/gis/geos/__init__.py @@ -6,9 +6,9 @@ for more details: __all__ = ['HAS_GEOS'] try: - from .libgeos import geos_version, geos_version_info, GEOS_PREPARE # NOQA: flake8 detects only the last __all__ + from .libgeos import geos_version, geos_version_info # NOQA: flake8 detects only the last __all__ HAS_GEOS = True - __all__ += ['geos_version', 'geos_version_info', 'GEOS_PREPARE'] + __all__ += ['geos_version', 'geos_version_info'] except ImportError: HAS_GEOS = False diff --git a/django/contrib/gis/geos/collections.py b/django/contrib/gis/geos/collections.py index 426cf3833d..483cb6f405 100644 --- a/django/contrib/gis/geos/collections.py +++ b/django/contrib/gis/geos/collections.py @@ -3,9 +3,8 @@ GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon """ from ctypes import c_int, c_uint, byref -from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.libgeos import get_pointer_arr, GEOS_PREPARE +from django.contrib.gis.geos.libgeos import get_pointer_arr from django.contrib.gis.geos.linestring import LineString, LinearRing from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.polygon import Polygon @@ -119,10 +118,7 @@ class MultiPolygon(GeometryCollection): @property def cascaded_union(self): "Returns a cascaded union of this MultiPolygon." - if GEOS_PREPARE: - return GEOSGeometry(capi.geos_cascaded_union(self.ptr), self.srid) - else: - raise GEOSException('The cascaded union operation requires GEOS 3.1+.') + return GEOSGeometry(capi.geos_cascaded_union(self.ptr), self.srid) # Setting the allowed types here since GeometryCollection is defined before # its subclasses. diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 073415abea..f453f113f7 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -17,7 +17,7 @@ from django.contrib.gis.gdal.error import SRSException from django.contrib.gis.geos.base import GEOSBase, gdal from django.contrib.gis.geos.coordseq import GEOSCoordSeq from django.contrib.gis.geos.error import GEOSException, GEOSIndexError -from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE +from django.contrib.gis.geos.libgeos import GEOM_PTR # All other functions in this module come from the ctypes # prototypes module -- which handles all interaction with @@ -289,8 +289,6 @@ class GEOSGeometry(GEOSBase, ListMixin): """ Returns a string containing the reason for any invalidity. """ - if not GEOS_PREPARE: - raise GEOSException('Upgrade GEOS to 3.1 to get validity reason.') return capi.geos_isvalidreason(self.ptr).decode() #### Binary predicates. #### @@ -411,9 +409,6 @@ class GEOSGeometry(GEOSBase, ListMixin): extension of the WKB specification that includes SRID value that are a part of this geometry. """ - if self.hasz and not GEOS_PREPARE: - # See: http://trac.osgeo.org/geos/ticket/216 - raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D HEXEWKB.') return ewkb_w(3 if self.hasz else 2).write_hex(self) @property @@ -443,9 +438,6 @@ class GEOSGeometry(GEOSBase, ListMixin): This is an extension of the WKB specification that includes any SRID value that are a part of this geometry. """ - if self.hasz and not GEOS_PREPARE: - # See: http://trac.osgeo.org/geos/ticket/216 - raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D EWKB.') return ewkb_w(3 if self.hasz else 2).write(self) @property @@ -460,10 +452,7 @@ class GEOSGeometry(GEOSBase, ListMixin): Returns a PreparedGeometry corresponding to this geometry -- it is optimized for the contains, intersects, and covers operations. """ - if GEOS_PREPARE: - return PreparedGeometry(self) - else: - raise GEOSException('GEOS 3.1+ required for prepared geometry support.') + return PreparedGeometry(self) #### GDAL-specific output routines #### @property @@ -707,16 +696,14 @@ from django.contrib.gis.geos.linestring import LineString, LinearRing from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.polygon import Polygon from django.contrib.gis.geos.collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon -GEOS_CLASSES = {0: Point, - 1: LineString, - 2: LinearRing, - 3: Polygon, - 4: MultiPoint, - 5: MultiLineString, - 6: MultiPolygon, - 7: GeometryCollection, - } - -# If supported, import the PreparedGeometry class. -if GEOS_PREPARE: - from django.contrib.gis.geos.prepared import PreparedGeometry +from django.contrib.gis.geos.prepared import PreparedGeometry +GEOS_CLASSES = { + 0: Point, + 1: LineString, + 2: LinearRing, + 3: Polygon, + 4: MultiPoint, + 5: MultiLineString, + 6: MultiPolygon, + 7: GeometryCollection, +} diff --git a/django/contrib/gis/geos/libgeos.py b/django/contrib/gis/geos/libgeos.py index 239067a433..5be05cee50 100644 --- a/django/contrib/gis/geos/libgeos.py +++ b/django/contrib/gis/geos/libgeos.py @@ -155,22 +155,10 @@ GEOS_MINOR_VERSION = int(_verinfo['minor']) GEOS_SUBMINOR_VERSION = int(_verinfo['subminor']) del _verinfo GEOS_VERSION = (GEOS_MAJOR_VERSION, GEOS_MINOR_VERSION, GEOS_SUBMINOR_VERSION) -GEOS_PREPARE = GEOS_VERSION >= (3, 1, 0) -if GEOS_PREPARE: - # Here we set up the prototypes for the initGEOS_r and finishGEOS_r - # routines. These functions aren't actually called until they are - # attached to a GEOS context handle -- this actually occurs in - # geos/prototypes/threadsafe.py. - lgeos.initGEOS_r.restype = CONTEXT_PTR - lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] -else: - # When thread-safety isn't available, the initGEOS routine must be called - # first. This function takes the notice and error functions, defined - # as Python callbacks above, as parameters. Here is the C code that is - # wrapped: - # extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function, GEOSMessageHandler error_function); - lgeos.initGEOS(notice_h, error_h) - # Calling finishGEOS() upon exit of the interpreter. - import atexit - atexit.register(lgeos.finishGEOS) +# Here we set up the prototypes for the initGEOS_r and finishGEOS_r +# routines. These functions aren't actually called until they are +# attached to a GEOS context handle -- this actually occurs in +# geos/prototypes/threadsafe.py. +lgeos.initGEOS_r.restype = CONTEXT_PTR +lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] diff --git a/django/contrib/gis/geos/prototypes/misc.py b/django/contrib/gis/geos/prototypes/misc.py index 6b10396aba..a8bb3cbd58 100644 --- a/django/contrib/gis/geos/prototypes/misc.py +++ b/django/contrib/gis/geos/prototypes/misc.py @@ -3,13 +3,13 @@ ones that return the area, distance, and length. """ from ctypes import c_int, c_double, POINTER -from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE +from django.contrib.gis.geos.libgeos import GEOM_PTR from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string from django.contrib.gis.geos.prototypes.geom import geos_char_p from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc from django.utils.six.moves import xrange -__all__ = ['geos_area', 'geos_distance', 'geos_length'] +__all__ = ['geos_area', 'geos_distance', 'geos_length', 'geos_isvalidreason'] ### ctypes generator function ### @@ -31,11 +31,7 @@ def dbl_from_geom(func, num_geom=1): geos_area = dbl_from_geom(GEOSFunc('GEOSArea')) geos_distance = dbl_from_geom(GEOSFunc('GEOSDistance'), num_geom=2) geos_length = dbl_from_geom(GEOSFunc('GEOSLength')) - -# Validity reason; only in GEOS 3.1+ -if GEOS_PREPARE: - geos_isvalidreason = GEOSFunc('GEOSisValidReason') - geos_isvalidreason.argtypes = [GEOM_PTR] - geos_isvalidreason.restype = geos_char_p - geos_isvalidreason.errcheck = check_string - __all__.append('geos_isvalidreason') +geos_isvalidreason = GEOSFunc('GEOSisValidReason') +geos_isvalidreason.argtypes = [GEOM_PTR] +geos_isvalidreason.restype = geos_char_p +geos_isvalidreason.errcheck = check_string diff --git a/django/contrib/gis/geos/prototypes/topology.py b/django/contrib/gis/geos/prototypes/topology.py index 5bc99e8409..60db46ec14 100644 --- a/django/contrib/gis/geos/prototypes/topology.py +++ b/django/contrib/gis/geos/prototypes/topology.py @@ -2,13 +2,14 @@ This module houses the GEOS ctypes prototype functions for the topological operations on geometries. """ -__all__ = ['geos_boundary', 'geos_buffer', 'geos_centroid', 'geos_convexhull', - 'geos_difference', 'geos_envelope', 'geos_intersection', - 'geos_linemerge', 'geos_pointonsurface', 'geos_preservesimplify', - 'geos_simplify', 'geos_symdifference', 'geos_union', 'geos_relate'] +__all__ = ['geos_boundary', 'geos_buffer', 'geos_cascaded_union', + 'geos_centroid', 'geos_convexhull', 'geos_difference', + 'geos_envelope', 'geos_intersection', 'geos_linemerge', + 'geos_pointonsurface', 'geos_preservesimplify', 'geos_simplify', + 'geos_symdifference', 'geos_union', 'geos_relate'] from ctypes import c_double, c_int -from django.contrib.gis.geos.libgeos import geos_version_info, GEOM_PTR, GEOS_PREPARE +from django.contrib.gis.geos.libgeos import geos_version_info, GEOM_PTR from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_minus_one, check_string from django.contrib.gis.geos.prototypes.geom import geos_char_p from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc @@ -39,19 +40,16 @@ geos_simplify = topology(GEOSFunc('GEOSSimplify'), c_double) geos_symdifference = topology(GEOSFunc('GEOSSymDifference'), GEOM_PTR) geos_union = topology(GEOSFunc('GEOSUnion'), GEOM_PTR) +geos_cascaded_union = GEOSFunc('GEOSUnionCascaded') +geos_cascaded_union.argtypes = [GEOM_PTR] +geos_cascaded_union.restype = GEOM_PTR + # GEOSRelate returns a string, not a geometry. geos_relate = GEOSFunc('GEOSRelate') geos_relate.argtypes = [GEOM_PTR, GEOM_PTR] geos_relate.restype = geos_char_p geos_relate.errcheck = check_string -# Routines only in GEOS 3.1+ -if GEOS_PREPARE: - geos_cascaded_union = GEOSFunc('GEOSUnionCascaded') - geos_cascaded_union.argtypes = [GEOM_PTR] - geos_cascaded_union.restype = GEOM_PTR - __all__.append('geos_cascaded_union') - # Linear referencing routines info = geos_version_info() if info['version'] >= '3.2.0': diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index 9ce7e0d73d..8356343839 100644 --- a/django/contrib/gis/geos/tests/test_geos.py +++ b/django/contrib/gis/geos/tests/test_geos.py @@ -22,8 +22,7 @@ from .. import HAS_GEOS if HAS_GEOS: from .. import (GEOSException, GEOSIndexError, GEOSGeometry, GeometryCollection, Point, MultiPoint, Polygon, MultiPolygon, LinearRing, - LineString, MultiLineString, fromfile, fromstr, geos_version_info, - GEOS_PREPARE) + LineString, MultiLineString, fromfile, fromstr, geos_version_info) from ..base import gdal, numpy, GEOSBase @@ -121,20 +120,12 @@ class GEOSTest(unittest.TestCase, TestDataMixin): # a bug in versions prior to 3.1 that puts the X coordinate in # place of Z; an exception should be raised on those versions. self.assertEqual(hexewkb_2d, pnt_2d.hexewkb) - if GEOS_PREPARE: - self.assertEqual(hexewkb_3d, pnt_3d.hexewkb) - self.assertEqual(True, GEOSGeometry(hexewkb_3d).hasz) - else: - with self.assertRaises(GEOSException): - pnt_3d.hexewkb + self.assertEqual(hexewkb_3d, pnt_3d.hexewkb) + self.assertEqual(True, GEOSGeometry(hexewkb_3d).hasz) # Same for EWKB. self.assertEqual(memoryview(a2b_hex(hexewkb_2d)), pnt_2d.ewkb) - if GEOS_PREPARE: - self.assertEqual(memoryview(a2b_hex(hexewkb_3d)), pnt_3d.ewkb) - else: - with self.assertRaises(GEOSException): - pnt_3d.ewkb + self.assertEqual(memoryview(a2b_hex(hexewkb_3d)), pnt_3d.ewkb) # Redundant sanity check. self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid) @@ -869,10 +860,9 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertIsInstance(g1.ogr, gdal.OGRGeometry) self.assertIsNone(g1.srs) - if GEOS_PREPARE: - g1_3d = fromstr('POINT(5 23 8)') - self.assertIsInstance(g1_3d.ogr, gdal.OGRGeometry) - self.assertEqual(g1_3d.ogr.z, 8) + g1_3d = fromstr('POINT(5 23 8)') + self.assertIsInstance(g1_3d.ogr, gdal.OGRGeometry) + self.assertEqual(g1_3d.ogr.z, 8) g2 = fromstr('LINESTRING(0 0, 5 5, 23 23)', srid=4326) self.assertIsInstance(g2.ogr, gdal.OGRGeometry) @@ -918,10 +908,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): def test_transform_3d(self): p3d = GEOSGeometry('POINT (5 23 100)', 4326) p3d.transform(2774) - if GEOS_PREPARE: - self.assertEqual(p3d.z, 100) - else: - self.assertIsNone(p3d.z) + self.assertEqual(p3d.z, 100) @skipUnless(HAS_GDAL, "GDAL is required.") def test_transform_noop(self): @@ -1030,7 +1017,6 @@ class GEOSTest(unittest.TestCase, TestDataMixin): if not no_srid: self.assertEqual(geom.srid, tmpg.srid) - @skipUnless(HAS_GEOS and GEOS_PREPARE, "geos >= 3.1.0 is required") def test_prepared(self): "Testing PreparedGeometry support." # Creating a simple multipolygon and getting a prepared version. @@ -1061,7 +1047,6 @@ class GEOSTest(unittest.TestCase, TestDataMixin): for geom, merged in zip(ref_geoms, ref_merged): self.assertEqual(merged, geom.merged) - @skipUnless(HAS_GEOS and GEOS_PREPARE, "geos >= 3.1.0 is required") def test_valid_reason(self): "Testing IsValidReason support" diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index d557af96a3..a1f92b31c7 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -282,10 +282,6 @@ Returns the EWKB of this Geometry in hexadecimal form. This is an extension of the WKB specification that includes the SRID value that are a part of this geometry. -.. note:: - - GEOS 3.1 is *required* if you want valid 3D HEXEWKB. - .. attribute:: GEOSGeometry.json Returns the GeoJSON representation of the geometry. @@ -329,10 +325,6 @@ Return the EWKB representation of this Geometry as a Python buffer. This is an extension of the WKB specification that includes any SRID value that are a part of this geometry. -.. note:: - - GEOS 3.1 is *required* if you want valid 3D EWKB. - .. attribute:: GEOSGeometry.wkt Returns the Well-Known Text of the geometry (an OGC standard). @@ -533,10 +525,6 @@ a :class:`Polygon`). .. attribute:: GEOSGeometry.prepared -.. note:: - - Support for prepared geometries requires GEOS 3.1. - Returns a GEOS ``PreparedGeometry`` for the contents of this geometry. ``PreparedGeometry`` objects are optimized for the contains, intersects, and covers operations. Refer to the :ref:`prepared-geometries` documentation @@ -710,10 +698,6 @@ Geometry Collections more efficient (faster) than trying to union the geometries together individually. [#fncascadedunion]_ - .. note:: - - GEOS 3.1 is *required* to peform cascaded unions. - ``GeometryCollection`` ---------------------- @@ -740,10 +724,6 @@ geometry can be orders of magnitude faster -- the more complex the geometry that is prepared, the larger the speedup in the operation. For more information, please consult the `GEOS wiki page on prepared geometries `_. -.. note:: - - GEOS 3.1 is *required* in order to use prepared geometries. - For example:: >>> from django.contrib.gis.geos import Point, Polygon diff --git a/docs/ref/contrib/gis/install/geolibs.txt b/docs/ref/contrib/gis/install/geolibs.txt index 508bf7809c..a529a497d2 100644 --- a/docs/ref/contrib/gis/install/geolibs.txt +++ b/docs/ref/contrib/gis/install/geolibs.txt @@ -10,7 +10,7 @@ geospatial libraries: ======================== ==================================== ================================ ========================== Program Description Required Supported Versions ======================== ==================================== ================================ ========================== -:ref:`GEOS ` Geometry Engine Open Source Yes 3.3, 3.2, 3.1, 3.0 +:ref:`GEOS ` Geometry Engine Open Source Yes 3.3, 3.2, 3.1 `PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.8, 4.7, 4.6, 4.5, 4.4 :ref:`GDAL ` Geospatial Data Abstraction Library No (but, required for SQLite) 1.9, 1.8, 1.7, 1.6 :ref:`GeoIP ` IP-based geolocation library No 1.4 @@ -20,7 +20,6 @@ Program Description Required .. Libs release dates: - GEOS 3.0.0 2008-08-14 GEOS 3.1.0 2009-03-11 GEOS 3.2.0 2009-12-14 GEOS 3.3.0 2011-05-30 diff --git a/docs/ref/contrib/gis/model-api.txt b/docs/ref/contrib/gis/model-api.txt index 81b619e338..10cc2957d8 100644 --- a/docs/ref/contrib/gis/model-api.txt +++ b/docs/ref/contrib/gis/model-api.txt @@ -172,8 +172,7 @@ three-dimensonal support. .. note:: - At this time 3D support requires that GEOS 3.1 be installed, and is - limited only to the PostGIS spatial backend. + At this time 3D support is limited to the PostGIS spatial backend. ``geography`` ------------- diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 3a1568fe45..21449b4e7c 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -722,6 +722,8 @@ Miscellaneous ``select_related('foo').select_related('bar')``. Previously the latter would have been equivalent to ``select_related('bar')``. +* GeoDjango dropped support for GEOS < 3.1. + Features deprecated in 1.7 ==========================