Skip to content

Commit

Permalink
Made geo3d tests independent from each other
Browse files Browse the repository at this point in the history
  • Loading branch information
claudep committed Sep 22, 2012
1 parent 69ff1b7 commit 59afc18
Showing 1 changed file with 85 additions and 49 deletions.
134 changes: 85 additions & 49 deletions django/contrib/gis/tests/geo3d/tests.py
Original file line number Original file line Diff line number Diff line change
@@ -1,16 +1,17 @@
from __future__ import absolute_import from __future__ import absolute_import, unicode_literals


import os import os
import re import re


from django.utils.unittest import TestCase
from django.contrib.gis.db.models import Union, Extent3D from django.contrib.gis.db.models import Union, Extent3D
from django.contrib.gis.geos import GEOSGeometry, Point, Polygon from django.contrib.gis.geos import GEOSGeometry, Point, Polygon
from django.contrib.gis.utils import LayerMapping, LayerMapError from django.contrib.gis.utils import LayerMapping, LayerMapError
from django.test import TestCase


from .models import (City3D, Interstate2D, Interstate3D, InterstateProj2D, from .models import (City3D, Interstate2D, Interstate3D, InterstateProj2D,
InterstateProj3D, Point2D, Point3D, MultiPoint3D, Polygon2D, Polygon3D) InterstateProj3D, Point2D, Point3D, MultiPoint3D, Polygon2D, Polygon3D)



data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data'))
city_file = os.path.join(data_path, 'cities', 'cities.shp') city_file = os.path.join(data_path, 'cities', 'cities.shp')
vrt_file = os.path.join(data_path, 'test_vrt', 'test_vrt.vrt') vrt_file = os.path.join(data_path, 'test_vrt', 'test_vrt.vrt')
Expand Down Expand Up @@ -46,12 +47,11 @@
# Bounding box polygon for inner-loop of Houston (in projected coordinate # Bounding box polygon for inner-loop of Houston (in projected coordinate
# system 32140), with elevation values from the National Elevation Dataset # system 32140), with elevation values from the National Elevation Dataset
# (see above). # (see above).
bbox_wkt = 'POLYGON((941527.97 4225693.20,962596.48 4226349.75,963152.57 4209023.95,942051.75 4208366.38,941527.97 4225693.20))' bbox_data = (
bbox_z = (21.71, 13.21, 9.12, 16.40, 21.71) 'POLYGON((941527.97 4225693.20,962596.48 4226349.75,963152.57 4209023.95,942051.75 4208366.38,941527.97 4225693.20))',
def gen_bbox(): (21.71, 13.21, 9.12, 16.40, 21.71)
bbox_2d = GEOSGeometry(bbox_wkt, srid=32140) )
bbox_3d = Polygon(tuple((x, y, z) for (x, y), z in zip(bbox_2d[0].coords, bbox_z)), srid=32140)
return bbox_2d, bbox_3d


class Geo3DTest(TestCase): class Geo3DTest(TestCase):
""" """
Expand All @@ -63,20 +63,7 @@ class Geo3DTest(TestCase):
http://postgis.refractions.net/documentation/manual-1.4/ch08.html#PostGIS_3D_Functions http://postgis.refractions.net/documentation/manual-1.4/ch08.html#PostGIS_3D_Functions
""" """


def test01_3d(self): def _load_interstate_data(self):
"Test the creation of 3D models."
# 3D models for the rest of the tests will be populated in here.
# For each 3D data set create model (and 2D version if necessary),
# retrieve, and assert geometry is in 3D and contains the expected
# 3D values.
for name, pnt_data in city_data:
x, y, z = pnt_data
pnt = Point(x, y, z, srid=4326)
City3D.objects.create(name=name, point=pnt)
city = City3D.objects.get(name=name)
self.assertTrue(city.point.hasz)
self.assertEqual(z, city.point.z)

# Interstate (2D / 3D and Geographic/Projected variants) # Interstate (2D / 3D and Geographic/Projected variants)
for name, line, exp_z in interstate_data: for name, line, exp_z in interstate_data:
line_3d = GEOSGeometry(line, srid=4269) line_3d = GEOSGeometry(line, srid=4269)
Expand All @@ -90,26 +77,51 @@ def test01_3d(self):
Interstate2D.objects.create(name=name, line=line_2d) Interstate2D.objects.create(name=name, line=line_2d)
InterstateProj2D.objects.create(name=name, line=line_2d) InterstateProj2D.objects.create(name=name, line=line_2d)


# Retrieving and making sure it's 3D and has expected def _load_city_data(self):
# Z values -- shouldn't change because of coordinate system. for name, pnt_data in city_data:
City3D.objects.create(name=name, point=Point(*pnt_data, srid=4326))

def _load_polygon_data(self):
bbox_wkt, bbox_z = bbox_data
bbox_2d = GEOSGeometry(bbox_wkt, srid=32140)
bbox_3d = Polygon(tuple((x, y, z) for (x, y), z in zip(bbox_2d[0].coords, bbox_z)), srid=32140)
Polygon2D.objects.create(name='2D BBox', poly=bbox_2d)
Polygon3D.objects.create(name='3D BBox', poly=bbox_3d)

def test_3d_hasz(self):
"""
Make sure data is 3D and has expected Z values -- shouldn't change
because of coordinate system.
"""
self._load_interstate_data()
for name, line, exp_z in interstate_data:
interstate = Interstate3D.objects.get(name=name) interstate = Interstate3D.objects.get(name=name)
interstate_proj = InterstateProj3D.objects.get(name=name) interstate_proj = InterstateProj3D.objects.get(name=name)
for i in [interstate, interstate_proj]: for i in [interstate, interstate_proj]:
self.assertTrue(i.line.hasz) self.assertTrue(i.line.hasz)
self.assertEqual(exp_z, tuple(i.line.z)) self.assertEqual(exp_z, tuple(i.line.z))


# Creating 3D Polygon. self._load_city_data()
bbox2d, bbox3d = gen_bbox() for name, pnt_data in city_data:
Polygon2D.objects.create(name='2D BBox', poly=bbox2d) city = City3D.objects.get(name=name)
Polygon3D.objects.create(name='3D BBox', poly=bbox3d) z = pnt_data[2]
self.assertTrue(city.point.hasz)
self.assertEqual(z, city.point.z)

def test_3d_polygons(self):
"""
Test the creation of polygon 3D models.
"""
self._load_polygon_data()
p3d = Polygon3D.objects.get(name='3D BBox') p3d = Polygon3D.objects.get(name='3D BBox')
self.assertTrue(p3d.poly.hasz) self.assertTrue(p3d.poly.hasz)
self.assertEqual(bbox3d, p3d.poly) self.assertIsInstance(p3d.poly, Polygon)

self.assertEqual(p3d.poly.srid, 32140)
def test01a_3d_layermapping(self):
"Testing LayerMapping on 3D models."
from .models import Point2D, Point3D


def test_3d_layermapping(self):
"""
Testing LayerMapping on 3D models.
"""
point_mapping = {'point' : 'POINT'} point_mapping = {'point' : 'POINT'}
mpoint_mapping = {'mpoint' : 'MULTIPOINT'} mpoint_mapping = {'mpoint' : 'MULTIPOINT'}


Expand All @@ -134,34 +146,46 @@ def test01a_3d_layermapping(self):
lm.save() lm.save()
self.assertEqual(3, MultiPoint3D.objects.count()) self.assertEqual(3, MultiPoint3D.objects.count())


def test02a_kml(self): def test_kml(self):
"Test GeoQuerySet.kml() with Z values." """
Test GeoQuerySet.kml() with Z values.
"""
self._load_city_data()
h = City3D.objects.kml(precision=6).get(name='Houston') h = City3D.objects.kml(precision=6).get(name='Houston')
# KML should be 3D. # KML should be 3D.
# `SELECT ST_AsKML(point, 6) FROM geo3d_city3d WHERE name = 'Houston';` # `SELECT ST_AsKML(point, 6) FROM geo3d_city3d WHERE name = 'Houston';`
ref_kml_regex = re.compile(r'^<Point><coordinates>-95.363\d+,29.763\d+,18</coordinates></Point>$') ref_kml_regex = re.compile(r'^<Point><coordinates>-95.363\d+,29.763\d+,18</coordinates></Point>$')
self.assertTrue(ref_kml_regex.match(h.kml)) self.assertTrue(ref_kml_regex.match(h.kml))


def test02b_geojson(self): def test_geojson(self):
"Test GeoQuerySet.geojson() with Z values." """
Test GeoQuerySet.geojson() with Z values.
"""
self._load_city_data()
h = City3D.objects.geojson(precision=6).get(name='Houston') h = City3D.objects.geojson(precision=6).get(name='Houston')
# GeoJSON should be 3D # GeoJSON should be 3D
# `SELECT ST_AsGeoJSON(point, 6) FROM geo3d_city3d WHERE name='Houston';` # `SELECT ST_AsGeoJSON(point, 6) FROM geo3d_city3d WHERE name='Houston';`
ref_json_regex = re.compile(r'^{"type":"Point","coordinates":\[-95.363151,29.763374,18(\.0+)?\]}$') ref_json_regex = re.compile(r'^{"type":"Point","coordinates":\[-95.363151,29.763374,18(\.0+)?\]}$')
self.assertTrue(ref_json_regex.match(h.geojson)) self.assertTrue(ref_json_regex.match(h.geojson))


def test03a_union(self): def test_union(self):
"Testing the Union aggregate of 3D models." """
Testing the Union aggregate of 3D models.
"""
# PostGIS query that returned the reference EWKT for this test: # PostGIS query that returned the reference EWKT for this test:
# `SELECT ST_AsText(ST_Union(point)) FROM geo3d_city3d;` # `SELECT ST_AsText(ST_Union(point)) FROM geo3d_city3d;`
self._load_city_data()
ref_ewkt = 'SRID=4326;MULTIPOINT(-123.305196 48.462611 15,-104.609252 38.255001 1433,-97.521157 34.464642 380,-96.801611 32.782057 147,-95.363151 29.763374 18,-95.23506 38.971823 251,-87.650175 41.850385 181,174.783117 -41.315268 14)' ref_ewkt = 'SRID=4326;MULTIPOINT(-123.305196 48.462611 15,-104.609252 38.255001 1433,-97.521157 34.464642 380,-96.801611 32.782057 147,-95.363151 29.763374 18,-95.23506 38.971823 251,-87.650175 41.850385 181,174.783117 -41.315268 14)'
ref_union = GEOSGeometry(ref_ewkt) ref_union = GEOSGeometry(ref_ewkt)
union = City3D.objects.aggregate(Union('point'))['point__union'] union = City3D.objects.aggregate(Union('point'))['point__union']
self.assertTrue(union.hasz) self.assertTrue(union.hasz)
self.assertEqual(ref_union, union) self.assertEqual(ref_union, union)


def test03b_extent(self): def test_extent(self):
"Testing the Extent3D aggregate for 3D models." """
Testing the Extent3D aggregate for 3D models.
"""
self._load_city_data()
# `SELECT ST_Extent3D(point) FROM geo3d_city3d;` # `SELECT ST_Extent3D(point) FROM geo3d_city3d;`
ref_extent3d = (-123.305196, -41.315268, 14,174.783117, 48.462611, 1433) ref_extent3d = (-123.305196, -41.315268, 14,174.783117, 48.462611, 1433)
extent1 = City3D.objects.aggregate(Extent3D('point'))['point__extent3d'] extent1 = City3D.objects.aggregate(Extent3D('point'))['point__extent3d']
Expand All @@ -174,8 +198,11 @@ def check_extent3d(extent3d, tol=6):
for e3d in [extent1, extent2]: for e3d in [extent1, extent2]:
check_extent3d(e3d) check_extent3d(e3d)


def test04_perimeter(self): def test_perimeter(self):
"Testing GeoQuerySet.perimeter() on 3D fields." """
Testing GeoQuerySet.perimeter() on 3D fields.
"""
self._load_polygon_data()
# Reference query for values below: # Reference query for values below:
# `SELECT ST_Perimeter3D(poly), ST_Perimeter2D(poly) FROM geo3d_polygon3d;` # `SELECT ST_Perimeter3D(poly), ST_Perimeter2D(poly) FROM geo3d_polygon3d;`
ref_perim_3d = 76859.2620451 ref_perim_3d = 76859.2620451
Expand All @@ -188,12 +215,15 @@ def test04_perimeter(self):
Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m, Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m,
tol) tol)


def test05_length(self): def test_length(self):
"Testing GeoQuerySet.length() on 3D fields." """
Testing GeoQuerySet.length() on 3D fields.
"""
# ST_Length_Spheroid Z-aware, and thus does not need to use # ST_Length_Spheroid Z-aware, and thus does not need to use
# a separate function internally. # a separate function internally.
# `SELECT ST_Length_Spheroid(line, 'SPHEROID["GRS 1980",6378137,298.257222101]') # `SELECT ST_Length_Spheroid(line, 'SPHEROID["GRS 1980",6378137,298.257222101]')
# FROM geo3d_interstate[2d|3d];` # FROM geo3d_interstate[2d|3d];`
self._load_interstate_data()
tol = 3 tol = 3
ref_length_2d = 4368.1721949481 ref_length_2d = 4368.1721949481
ref_length_3d = 4368.62547052088 ref_length_3d = 4368.62547052088
Expand All @@ -217,16 +247,22 @@ def test05_length(self):
InterstateProj3D.objects.length().get(name='I-45').length.m, InterstateProj3D.objects.length().get(name='I-45').length.m,
tol) tol)


def test06_scale(self): def test_scale(self):
"Testing GeoQuerySet.scale() on Z values." """
Testing GeoQuerySet.scale() on Z values.
"""
self._load_city_data()
# Mapping of City name to reference Z values. # Mapping of City name to reference Z values.
zscales = (-3, 4, 23) zscales = (-3, 4, 23)
for zscale in zscales: for zscale in zscales:
for city in City3D.objects.scale(1.0, 1.0, zscale): for city in City3D.objects.scale(1.0, 1.0, zscale):
self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z) self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z)


def test07_translate(self): def test_translate(self):
"Testing GeoQuerySet.translate() on Z values." """
Testing GeoQuerySet.translate() on Z values.
"""
self._load_city_data()
ztranslations = (5.23, 23, -17) ztranslations = (5.23, 23, -17)
for ztrans in ztranslations: for ztrans in ztranslations:
for city in City3D.objects.translate(0, 0, ztrans): for city in City3D.objects.translate(0, 0, ztrans):
Expand Down

0 comments on commit 59afc18

Please sign in to comment.