|
29
|
1 |
""" |
|
|
2 |
Tests for geography support in PostGIS 1.5+ |
|
|
3 |
""" |
|
|
4 |
import os |
|
|
5 |
from django.contrib.gis import gdal |
|
|
6 |
from django.contrib.gis.measure import D |
|
|
7 |
from django.test import TestCase |
|
|
8 |
from models import City, County, Zipcode |
|
|
9 |
|
|
|
10 |
class GeographyTest(TestCase): |
|
|
11 |
|
|
|
12 |
def test01_fixture_load(self): |
|
|
13 |
"Ensure geography features loaded properly." |
|
|
14 |
self.assertEqual(8, City.objects.count()) |
|
|
15 |
|
|
|
16 |
def test02_distance_lookup(self): |
|
|
17 |
"Testing GeoQuerySet distance lookup support on non-point geography fields." |
|
|
18 |
z = Zipcode.objects.get(code='77002') |
|
|
19 |
cities1 = list(City.objects |
|
|
20 |
.filter(point__distance_lte=(z.poly, D(mi=500))) |
|
|
21 |
.order_by('name') |
|
|
22 |
.values_list('name', flat=True)) |
|
|
23 |
cities2 = list(City.objects |
|
|
24 |
.filter(point__dwithin=(z.poly, D(mi=500))) |
|
|
25 |
.order_by('name') |
|
|
26 |
.values_list('name', flat=True)) |
|
|
27 |
for cities in [cities1, cities2]: |
|
|
28 |
self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities) |
|
|
29 |
|
|
|
30 |
def test03_distance_method(self): |
|
|
31 |
"Testing GeoQuerySet.distance() support on non-point geography fields." |
|
|
32 |
# `GeoQuerySet.distance` is not allowed geometry fields. |
|
|
33 |
htown = City.objects.get(name='Houston') |
|
|
34 |
qs = Zipcode.objects.distance(htown.point) |
|
|
35 |
|
|
|
36 |
def test04_invalid_operators_functions(self): |
|
|
37 |
"Ensuring exceptions are raised for operators & functions invalid on geography fields." |
|
|
38 |
# Only a subset of the geometry functions & operator are available |
|
|
39 |
# to PostGIS geography types. For more information, visit: |
|
|
40 |
# http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_GeographyFunctions |
|
|
41 |
z = Zipcode.objects.get(code='77002') |
|
|
42 |
# ST_Within not available. |
|
|
43 |
self.assertRaises(ValueError, City.objects.filter(point__within=z.poly).count) |
|
|
44 |
# `@` operator not available. |
|
|
45 |
self.assertRaises(ValueError, City.objects.filter(point__contained=z.poly).count) |
|
|
46 |
|
|
|
47 |
def test05_geography_layermapping(self): |
|
|
48 |
"Testing LayerMapping support on models with geography fields." |
|
|
49 |
# There is a similar test in `layermap` that uses the same data set, |
|
|
50 |
# but the County model here is a bit different. |
|
|
51 |
if not gdal.HAS_GDAL: return |
|
|
52 |
from django.contrib.gis.utils import LayerMapping |
|
|
53 |
|
|
|
54 |
# Getting the shapefile and mapping dictionary. |
|
|
55 |
shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) |
|
|
56 |
co_shp = os.path.join(shp_path, 'counties', 'counties.shp') |
|
|
57 |
co_mapping = {'name' : 'Name', |
|
|
58 |
'state' : 'State', |
|
|
59 |
'mpoly' : 'MULTIPOLYGON', |
|
|
60 |
} |
|
|
61 |
|
|
|
62 |
# Reference county names, number of polygons, and state names. |
|
|
63 |
names = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo'] |
|
|
64 |
num_polys = [1, 2, 1, 19, 1] # Number of polygons for each. |
|
|
65 |
st_names = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado'] |
|
|
66 |
|
|
|
67 |
lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269, unique='name') |
|
|
68 |
lm.save(silent=True, strict=True) |
|
|
69 |
|
|
|
70 |
for c, name, num_poly, state in zip(County.objects.order_by('name'), names, num_polys, st_names): |
|
|
71 |
self.assertEqual(4326, c.mpoly.srid) |
|
|
72 |
self.assertEqual(num_poly, len(c.mpoly)) |
|
|
73 |
self.assertEqual(name, c.name) |
|
|
74 |
self.assertEqual(state, c.state) |