Dropped support for GEOS < 3.1

This commit is contained in:
Claude Paroz 2013-12-24 15:57:13 +01:00
parent 542198c1d0
commit d17404aa90
11 changed files with 51 additions and 121 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <http://trac.osgeo.org/geos/wiki/PreparedGeometry>`_.
.. note::
GEOS 3.1 is *required* in order to use prepared geometries.
For example::
>>> from django.contrib.gis.geos import Point, Polygon

View File

@ -10,7 +10,7 @@ geospatial libraries:
======================== ==================================== ================================ ==========================
Program Description Required Supported Versions
======================== ==================================== ================================ ==========================
:ref:`GEOS <ref-geos>` Geometry Engine Open Source Yes 3.3, 3.2, 3.1, 3.0
:ref:`GEOS <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 <ref-gdal>` Geospatial Data Abstraction Library No (but, required for SQLite) 1.9, 1.8, 1.7, 1.6
:ref:`GeoIP <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

View File

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

View File

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