Author: jbronn
Date: 2010-03-29 12:33:59 -0500 (Mon, 29 Mar 2010)
New Revision: 12878
Modified:
django/trunk/django/contrib/gis/gdal/geometries.py
django/trunk/django/contrib/gis/gdal/tests/test_geom.py
Log:
Fixed #12312 -- Set the coordinate dimension on each component of geometry
collections after transform (refines GDAL bug workaround introduced in r11628).
Thanks, yourcelf for bug report.
Modified: django/trunk/django/contrib/gis/gdal/geometries.py
===================================================================
--- django/trunk/django/contrib/gis/gdal/geometries.py 2010-03-29 16:48:38 UTC
(rev 12877)
+++ django/trunk/django/contrib/gis/gdal/geometries.py 2010-03-29 17:33:59 UTC
(rev 12878)
@@ -48,11 +48,11 @@
from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.error import OGRException, OGRIndexError,
SRSException
from django.contrib.gis.gdal.geomtype import OGRGeomType
+from django.contrib.gis.gdal.libgdal import GEOJSON, GDAL_VERSION
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
# Getting the ctypes prototype functions that interface w/the GDAL C library.
from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
-GEOJSON = capi.GEOJSON
# For recognizing geometry input.
from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex
@@ -400,7 +400,8 @@
# afterwards. This is done because of GDAL bug (in versions prior
# to 1.7) that turns geometries 3D after transformation, see:
# http://trac.osgeo.org/gdal/changeset/17792
- orig_dim = self.coord_dim
+ if GDAL_VERSION < (1, 7):
+ orig_dim = self.coord_dim
# Depending on the input type, use the appropriate OGR routine
# to perform the transformation.
@@ -412,11 +413,22 @@
sr = SpatialReference(coord_trans)
capi.geom_transform_to(self.ptr, sr.ptr)
else:
- raise TypeError('Transform only accepts CoordTransform,
SpatialReference, string, and integer objects.')
+ raise TypeError('Transform only accepts CoordTransform, '
+ 'SpatialReference, string, and integer objects.')
# Setting with original dimension, see comment above.
- if self.coord_dim != orig_dim:
- self.coord_dim = orig_dim
+ if GDAL_VERSION < (1, 7):
+ if isinstance(self, GeometryCollection):
+ # With geometry collections have to set dimension on
+ # each internal geometry reference, as the collection
+ # dimension isn't affected.
+ for i in xrange(len(self)):
+ internal_ptr = capi.get_geom_ref(self.ptr, i)
+ if orig_dim != capi.get_coord_dim(internal_ptr):
+ capi.set_coord_dim(internal_ptr, orig_dim)
+ else:
+ if self.coord_dim != orig_dim:
+ self.coord_dim = orig_dim
def transform_to(self, srs):
"For backwards-compatibility."
Modified: django/trunk/django/contrib/gis/gdal/tests/test_geom.py
===================================================================
--- django/trunk/django/contrib/gis/gdal/tests/test_geom.py 2010-03-29
16:48:38 UTC (rev 12877)
+++ django/trunk/django/contrib/gis/gdal/tests/test_geom.py 2010-03-29
17:33:59 UTC (rev 12878)
@@ -136,7 +136,7 @@
self.assertEqual(mgeom1, mgeom3)
self.assertEqual(mp.points, mgeom2.tuple)
self.assertEqual(mp.n_p, mgeom2.point_count)
-
+
def test04_linestring(self):
"Testing LineString objects."
prev = OGRGeometry('POINT(0 0)')
@@ -172,7 +172,7 @@
for ls in mlinestr:
self.assertEqual(2, ls.geom_type)
self.assertEqual('LINESTRING', ls.geom_name)
- self.assertRaises(OGRIndexError, mlinestr.__getitem__,
len(mlinestr))
+ self.assertRaises(OGRIndexError, mlinestr.__getitem__,
len(mlinestr))
def test06_linearring(self):
"Testing LinearRing objects."
@@ -190,7 +190,7 @@
"Testing Polygon objects."
# Testing `from_bbox` class method
- bbox = (-180,-90,180,90)
+ bbox = (-180,-90,180,90)
p = OGRGeometry.from_bbox( bbox )
self.assertEqual(bbox, p.extent)
@@ -211,13 +211,13 @@
# Testing equivalence
self.assertEqual(True, poly == OGRGeometry(p.wkt))
self.assertEqual(True, poly != prev)
-
+
if p.ext_ring_cs:
ring = poly[0]
self.assertEqual(p.ext_ring_cs, ring.tuple)
self.assertEqual(p.ext_ring_cs, poly[0].tuple)
self.assertEqual(len(p.ext_ring_cs), ring.point_count)
-
+
for r in poly:
self.assertEqual('LINEARRING', r.geom_name)
@@ -269,11 +269,11 @@
sr = SpatialReference('WGS84')
mpoly = OGRGeometry(mp.wkt, sr)
self.assertEqual(sr.wkt, mpoly.srs.wkt)
-
+
# Ensuring that SRS is propagated to clones.
klone = mpoly.clone()
self.assertEqual(sr.wkt, klone.srs.wkt)
-
+
# Ensuring all children geometries (polygons and their rings) all
# return the assigned spatial reference as well.
for poly in mpoly:
@@ -295,7 +295,7 @@
mpoly.srs = SpatialReference(4269)
self.assertEqual(4269, mpoly.srid)
self.assertEqual('NAD83', mpoly.srs.name)
-
+
# Incrementing through the multipolyogn after the spatial reference
# has been re-assigned.
for poly in mpoly:
@@ -341,7 +341,7 @@
"Testing coordinate dimension is the same on transformed geometries."
ls_orig = OGRGeometry('LINESTRING(-104.609 38.255)', 4326)
ls_trans = OGRGeometry('LINESTRING(992385.4472045 481455.4944650)',
2774)
-
+
prec = 3
ls_orig.transform(ls_trans.srs)
# Making sure the coordinate dimension is still 2D.
@@ -388,7 +388,7 @@
self.assertEqual(d1, a ^ b) # __xor__ is symmetric difference
operator
a ^= b # testing __ixor__
self.assertEqual(d1, a)
-
+
def test13_union(self):
"Testing union()."
for i in xrange(len(topology_geoms)):
@@ -455,8 +455,32 @@
self.assertEqual(g1, g2)
self.assertEqual(4326, g2.srs.srid)
self.assertEqual(g1.srs.wkt, g2.srs.wkt)
-
+ def test18_ogrgeometry_transform_workaround(self):
+ "Testing coordinate dimensions on geometries after transformation."
+ # A bug in GDAL versions prior to 1.7 changes the coordinate
+ # dimension of a geometry after it has been transformed.
+ # This test ensures that the bug workarounds employed within
+ # `OGRGeometry.transform` indeed work.
+ wkt_2d = "MULTILINESTRING ((0 0,1 1,2 2))"
+ wkt_3d = "MULTILINESTRING ((0 0 0,1 1 1,2 2 2))"
+ srid = 4326
+
+ # For both the 2D and 3D MultiLineString, ensure _both_ the dimension
+ # of the collection and the component LineString have the expected
+ # coordinate dimension after transform.
+ geom = OGRGeometry(wkt_2d, srid)
+ geom.transform(srid)
+ self.assertEqual(2, geom.coord_dim)
+ self.assertEqual(2, geom[0].coord_dim)
+ self.assertEqual(wkt_2d, geom.wkt)
+
+ geom = OGRGeometry(wkt_3d, srid)
+ geom.transform(srid)
+ self.assertEqual(3, geom.coord_dim)
+ self.assertEqual(3, geom[0].coord_dim)
+ self.assertEqual(wkt_3d, geom.wkt)
+
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(OGRGeomTest))
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.