mirror of https://github.com/django/django.git
Fixed #13788 -- `GEOSGeometry.transform` no longer silently no-ops when GDAL isn't available. Thanks, Rob Coup.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15025 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
df4cb60004
commit
5fddfda559
|
@ -4,6 +4,7 @@
|
||||||
"""
|
"""
|
||||||
# Python, ctypes and types dependencies.
|
# Python, ctypes and types dependencies.
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
from ctypes import addressof, byref, c_double, c_size_t
|
from ctypes import addressof, byref, c_double, c_size_t
|
||||||
|
|
||||||
# super-class for mutable list behavior
|
# super-class for mutable list behavior
|
||||||
|
@ -498,7 +499,24 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
instead.
|
instead.
|
||||||
"""
|
"""
|
||||||
srid = self.srid
|
srid = self.srid
|
||||||
if gdal.HAS_GDAL and srid:
|
|
||||||
|
if ct == srid:
|
||||||
|
# short-circuit where source & dest SRIDs match
|
||||||
|
if clone:
|
||||||
|
return self.clone()
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if (srid is None) or (srid < 0):
|
||||||
|
warnings.warn("Calling transform() with no SRID set does no transformation!",
|
||||||
|
stacklevel=2)
|
||||||
|
warnings.warn("Calling transform() with no SRID will raise GEOSException in v1.5",
|
||||||
|
FutureWarning, stacklevel=2)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not gdal.HAS_GDAL:
|
||||||
|
raise GEOSException("GDAL library is not available to transform() geometry.")
|
||||||
|
|
||||||
# Creating an OGR Geometry, which is then transformed.
|
# Creating an OGR Geometry, which is then transformed.
|
||||||
g = gdal.OGRGeometry(self.wkb, srid)
|
g = gdal.OGRGeometry(self.wkb, srid)
|
||||||
g.transform(ct)
|
g.transform(ct)
|
||||||
|
|
|
@ -852,6 +852,114 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
|
||||||
self.assertAlmostEqual(trans.x, p.x, prec)
|
self.assertAlmostEqual(trans.x, p.x, prec)
|
||||||
self.assertAlmostEqual(trans.y, p.y, prec)
|
self.assertAlmostEqual(trans.y, p.y, prec)
|
||||||
|
|
||||||
|
def test23_transform_noop(self):
|
||||||
|
""" Testing `transform` method (SRID match) """
|
||||||
|
# transform() should no-op if source & dest SRIDs match,
|
||||||
|
# regardless of whether GDAL is available.
|
||||||
|
if gdal.HAS_GDAL:
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
gt = g.tuple
|
||||||
|
g.transform(4326)
|
||||||
|
self.assertEqual(g.tuple, gt)
|
||||||
|
self.assertEqual(g.srid, 4326)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
g1 = g.transform(4326, clone=True)
|
||||||
|
self.assertEqual(g1.tuple, g.tuple)
|
||||||
|
self.assertEqual(g1.srid, 4326)
|
||||||
|
self.assert_(g1 is not g, "Clone didn't happen")
|
||||||
|
|
||||||
|
old_has_gdal = gdal.HAS_GDAL
|
||||||
|
try:
|
||||||
|
gdal.HAS_GDAL = False
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
gt = g.tuple
|
||||||
|
g.transform(4326)
|
||||||
|
self.assertEqual(g.tuple, gt)
|
||||||
|
self.assertEqual(g.srid, 4326)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
g1 = g.transform(4326, clone=True)
|
||||||
|
self.assertEqual(g1.tuple, g.tuple)
|
||||||
|
self.assertEqual(g1.srid, 4326)
|
||||||
|
self.assert_(g1 is not g, "Clone didn't happen")
|
||||||
|
finally:
|
||||||
|
gdal.HAS_GDAL = old_has_gdal
|
||||||
|
|
||||||
|
def test23_transform_nosrid(self):
|
||||||
|
""" Testing `transform` method (no SRID) """
|
||||||
|
# raise a warning if SRID <0/None
|
||||||
|
import warnings
|
||||||
|
print "\nBEGIN - expecting Warnings; safe to ignore.\n"
|
||||||
|
|
||||||
|
# test for do-nothing behaviour.
|
||||||
|
try:
|
||||||
|
# Keeping line-noise down by only printing the relevant
|
||||||
|
# warnings once.
|
||||||
|
warnings.simplefilter('once', UserWarning)
|
||||||
|
warnings.simplefilter('once', FutureWarning)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
|
||||||
|
g.transform(2774)
|
||||||
|
self.assertEqual(g.tuple, (-104.609, 38.255))
|
||||||
|
self.assertEqual(g.srid, None)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
|
||||||
|
g1 = g.transform(2774, clone=True)
|
||||||
|
self.assert_(g1 is None)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
|
||||||
|
g.transform(2774)
|
||||||
|
self.assertEqual(g.tuple, (-104.609, 38.255))
|
||||||
|
self.assertEqual(g.srid, -1)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
|
||||||
|
g1 = g.transform(2774, clone=True)
|
||||||
|
self.assert_(g1 is None)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
warnings.simplefilter('default', UserWarning)
|
||||||
|
warnings.simplefilter('default', FutureWarning)
|
||||||
|
|
||||||
|
print "\nEND - expecting Warnings; safe to ignore.\n"
|
||||||
|
|
||||||
|
|
||||||
|
# test warning is raised
|
||||||
|
try:
|
||||||
|
warnings.simplefilter('error', FutureWarning)
|
||||||
|
warnings.simplefilter('ignore', UserWarning)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
|
||||||
|
self.assertRaises(FutureWarning, g.transform, 2774)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
|
||||||
|
self.assertRaises(FutureWarning, g.transform, 2774, clone=True)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
|
||||||
|
self.assertRaises(FutureWarning, g.transform, 2774)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
|
||||||
|
self.assertRaises(FutureWarning, g.transform, 2774, clone=True)
|
||||||
|
finally:
|
||||||
|
warnings.simplefilter('default', FutureWarning)
|
||||||
|
warnings.simplefilter('default', UserWarning)
|
||||||
|
|
||||||
|
|
||||||
|
def test23_transform_nogdal(self):
|
||||||
|
""" Testing `transform` method (GDAL not available) """
|
||||||
|
old_has_gdal = gdal.HAS_GDAL
|
||||||
|
try:
|
||||||
|
gdal.HAS_GDAL = False
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
self.assertRaises(GEOSException, g.transform, 2774)
|
||||||
|
|
||||||
|
g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
|
||||||
|
self.assertRaises(GEOSException, g.transform, 2774, clone=True)
|
||||||
|
finally:
|
||||||
|
gdal.HAS_GDAL = old_has_gdal
|
||||||
|
|
||||||
def test24_extent(self):
|
def test24_extent(self):
|
||||||
"Testing `extent` method."
|
"Testing `extent` method."
|
||||||
# The xmin, ymin, xmax, ymax of the MultiPoint should be returned.
|
# The xmin, ymin, xmax, ymax of the MultiPoint should be returned.
|
||||||
|
|
|
@ -147,6 +147,10 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||||
The ``supports_inactive_user`` variable is not checked any
|
The ``supports_inactive_user`` variable is not checked any
|
||||||
longer and can be removed.
|
longer and can be removed.
|
||||||
|
|
||||||
|
* :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
|
||||||
|
a :class:`~django.contrib.gis.geos.GEOSException` when called
|
||||||
|
on a geometry with no SRID value.
|
||||||
|
|
||||||
* 2.0
|
* 2.0
|
||||||
* ``django.views.defaults.shortcut()``. This function has been moved
|
* ``django.views.defaults.shortcut()``. This function has been moved
|
||||||
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
|
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
|
||||||
|
|
|
@ -523,7 +523,9 @@ corresponding to the SRID of the geometry or ``None``.
|
||||||
|
|
||||||
Requires GDAL.
|
Requires GDAL.
|
||||||
|
|
||||||
.. method:: transform(ct, clone=False)
|
.. method:: GEOSGeometry.transform(ct, clone=False)
|
||||||
|
|
||||||
|
.. versionchanged:: 1.3
|
||||||
|
|
||||||
Transforms the geometry according to the given coordinate transformation paramter
|
Transforms the geometry according to the given coordinate transformation paramter
|
||||||
(``ct``), which may be an integer SRID, spatial reference WKT string,
|
(``ct``), which may be an integer SRID, spatial reference WKT string,
|
||||||
|
@ -537,6 +539,16 @@ is returned instead.
|
||||||
|
|
||||||
Requires GDAL.
|
Requires GDAL.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Prior to 1.3, this method would silently no-op if GDAL was not available.
|
||||||
|
Now, a :class:`~django.contrib.gis.geos.GEOSException` is raised as
|
||||||
|
application code relying on this behavior is in error. In addition,
|
||||||
|
use of this method when the SRID is ``None`` or less than 0 now generates
|
||||||
|
a warning because a :class:`~django.contrib.gis.geos.GEOSException` will
|
||||||
|
be raised instead in version 1.5.
|
||||||
|
|
||||||
|
|
||||||
``Point``
|
``Point``
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
@ -98,8 +98,9 @@ Program Description Required
|
||||||
.. admonition:: Install GDAL
|
.. admonition:: Install GDAL
|
||||||
|
|
||||||
While :ref:`gdalbuild` is technically not required, it is *recommended*.
|
While :ref:`gdalbuild` is technically not required, it is *recommended*.
|
||||||
Some features of GeoDjango (including the :ref:`ref-layermapping` and the geographic
|
Important features of GeoDjango (including the :ref:`ref-layermapping`,
|
||||||
admin) depend on its functionality.
|
geometry reprojection, and the geographic admin) depend on its
|
||||||
|
functionality.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -273,9 +274,9 @@ supports :ref:`GDAL's vector data <ref-gdal>` capabilities [#]_.
|
||||||
|
|
||||||
First download the latest GDAL release version and untar the archive::
|
First download the latest GDAL release version and untar the archive::
|
||||||
|
|
||||||
$ wget http://download.osgeo.org/gdal/gdal-1.7.2.tar.gz
|
$ wget http://download.osgeo.org/gdal/gdal-1.7.3.tar.gz
|
||||||
$ tar xzf gdal-1.7.2.tar.gz
|
$ tar xzf gdal-1.7.3.tar.gz
|
||||||
$ cd gdal-1.7.2
|
$ cd gdal-1.7.3
|
||||||
|
|
||||||
Configure, make and install::
|
Configure, make and install::
|
||||||
|
|
||||||
|
|
|
@ -528,6 +528,14 @@ statements manually.
|
||||||
GeoDjango
|
GeoDjango
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
The :setting:`TEST_RUNNER` previously used to execute the GeoDjango test suite,
|
* The function-based :setting:`TEST_RUNNER` previously used to execute
|
||||||
:func:`django.contrib.gis.tests.run_gis_tests`, is deprecated in favor of
|
the GeoDjango test suite, :func:`django.contrib.gis.tests.run_gis_tests`,
|
||||||
the :class:`django.contrib.gis.tests.GeoDjangoTestSuiteRunner` class.
|
was deprecated for the class-bassed runner,
|
||||||
|
:class:`django.contrib.gis.tests.GeoDjangoTestSuiteRunner`.
|
||||||
|
|
||||||
|
* Previously, calling :meth:`~django.contrib.gis.geos.GEOSGeometry.transform`
|
||||||
|
would silently do nothing when GDAL wasn't available. Now,
|
||||||
|
a :class:`~django.contrib.gis.geos.GEOSException` is properly raised
|
||||||
|
to indicate possible faulty application code. A warning is now raised
|
||||||
|
if :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` is called when
|
||||||
|
the SRID of the geometry is less than 0 or ``None``.
|
||||||
|
|
Loading…
Reference in New Issue