Fixed regression introduced in r13755 that prevented the running of the GEOS/GDAL test suites without configuring Django settings; moved reference geometry data from Python module to compressed JSON fixture; put in workaround in tests for GDAL bug #3783.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14414 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
34e545a938
commit
315ae1ce6e
|
@ -1,20 +1,7 @@
|
|||
import os, os.path, unittest
|
||||
from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError
|
||||
from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError, GDAL_VERSION
|
||||
from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString
|
||||
from django.contrib import gis
|
||||
|
||||
# Path for SHP files
|
||||
data_path = os.path.join(os.path.dirname(gis.__file__), 'tests' + os.sep + 'data')
|
||||
def get_ds_file(name, ext):
|
||||
return os.sep.join([data_path, name, name + '.%s' % ext])
|
||||
|
||||
# Test SHP data source object
|
||||
class TestDS:
|
||||
def __init__(self, name, **kwargs):
|
||||
ext = kwargs.pop('ext', 'shp')
|
||||
self.ds = get_ds_file(name, ext)
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, value)
|
||||
from django.contrib.gis.geometry.test_data import get_ds_file, TestDS
|
||||
|
||||
# List of acceptable data sources.
|
||||
ds_list = (TestDS('test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='ESRI Shapefile',
|
||||
|
@ -28,7 +15,7 @@ ds_list = (TestDS('test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='
|
|||
extent=(1.0, 2.0, 100.0, 523.5), # Min/Max from CSV
|
||||
field_values={'POINT_X' : ['1.0', '5.0', '100.0'], 'POINT_Y' : ['2.0', '23.0', '523.5'], 'NUM' : ['5', '17', '23']},
|
||||
fids=range(1,4)),
|
||||
TestDS('test_poly', nfeat=3, nfld=3, geom='POLYGON', gtype=3,
|
||||
TestDS('test_poly', nfeat=3, nfld=3, geom='POLYGON', gtype=3,
|
||||
driver='ESRI Shapefile',
|
||||
fields={'float' : OFTReal, 'int' : OFTInteger, 'str' : OFTString,},
|
||||
extent=(-1.01513,-0.558245,0.161876,0.839637), # Got extent from QGIS
|
||||
|
@ -63,7 +50,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
pass
|
||||
else:
|
||||
self.fail('Expected an IndexError!')
|
||||
|
||||
|
||||
def test02_invalid_shp(self):
|
||||
"Testing invalid SHP files for the Data Source."
|
||||
for source in bad_ds:
|
||||
|
@ -76,7 +63,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
ds = DataSource(source.ds)
|
||||
|
||||
# Incrementing through each layer, this tests DataSource.__iter__
|
||||
for layer in ds:
|
||||
for layer in ds:
|
||||
# Making sure we get the number of features we expect
|
||||
self.assertEqual(len(layer), source.nfeat)
|
||||
|
||||
|
@ -85,16 +72,22 @@ class DataSourceTest(unittest.TestCase):
|
|||
self.assertEqual(source.nfld, len(layer.fields))
|
||||
|
||||
# Testing the layer's extent (an Envelope), and it's properties
|
||||
self.assertEqual(True, isinstance(layer.extent, Envelope))
|
||||
self.assertAlmostEqual(source.extent[0], layer.extent.min_x, 5)
|
||||
self.assertAlmostEqual(source.extent[1], layer.extent.min_y, 5)
|
||||
self.assertAlmostEqual(source.extent[2], layer.extent.max_x, 5)
|
||||
self.assertAlmostEqual(source.extent[3], layer.extent.max_y, 5)
|
||||
if source.driver == 'VRT' and (GDAL_VERSION > (1, 7, 0) and GDAL_VERSION < (1, 7, 3)):
|
||||
# There's a known GDAL regression with retrieving the extent
|
||||
# of a VRT layer in versions 1.7.0-1.7.2:
|
||||
# http://trac.osgeo.org/gdal/ticket/3783
|
||||
pass
|
||||
else:
|
||||
self.assertEqual(True, isinstance(layer.extent, Envelope))
|
||||
self.assertAlmostEqual(source.extent[0], layer.extent.min_x, 5)
|
||||
self.assertAlmostEqual(source.extent[1], layer.extent.min_y, 5)
|
||||
self.assertAlmostEqual(source.extent[2], layer.extent.max_x, 5)
|
||||
self.assertAlmostEqual(source.extent[3], layer.extent.max_y, 5)
|
||||
|
||||
# Now checking the field names.
|
||||
flds = layer.fields
|
||||
for f in flds: self.assertEqual(True, f in source.fields)
|
||||
|
||||
|
||||
# Negative FIDs are not allowed.
|
||||
self.assertRaises(OGRIndexError, layer.__getitem__, -1)
|
||||
self.assertRaises(OGRIndexError, layer.__getitem__, 50000)
|
||||
|
@ -115,7 +108,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
for fld_name in fld_names:
|
||||
self.assertEqual(source.field_values[fld_name][i], feat.get(fld_name))
|
||||
print "\nEND - expecting out of range feature id error; safe to ignore."
|
||||
|
||||
|
||||
def test03b_layer_slice(self):
|
||||
"Test indexing and slicing on Layers."
|
||||
# Using the first data-source because the same slice
|
||||
|
@ -146,7 +139,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
# Making sure we can call OGR routines on the Layer returned.
|
||||
lyr = get_layer()
|
||||
self.assertEqual(source.nfeat, len(lyr))
|
||||
self.assertEqual(source.gtype, lyr.geom_type.num)
|
||||
self.assertEqual(source.gtype, lyr.geom_type.num)
|
||||
|
||||
def test04_features(self):
|
||||
"Testing Data Source Features."
|
||||
|
@ -170,7 +163,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
|
||||
# Testing Feature.__iter__
|
||||
for fld in feat: self.assertEqual(True, fld.name in source.fields.keys())
|
||||
|
||||
|
||||
def test05_geometries(self):
|
||||
"Testing Geometries from Data Source Features."
|
||||
for source in ds_list:
|
||||
|
@ -223,7 +216,7 @@ class DataSourceTest(unittest.TestCase):
|
|||
# should indicate that there are 3 features in the Layer.
|
||||
lyr.spatial_filter = None
|
||||
self.assertEqual(3, len(lyr))
|
||||
|
||||
|
||||
def suite():
|
||||
s = unittest.TestSuite()
|
||||
s.addTest(unittest.makeSuite(DataSourceTest))
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, \
|
||||
OGRException, OGRIndexError, SpatialReference, CoordTransform, \
|
||||
gdal_version
|
||||
from django.contrib.gis.tests.geometries import *
|
||||
from django.utils import unittest
|
||||
from django.contrib.gis.geometry.test_data import TestDataMixin
|
||||
|
||||
|
||||
class OGRGeomTest(unittest.TestCase):
|
||||
class OGRGeomTest(unittest.TestCase, TestDataMixin):
|
||||
"This tests the OGR Geometry."
|
||||
|
||||
def test00a_geomtype(self):
|
||||
|
@ -56,7 +55,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test01a_wkt(self):
|
||||
"Testing WKT output."
|
||||
for g in wkt_out:
|
||||
for g in self.geometries.wkt_out:
|
||||
geom = OGRGeometry(g.wkt)
|
||||
self.assertEqual(g.wkt, geom.wkt)
|
||||
|
||||
|
@ -73,13 +72,13 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test01b_gml(self):
|
||||
"Testing GML output."
|
||||
for g in wkt_out:
|
||||
for g in self.geometries.wkt_out:
|
||||
geom = OGRGeometry(g.wkt)
|
||||
self.assertEqual(g.gml, geom.gml)
|
||||
|
||||
def test01c_hex(self):
|
||||
"Testing HEX input/output."
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
geom1 = OGRGeometry(g.wkt)
|
||||
self.assertEqual(g.hex, geom1.hex)
|
||||
# Constructing w/HEX
|
||||
|
@ -89,7 +88,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
def test01d_wkb(self):
|
||||
"Testing WKB input/output."
|
||||
from binascii import b2a_hex
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
geom1 = OGRGeometry(g.wkt)
|
||||
wkb = geom1.wkb
|
||||
self.assertEqual(b2a_hex(wkb).upper(), g.hex)
|
||||
|
@ -101,7 +100,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
"Testing GeoJSON input/output."
|
||||
from django.contrib.gis.gdal.prototypes.geom import GEOJSON
|
||||
if not GEOJSON: return
|
||||
for g in json_geoms:
|
||||
for g in self.geometries.json_geoms:
|
||||
geom = OGRGeometry(g.wkt)
|
||||
if not hasattr(g, 'not_equal'):
|
||||
self.assertEqual(g.json, geom.json)
|
||||
|
@ -112,7 +111,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
"Testing Point objects."
|
||||
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for p in points:
|
||||
for p in self.geometries.points:
|
||||
if not hasattr(p, 'z'): # No 3D
|
||||
pnt = OGRGeometry(p.wkt)
|
||||
self.assertEqual(1, pnt.geom_type)
|
||||
|
@ -123,8 +122,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test03_multipoints(self):
|
||||
"Testing MultiPoint objects."
|
||||
|
||||
for mp in multipoints:
|
||||
for mp in self.geometries.multipoints:
|
||||
mgeom1 = OGRGeometry(mp.wkt) # First one from WKT
|
||||
self.assertEqual(4, mgeom1.geom_type)
|
||||
self.assertEqual('MULTIPOINT', mgeom1.geom_name)
|
||||
|
@ -135,38 +133,38 @@ class OGRGeomTest(unittest.TestCase):
|
|||
mgeom3.add(g.wkt) # should take WKT as well
|
||||
self.assertEqual(mgeom1, mgeom2) # they should equal
|
||||
self.assertEqual(mgeom1, mgeom3)
|
||||
self.assertEqual(mp.points, mgeom2.tuple)
|
||||
self.assertEqual(mp.coords, mgeom2.coords)
|
||||
self.assertEqual(mp.n_p, mgeom2.point_count)
|
||||
|
||||
def test04_linestring(self):
|
||||
"Testing LineString objects."
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for ls in linestrings:
|
||||
for ls in self.geometries.linestrings:
|
||||
linestr = OGRGeometry(ls.wkt)
|
||||
self.assertEqual(2, linestr.geom_type)
|
||||
self.assertEqual('LINESTRING', linestr.geom_name)
|
||||
self.assertEqual(ls.n_p, linestr.point_count)
|
||||
self.assertEqual(ls.tup, linestr.tuple)
|
||||
self.assertEqual(ls.coords, linestr.tuple)
|
||||
self.assertEqual(True, linestr == OGRGeometry(ls.wkt))
|
||||
self.assertEqual(True, linestr != prev)
|
||||
self.assertRaises(OGRIndexError, linestr.__getitem__, len(linestr))
|
||||
prev = linestr
|
||||
|
||||
# Testing the x, y properties.
|
||||
x = [tmpx for tmpx, tmpy in ls.tup]
|
||||
y = [tmpy for tmpx, tmpy in ls.tup]
|
||||
x = [tmpx for tmpx, tmpy in ls.coords]
|
||||
y = [tmpy for tmpx, tmpy in ls.coords]
|
||||
self.assertEqual(x, linestr.x)
|
||||
self.assertEqual(y, linestr.y)
|
||||
|
||||
def test05_multilinestring(self):
|
||||
"Testing MultiLineString objects."
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for mls in multilinestrings:
|
||||
for mls in self.geometries.multilinestrings:
|
||||
mlinestr = OGRGeometry(mls.wkt)
|
||||
self.assertEqual(5, mlinestr.geom_type)
|
||||
self.assertEqual('MULTILINESTRING', mlinestr.geom_name)
|
||||
self.assertEqual(mls.n_p, mlinestr.point_count)
|
||||
self.assertEqual(mls.tup, mlinestr.tuple)
|
||||
self.assertEqual(mls.coords, mlinestr.tuple)
|
||||
self.assertEqual(True, mlinestr == OGRGeometry(mls.wkt))
|
||||
self.assertEqual(True, mlinestr != prev)
|
||||
prev = mlinestr
|
||||
|
@ -178,7 +176,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
def test06_linearring(self):
|
||||
"Testing LinearRing objects."
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for rr in linearrings:
|
||||
for rr in self.geometries.linearrings:
|
||||
lr = OGRGeometry(rr.wkt)
|
||||
#self.assertEqual(101, lr.geom_type.num)
|
||||
self.assertEqual('LINEARRING', lr.geom_name)
|
||||
|
@ -196,7 +194,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
self.assertEqual(bbox, p.extent)
|
||||
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for p in polygons:
|
||||
for p in self.geometries.polygons:
|
||||
poly = OGRGeometry(p.wkt)
|
||||
self.assertEqual(3, poly.geom_type)
|
||||
self.assertEqual('POLYGON', poly.geom_name)
|
||||
|
@ -250,7 +248,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
def test08_multipolygons(self):
|
||||
"Testing MultiPolygon objects."
|
||||
prev = OGRGeometry('POINT(0 0)')
|
||||
for mp in multipolygons:
|
||||
for mp in self.geometries.multipolygons:
|
||||
mpoly = OGRGeometry(mp.wkt)
|
||||
self.assertEqual(6, mpoly.geom_type)
|
||||
self.assertEqual('MULTIPOLYGON', mpoly.geom_name)
|
||||
|
@ -265,7 +263,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test09a_srs(self):
|
||||
"Testing OGR Geometries with Spatial Reference objects."
|
||||
for mp in multipolygons:
|
||||
for mp in self.geometries.multipolygons:
|
||||
# Creating a geometry w/spatial reference
|
||||
sr = SpatialReference('WGS84')
|
||||
mpoly = OGRGeometry(mp.wkt, sr)
|
||||
|
@ -283,8 +281,8 @@ class OGRGeomTest(unittest.TestCase):
|
|||
self.assertEqual(sr.wkt, ring.srs.wkt)
|
||||
|
||||
# Ensuring SRS propagate in topological ops.
|
||||
a, b = topology_geoms[0]
|
||||
a, b = OGRGeometry(a.wkt, sr), OGRGeometry(b.wkt, sr)
|
||||
a = OGRGeometry(self.geometries.topology_geoms[0].wkt_a, sr)
|
||||
b = OGRGeometry(self.geometries.topology_geoms[0].wkt_b, sr)
|
||||
diff = a.difference(b)
|
||||
union = a.union(b)
|
||||
self.assertEqual(sr.wkt, diff.srs.wkt)
|
||||
|
@ -352,11 +350,10 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test10_difference(self):
|
||||
"Testing difference()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = OGRGeometry(g_tup[0].wkt)
|
||||
b = OGRGeometry(g_tup[1].wkt)
|
||||
d1 = OGRGeometry(diff_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
|
||||
d1 = OGRGeometry(self.geometries.diff_geoms[i].wkt)
|
||||
d2 = a.difference(b)
|
||||
self.assertEqual(d1, d2)
|
||||
self.assertEqual(d1, a - b) # __sub__ is difference operator
|
||||
|
@ -365,11 +362,10 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test11_intersection(self):
|
||||
"Testing intersects() and intersection()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = OGRGeometry(g_tup[0].wkt)
|
||||
b = OGRGeometry(g_tup[1].wkt)
|
||||
i1 = OGRGeometry(intersect_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
|
||||
i1 = OGRGeometry(self.geometries.intersect_geoms[i].wkt)
|
||||
self.assertEqual(True, a.intersects(b))
|
||||
i2 = a.intersection(b)
|
||||
self.assertEqual(i1, i2)
|
||||
|
@ -379,11 +375,10 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test12_symdifference(self):
|
||||
"Testing sym_difference()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = OGRGeometry(g_tup[0].wkt)
|
||||
b = OGRGeometry(g_tup[1].wkt)
|
||||
d1 = OGRGeometry(sdiff_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
|
||||
d1 = OGRGeometry(self.geometries.sdiff_geoms[i].wkt)
|
||||
d2 = a.sym_difference(b)
|
||||
self.assertEqual(d1, d2)
|
||||
self.assertEqual(d1, a ^ b) # __xor__ is symmetric difference operator
|
||||
|
@ -392,11 +387,10 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
def test13_union(self):
|
||||
"Testing union()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = OGRGeometry(g_tup[0].wkt)
|
||||
b = OGRGeometry(g_tup[1].wkt)
|
||||
u1 = OGRGeometry(union_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
|
||||
u1 = OGRGeometry(self.geometries.union_geoms[i].wkt)
|
||||
u2 = a.union(b)
|
||||
self.assertEqual(u1, u2)
|
||||
self.assertEqual(u1, a | b) # __or__ is union operator
|
||||
|
@ -412,7 +406,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
|
||||
# GeometryCollection.add may take an OGRGeometry (if another collection
|
||||
# of the same type all child geoms will be added individually) or WKT.
|
||||
for mp in multipolygons:
|
||||
for mp in self.geometries.multipolygons:
|
||||
mpoly = OGRGeometry(mp.wkt)
|
||||
mp1 = OGRGeometry('MultiPolygon')
|
||||
mp2 = OGRGeometry('MultiPolygon')
|
||||
|
@ -430,7 +424,7 @@ class OGRGeomTest(unittest.TestCase):
|
|||
mp = OGRGeometry('MULTIPOINT(5 23, 0 0, 10 50)')
|
||||
self.assertEqual((0.0, 0.0, 10.0, 50.0), mp.extent)
|
||||
# Testing on the 'real world' Polygon.
|
||||
poly = OGRGeometry(polygons[3].wkt)
|
||||
poly = OGRGeometry(self.geometries.polygons[3].wkt)
|
||||
ring = poly.shell
|
||||
x, y = ring.x, ring.y
|
||||
xmin, ymin = min(x), min(y)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
"""
|
||||
This module has the mock object definitions used to hold reference geometry
|
||||
for the GEOS and GDAL tests.
|
||||
"""
|
||||
import gzip
|
||||
import os
|
||||
|
||||
from django.contrib import gis
|
||||
from django.utils import simplejson
|
||||
|
||||
|
||||
# This global used to store reference geometry data.
|
||||
GEOMETRIES = None
|
||||
|
||||
# Path where reference test data is located.
|
||||
TEST_DATA = os.path.join(os.path.dirname(gis.__file__), 'tests', 'data')
|
||||
|
||||
|
||||
def tuplize(seq):
|
||||
"Turn all nested sequences to tuples in given sequence."
|
||||
if isinstance(seq, (list, tuple)):
|
||||
return tuple([tuplize(i) for i in seq])
|
||||
return seq
|
||||
|
||||
|
||||
def get_ds_file(name, ext):
|
||||
return os.path.join(TEST_DATA,
|
||||
name,
|
||||
name + '.%s' % ext
|
||||
)
|
||||
|
||||
|
||||
class TestObj(object):
|
||||
"""
|
||||
Base testing object, turns keyword args into attributes.
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
class TestDS(TestObj):
|
||||
"""
|
||||
Object for testing GDAL data sources.
|
||||
"""
|
||||
def __init__(self, name, **kwargs):
|
||||
# Shapefile is default extension, unless specified otherwise.
|
||||
ext = kwargs.pop('ext', 'shp')
|
||||
self.ds = get_ds_file(name, ext)
|
||||
super(TestDS, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class TestGeom(TestObj):
|
||||
"""
|
||||
Testing object used for wrapping reference geometry data
|
||||
in GEOS/GDAL tests.
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
# Converting lists to tuples of certain keyword args
|
||||
# so coordinate test cases will match (JSON has no
|
||||
# concept of tuple).
|
||||
coords = kwargs.pop('coords', None)
|
||||
if coords:
|
||||
self.coords = tuplize(coords)
|
||||
|
||||
centroid = kwargs.pop('centroid', None)
|
||||
if centroid:
|
||||
self.centroid = tuple(centroid)
|
||||
|
||||
ext_ring_cs = kwargs.pop('ext_ring_cs', None)
|
||||
if ext_ring_cs:
|
||||
ext_ring_cs = tuplize(ext_ring_cs)
|
||||
self.ext_ring_cs = ext_ring_cs
|
||||
|
||||
super(TestGeom, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class TestGeomSet(object):
|
||||
"""
|
||||
Each attribute of this object is a list of `TestGeom` instances.
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, [TestGeom(**kwargs) for kwargs in value])
|
||||
|
||||
|
||||
class TestDataMixin(object):
|
||||
"""
|
||||
Mixin used for GEOS/GDAL test cases that defines a `geometries`
|
||||
property, which returns and/or loads the reference geometry data.
|
||||
"""
|
||||
@property
|
||||
def geometries(self):
|
||||
global GEOMETRIES
|
||||
if GEOMETRIES is None:
|
||||
# Load up the test geometry data from fixture into global.
|
||||
gzf = gzip.GzipFile(os.path.join(TEST_DATA, 'geometries.json.gz'))
|
||||
geometries = simplejson.loads(gzf.read())
|
||||
GEOMETRIES = TestGeomSet(**geometries)
|
||||
return GEOMETRIES
|
|
@ -1,9 +1,9 @@
|
|||
import ctypes, random, unittest, sys
|
||||
from django.contrib.gis.geos import *
|
||||
from django.contrib.gis.geos.base import gdal, numpy, GEOSBase
|
||||
from django.contrib.gis.tests.geometries import *
|
||||
from django.contrib.gis.geometry.test_data import TestDataMixin
|
||||
|
||||
class GEOSTest(unittest.TestCase):
|
||||
class GEOSTest(unittest.TestCase, TestDataMixin):
|
||||
|
||||
@property
|
||||
def null_srid(self):
|
||||
|
@ -61,13 +61,13 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test01a_wkt(self):
|
||||
"Testing WKT output."
|
||||
for g in wkt_out:
|
||||
for g in self.geometries.wkt_out:
|
||||
geom = fromstr(g.wkt)
|
||||
self.assertEqual(g.ewkt, geom.wkt)
|
||||
|
||||
def test01b_hex(self):
|
||||
"Testing HEX output."
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
geom = fromstr(g.wkt)
|
||||
self.assertEqual(g.hex, geom.hex)
|
||||
|
||||
|
@ -75,9 +75,16 @@ class GEOSTest(unittest.TestCase):
|
|||
"Testing (HEX)EWKB output."
|
||||
from binascii import a2b_hex
|
||||
|
||||
# For testing HEX(EWKB).
|
||||
ogc_hex = '01010000000000000000000000000000000000F03F'
|
||||
# `SELECT ST_AsHEXEWKB(ST_GeomFromText('POINT(0 1)', 4326));`
|
||||
hexewkb_2d = '0101000020E61000000000000000000000000000000000F03F'
|
||||
# `SELECT ST_AsHEXEWKB(ST_GeomFromEWKT('SRID=4326;POINT(0 1 2)'));`
|
||||
hexewkb_3d = '01010000A0E61000000000000000000000000000000000F03F0000000000000040'
|
||||
|
||||
pnt_2d = Point(0, 1, srid=4326)
|
||||
pnt_3d = Point(0, 1, 2, srid=4326)
|
||||
|
||||
|
||||
# OGC-compliant HEX will not have SRID nor Z value.
|
||||
self.assertEqual(ogc_hex, pnt_2d.hex)
|
||||
self.assertEqual(ogc_hex, pnt_3d.hex)
|
||||
|
@ -110,13 +117,13 @@ class GEOSTest(unittest.TestCase):
|
|||
pass
|
||||
else:
|
||||
self.fail('Should have raised GEOSException')
|
||||
|
||||
|
||||
# Redundant sanity check.
|
||||
self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid)
|
||||
|
||||
def test01c_kml(self):
|
||||
"Testing KML output."
|
||||
for tg in wkt_out:
|
||||
for tg in self.geometries.wkt_out:
|
||||
geom = fromstr(tg.wkt)
|
||||
kml = getattr(tg, 'kml', False)
|
||||
if kml: self.assertEqual(kml, geom.kml)
|
||||
|
@ -125,7 +132,7 @@ class GEOSTest(unittest.TestCase):
|
|||
"Testing the Error handlers."
|
||||
# string-based
|
||||
print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n"
|
||||
for err in errors:
|
||||
for err in self.geometries.errors:
|
||||
try:
|
||||
g = fromstr(err.wkt)
|
||||
except (GEOSException, ValueError):
|
||||
|
@ -147,14 +154,14 @@ class GEOSTest(unittest.TestCase):
|
|||
def test01e_wkb(self):
|
||||
"Testing WKB output."
|
||||
from binascii import b2a_hex
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
geom = fromstr(g.wkt)
|
||||
wkb = geom.wkb
|
||||
self.assertEqual(b2a_hex(wkb).upper(), g.hex)
|
||||
|
||||
def test01f_create_hex(self):
|
||||
"Testing creation from HEX."
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
geom_h = GEOSGeometry(g.hex)
|
||||
# we need to do this so decimal places get normalised
|
||||
geom_t = fromstr(g.wkt)
|
||||
|
@ -163,7 +170,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test01g_create_wkb(self):
|
||||
"Testing creation from WKB."
|
||||
from binascii import a2b_hex
|
||||
for g in hex_wkt:
|
||||
for g in self.geometries.hex_wkt:
|
||||
wkb = buffer(a2b_hex(g.hex))
|
||||
geom_h = GEOSGeometry(wkb)
|
||||
# we need to do this so decimal places get normalised
|
||||
|
@ -173,7 +180,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test01h_ewkt(self):
|
||||
"Testing EWKT."
|
||||
srid = 32140
|
||||
for p in polygons:
|
||||
for p in self.geometries.polygons:
|
||||
ewkt = 'SRID=%d;%s' % (srid, p.wkt)
|
||||
poly = fromstr(ewkt)
|
||||
self.assertEqual(srid, poly.srid)
|
||||
|
@ -183,7 +190,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test01i_json(self):
|
||||
"Testing GeoJSON input/output (via GDAL)."
|
||||
if not gdal or not gdal.GEOJSON: return
|
||||
for g in json_geoms:
|
||||
for g in self.geometries.json_geoms:
|
||||
geom = GEOSGeometry(g.wkt)
|
||||
if not hasattr(g, 'not_equal'):
|
||||
self.assertEqual(g.json, geom.json)
|
||||
|
@ -225,7 +232,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test02a_points(self):
|
||||
"Testing Point objects."
|
||||
prev = fromstr('POINT(0 0)')
|
||||
for p in points:
|
||||
for p in self.geometries.points:
|
||||
# Creating the point from the WKT
|
||||
pnt = fromstr(p.wkt)
|
||||
self.assertEqual(pnt.geom_type, 'Point')
|
||||
|
@ -279,7 +286,7 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test02b_multipoints(self):
|
||||
"Testing MultiPoint objects."
|
||||
for mp in multipoints:
|
||||
for mp in self.geometries.multipoints:
|
||||
mpnt = fromstr(mp.wkt)
|
||||
self.assertEqual(mpnt.geom_type, 'MultiPoint')
|
||||
self.assertEqual(mpnt.geom_typeid, 4)
|
||||
|
@ -289,7 +296,7 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
self.assertRaises(GEOSIndexError, mpnt.__getitem__, len(mpnt))
|
||||
self.assertEqual(mp.centroid, mpnt.centroid.tuple)
|
||||
self.assertEqual(mp.points, tuple(m.tuple for m in mpnt))
|
||||
self.assertEqual(mp.coords, tuple(m.tuple for m in mpnt))
|
||||
for p in mpnt:
|
||||
self.assertEqual(p.geom_type, 'Point')
|
||||
self.assertEqual(p.geom_typeid, 0)
|
||||
|
@ -299,7 +306,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test03a_linestring(self):
|
||||
"Testing LineString objects."
|
||||
prev = fromstr('POINT(0 0)')
|
||||
for l in linestrings:
|
||||
for l in self.geometries.linestrings:
|
||||
ls = fromstr(l.wkt)
|
||||
self.assertEqual(ls.geom_type, 'LineString')
|
||||
self.assertEqual(ls.geom_typeid, 1)
|
||||
|
@ -325,7 +332,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test03b_multilinestring(self):
|
||||
"Testing MultiLineString objects."
|
||||
prev = fromstr('POINT(0 0)')
|
||||
for l in multilinestrings:
|
||||
for l in self.geometries.multilinestrings:
|
||||
ml = fromstr(l.wkt)
|
||||
self.assertEqual(ml.geom_type, 'MultiLineString')
|
||||
self.assertEqual(ml.geom_typeid, 5)
|
||||
|
@ -348,7 +355,7 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test04_linearring(self):
|
||||
"Testing LinearRing objects."
|
||||
for rr in linearrings:
|
||||
for rr in self.geometries.linearrings:
|
||||
lr = fromstr(rr.wkt)
|
||||
self.assertEqual(lr.geom_type, 'LinearRing')
|
||||
self.assertEqual(lr.geom_typeid, 2)
|
||||
|
@ -371,7 +378,7 @@ class GEOSTest(unittest.TestCase):
|
|||
self.assertEqual(bbox, p.extent)
|
||||
|
||||
prev = fromstr('POINT(0 0)')
|
||||
for p in polygons:
|
||||
for p in self.geometries.polygons:
|
||||
# Creating the Polygon, testing its properties.
|
||||
poly = fromstr(p.wkt)
|
||||
self.assertEqual(poly.geom_type, 'Polygon')
|
||||
|
@ -430,7 +437,7 @@ class GEOSTest(unittest.TestCase):
|
|||
"Testing MultiPolygon objects."
|
||||
print "\nBEGIN - expecting GEOS_NOTICE; safe to ignore.\n"
|
||||
prev = fromstr('POINT (0 0)')
|
||||
for mp in multipolygons:
|
||||
for mp in self.geometries.multipolygons:
|
||||
mpoly = fromstr(mp.wkt)
|
||||
self.assertEqual(mpoly.geom_type, 'MultiPolygon')
|
||||
self.assertEqual(mpoly.geom_typeid, 6)
|
||||
|
@ -456,7 +463,7 @@ class GEOSTest(unittest.TestCase):
|
|||
# These tests are needed to ensure sanity with writable geometries.
|
||||
|
||||
# Getting a polygon with interior rings, and pulling out the interior rings
|
||||
poly = fromstr(polygons[1].wkt)
|
||||
poly = fromstr(self.geometries.polygons[1].wkt)
|
||||
ring1 = poly[0]
|
||||
ring2 = poly[1]
|
||||
|
||||
|
@ -472,12 +479,9 @@ class GEOSTest(unittest.TestCase):
|
|||
# Access to these rings is OK since they are clones.
|
||||
s1, s2 = str(ring1), str(ring2)
|
||||
|
||||
# The previous hijinks tests are now moot because only clones are
|
||||
# now used =)
|
||||
|
||||
def test08_coord_seq(self):
|
||||
"Testing Coordinate Sequence objects."
|
||||
for p in polygons:
|
||||
for p in self.geometries.polygons:
|
||||
if p.ext_ring_cs:
|
||||
# Constructing the polygon and getting the coordinate sequence
|
||||
poly = fromstr(p.wkt)
|
||||
|
@ -506,22 +510,18 @@ class GEOSTest(unittest.TestCase):
|
|||
"Testing relate() and relate_pattern()."
|
||||
g = fromstr('POINT (0 0)')
|
||||
self.assertRaises(GEOSException, g.relate_pattern, 0, 'invalid pattern, yo')
|
||||
for i in xrange(len(relate_geoms)):
|
||||
g_tup = relate_geoms[i]
|
||||
a = fromstr(g_tup[0].wkt)
|
||||
b = fromstr(g_tup[1].wkt)
|
||||
pat = g_tup[2]
|
||||
result = g_tup[3]
|
||||
self.assertEqual(result, a.relate_pattern(b, pat))
|
||||
self.assertEqual(pat, a.relate(b))
|
||||
for rg in self.geometries.relate_geoms:
|
||||
a = fromstr(rg.wkt_a)
|
||||
b = fromstr(rg.wkt_b)
|
||||
self.assertEqual(rg.result, a.relate_pattern(b, rg.pattern))
|
||||
self.assertEqual(rg.pattern, a.relate(b))
|
||||
|
||||
def test10_intersection(self):
|
||||
"Testing intersects() and intersection()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = fromstr(g_tup[0].wkt)
|
||||
b = fromstr(g_tup[1].wkt)
|
||||
i1 = fromstr(intersect_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = fromstr(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = fromstr(self.geometries.topology_geoms[i].wkt_b)
|
||||
i1 = fromstr(self.geometries.intersect_geoms[i].wkt)
|
||||
self.assertEqual(True, a.intersects(b))
|
||||
i2 = a.intersection(b)
|
||||
self.assertEqual(i1, i2)
|
||||
|
@ -531,11 +531,10 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test11_union(self):
|
||||
"Testing union()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = fromstr(g_tup[0].wkt)
|
||||
b = fromstr(g_tup[1].wkt)
|
||||
u1 = fromstr(union_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = fromstr(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = fromstr(self.geometries.topology_geoms[i].wkt_b)
|
||||
u1 = fromstr(self.geometries.union_geoms[i].wkt)
|
||||
u2 = a.union(b)
|
||||
self.assertEqual(u1, u2)
|
||||
self.assertEqual(u1, a | b) # __or__ is union operator
|
||||
|
@ -544,11 +543,10 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test12_difference(self):
|
||||
"Testing difference()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = fromstr(g_tup[0].wkt)
|
||||
b = fromstr(g_tup[1].wkt)
|
||||
d1 = fromstr(diff_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = fromstr(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = fromstr(self.geometries.topology_geoms[i].wkt_b)
|
||||
d1 = fromstr(self.geometries.diff_geoms[i].wkt)
|
||||
d2 = a.difference(b)
|
||||
self.assertEqual(d1, d2)
|
||||
self.assertEqual(d1, a - b) # __sub__ is difference operator
|
||||
|
@ -557,11 +555,10 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test13_symdifference(self):
|
||||
"Testing sym_difference()."
|
||||
for i in xrange(len(topology_geoms)):
|
||||
g_tup = topology_geoms[i]
|
||||
a = fromstr(g_tup[0].wkt)
|
||||
b = fromstr(g_tup[1].wkt)
|
||||
d1 = fromstr(sdiff_geoms[i].wkt)
|
||||
for i in xrange(len(self.geometries.topology_geoms)):
|
||||
a = fromstr(self.geometries.topology_geoms[i].wkt_a)
|
||||
b = fromstr(self.geometries.topology_geoms[i].wkt_b)
|
||||
d1 = fromstr(self.geometries.sdiff_geoms[i].wkt)
|
||||
d2 = a.sym_difference(b)
|
||||
self.assertEqual(d1, d2)
|
||||
self.assertEqual(d1, a ^ b) # __xor__ is symmetric difference operator
|
||||
|
@ -570,18 +567,19 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
def test14_buffer(self):
|
||||
"Testing buffer()."
|
||||
for i in xrange(len(buffer_geoms)):
|
||||
g_tup = buffer_geoms[i]
|
||||
g = fromstr(g_tup[0].wkt)
|
||||
for bg in self.geometries.buffer_geoms:
|
||||
g = fromstr(bg.wkt)
|
||||
|
||||
# The buffer we expect
|
||||
exp_buf = fromstr(g_tup[1].wkt)
|
||||
exp_buf = fromstr(bg.buffer_wkt)
|
||||
quadsegs = bg.quadsegs
|
||||
width = bg.width
|
||||
|
||||
# Can't use a floating-point for the number of quadsegs.
|
||||
self.assertRaises(ctypes.ArgumentError, g.buffer, g_tup[2], float(g_tup[3]))
|
||||
self.assertRaises(ctypes.ArgumentError, g.buffer, width, float(quadsegs))
|
||||
|
||||
# Constructing our buffer
|
||||
buf = g.buffer(g_tup[2], g_tup[3])
|
||||
buf = g.buffer(width, quadsegs)
|
||||
self.assertEqual(exp_buf.num_coords, buf.num_coords)
|
||||
self.assertEqual(len(exp_buf), len(buf))
|
||||
|
||||
|
@ -605,7 +603,7 @@ class GEOSTest(unittest.TestCase):
|
|||
self.assertRaises(ctypes.ArgumentError, pnt.set_srid, '4326')
|
||||
|
||||
# Testing SRID keyword on fromstr(), and on Polygon rings.
|
||||
poly = fromstr(polygons[1].wkt, srid=4269)
|
||||
poly = fromstr(self.geometries.polygons[1].wkt, srid=4269)
|
||||
self.assertEqual(4269, poly.srid)
|
||||
for ring in poly: self.assertEqual(4269, ring.srid)
|
||||
poly.srid = 4326
|
||||
|
@ -636,7 +634,7 @@ class GEOSTest(unittest.TestCase):
|
|||
def test16_mutable_geometries(self):
|
||||
"Testing the mutability of Polygons and Geometry Collections."
|
||||
### Testing the mutability of Polygons ###
|
||||
for p in polygons:
|
||||
for p in self.geometries.polygons:
|
||||
poly = fromstr(p.wkt)
|
||||
|
||||
# Should only be able to use __setitem__ with LinearRing geometries.
|
||||
|
@ -655,7 +653,7 @@ class GEOSTest(unittest.TestCase):
|
|||
self.assertEqual(poly[0], new_shell)
|
||||
|
||||
### Testing the mutability of Geometry Collections
|
||||
for tg in multipoints:
|
||||
for tg in self.geometries.multipoints:
|
||||
mp = fromstr(tg.wkt)
|
||||
for i in range(len(mp)):
|
||||
# Creating a random point.
|
||||
|
@ -670,7 +668,7 @@ class GEOSTest(unittest.TestCase):
|
|||
|
||||
# MultiPolygons involve much more memory management because each
|
||||
# Polygon w/in the collection has its own rings.
|
||||
for tg in multipolygons:
|
||||
for tg in self.geometries.multipolygons:
|
||||
mpoly = fromstr(tg.wkt)
|
||||
for i in xrange(len(mpoly)):
|
||||
poly = mpoly[i]
|
||||
|
@ -791,10 +789,10 @@ class GEOSTest(unittest.TestCase):
|
|||
"Testing GeometryCollection handling of other collections."
|
||||
# Creating a GeometryCollection WKT string composed of other
|
||||
# collections and polygons.
|
||||
coll = [mp.wkt for mp in multipolygons if mp.valid]
|
||||
coll.extend([mls.wkt for mls in multilinestrings])
|
||||
coll.extend([p.wkt for p in polygons])
|
||||
coll.extend([mp.wkt for mp in multipoints])
|
||||
coll = [mp.wkt for mp in self.geometries.multipolygons if mp.valid]
|
||||
coll.extend([mls.wkt for mls in self.geometries.multilinestrings])
|
||||
coll.extend([p.wkt for p in self.geometries.polygons])
|
||||
coll.extend([mp.wkt for mp in self.geometries.multipoints])
|
||||
gc_wkt = 'GEOMETRYCOLLECTION(%s)' % ','.join(coll)
|
||||
|
||||
# Should construct ok from WKT
|
||||
|
@ -862,7 +860,7 @@ class GEOSTest(unittest.TestCase):
|
|||
# Extent of points is just the point itself repeated.
|
||||
self.assertEqual((5.23, 17.8, 5.23, 17.8), pnt.extent)
|
||||
# Testing on the 'real world' Polygon.
|
||||
poly = fromstr(polygons[3].wkt)
|
||||
poly = fromstr(self.geometries.polygons[3].wkt)
|
||||
ring = poly.shell
|
||||
x, y = ring.x, ring.y
|
||||
xmin, ymin = min(x), min(y)
|
||||
|
@ -878,10 +876,10 @@ class GEOSTest(unittest.TestCase):
|
|||
# and setting the SRID on some of them.
|
||||
def get_geoms(lst, srid=None):
|
||||
return [GEOSGeometry(tg.wkt, srid) for tg in lst]
|
||||
tgeoms = get_geoms(points)
|
||||
tgeoms.extend(get_geoms(multilinestrings, 4326))
|
||||
tgeoms.extend(get_geoms(polygons, 3084))
|
||||
tgeoms.extend(get_geoms(multipolygons, 900913))
|
||||
tgeoms = get_geoms(self.geometries.points)
|
||||
tgeoms.extend(get_geoms(self.geometries.multilinestrings, 4326))
|
||||
tgeoms.extend(get_geoms(self.geometries.polygons, 3084))
|
||||
tgeoms.extend(get_geoms(self.geometries.multipolygons, 900913))
|
||||
|
||||
# The SRID won't be exported in GEOS 3.0 release candidates.
|
||||
no_srid = self.null_srid == -1
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue