mirror of https://github.com/django/django.git
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.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12878 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
7d25682108
commit
87302ac009
|
@ -48,11 +48,11 @@ from django.contrib.gis.gdal.base import GDALBase
|
|||
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 @@ class OGRGeometry(GDALBase):
|
|||
# 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 @@ class OGRGeometry(GDALBase):
|
|||
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."
|
||||
|
|
|
@ -136,7 +136,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
"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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
# 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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
"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 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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,7 +455,31 @@ class OGRGeomTest(unittest.TestCase):
|
|||
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()
|
||||
|
|
Loading…
Reference in New Issue