diff options
| author | Sergey Fedoseev <fedoseev.sergey@gmail.com> | 2017-04-01 18:47:49 +0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-04-01 09:47:49 -0400 |
| commit | bde86ce9ae17ee52aa5be9b74b64422f5219530d (patch) | |
| tree | d9b2429b46be178137e2c46bec273d316714dff2 /tests | |
| parent | e487ffd3f0f9931e7c18bfbd47cf1e6b059ddc41 (diff) | |
Fixed #25605 -- Made GIS DB functions accept geometric expressions, not only values, in all positions.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/gis_tests/distapp/tests.py | 3 | ||||
| -rw-r--r-- | tests/gis_tests/geoapp/test_functions.py | 49 | ||||
| -rw-r--r-- | tests/gis_tests/geogapp/tests.py | 12 | ||||
| -rw-r--r-- | tests/gis_tests/rasterapp/test_rasterfield.py | 6 |
4 files changed, 63 insertions, 7 deletions
diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py index de00bafd70..31987d9ce8 100644 --- a/tests/gis_tests/distapp/tests.py +++ b/tests/gis_tests/distapp/tests.py @@ -429,6 +429,9 @@ class DistanceFunctionsTests(TestCase): self.assertTrue( SouthTexasInterstate.objects.annotate(length=Length('path')).filter(length__gt=4000).exists() ) + # Length with an explicit geometry value. + qs = Interstate.objects.annotate(length=Length(i10.path)) + self.assertAlmostEqual(qs.first().length.m, len_m2, 2) @skipUnlessDBFeature("has_Perimeter_function") def test_perimeter(self): diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index 21b0c283e4..34deb88f4a 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -2,7 +2,9 @@ import re from decimal import Decimal from django.contrib.gis.db.models import functions -from django.contrib.gis.geos import LineString, Point, Polygon, fromstr +from django.contrib.gis.geos import ( + GEOSGeometry, LineString, Point, Polygon, fromstr, +) from django.contrib.gis.measure import Area from django.db import connection from django.db.models import Sum @@ -494,7 +496,48 @@ class GISFunctionsTests(TestCase): @skipUnlessDBFeature("has_Union_function") def test_union(self): + """Union with all combinations of geometries/geometry fields.""" geom = Point(-95.363151, 29.763374, srid=4326) - ptown = City.objects.annotate(union=functions.Union('point', geom)).get(name='Dallas') + + union = City.objects.annotate(union=functions.Union('point', geom)).get(name='Dallas').union expected = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)', srid=4326) - self.assertTrue(expected.equals(ptown.union)) + self.assertTrue(expected.equals(union)) + + union = City.objects.annotate(union=functions.Union(geom, 'point')).get(name='Dallas').union + self.assertTrue(expected.equals(union)) + + union = City.objects.annotate(union=functions.Union('point', 'point')).get(name='Dallas').union + expected = GEOSGeometry('POINT(-96.801611 32.782057)', srid=4326) + self.assertTrue(expected.equals(union)) + + union = City.objects.annotate(union=functions.Union(geom, geom)).get(name='Dallas').union + self.assertTrue(geom.equals(union)) + + @skipUnlessDBFeature("has_Union_function", "has_Transform_function") + def test_union_mixed_srid(self): + """The result SRID depends on the order of parameters.""" + geom = Point(61.42915, 55.15402, srid=4326) + geom_3857 = geom.transform(3857, clone=True) + tol = 0.001 + + for city in City.objects.annotate(union=functions.Union('point', geom_3857)): + expected = city.point | geom + self.assertTrue(city.union.equals_exact(expected, tol)) + self.assertEqual(city.union.srid, 4326) + + for city in City.objects.annotate(union=functions.Union(geom_3857, 'point')): + expected = geom_3857 | city.point.transform(3857, clone=True) + self.assertTrue(expected.equals_exact(city.union, tol)) + self.assertEqual(city.union.srid, 3857) + + def test_argument_validation(self): + with self.assertRaisesMessage(ValueError, 'SRID is required for all geometries.'): + City.objects.annotate(geo=functions.GeoFunc(Point(1, 1))) + + msg = 'GeoFunc function requires a GeometryField in position 1, got CharField.' + with self.assertRaisesMessage(TypeError, msg): + City.objects.annotate(geo=functions.GeoFunc('name')) + + msg = 'GeoFunc function requires a geometric argument in position 1.' + with self.assertRaisesMessage(TypeError, msg): + City.objects.annotate(union=functions.GeoFunc(1, 'point')).get(name='Dallas') diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py index 551fda4b83..3450847504 100644 --- a/tests/gis_tests/geogapp/tests.py +++ b/tests/gis_tests/geogapp/tests.py @@ -120,9 +120,19 @@ class GeographyFunctionTests(TestCase): else: ref_dists = [0, 4891.20, 8071.64, 9123.95] htown = City.objects.get(name='Houston') - qs = Zipcode.objects.annotate(distance=Distance('poly', htown.point)) + qs = Zipcode.objects.annotate( + distance=Distance('poly', htown.point), + distance2=Distance(htown.point, 'poly'), + ) for z, ref in zip(qs, ref_dists): self.assertAlmostEqual(z.distance.m, ref, 2) + + if postgis: + # PostGIS casts geography to geometry when distance2 is calculated. + ref_dists = [0, 4899.68, 8081.30, 9115.15] + for z, ref in zip(qs, ref_dists): + self.assertAlmostEqual(z.distance2.m, ref, 2) + if not spatialite: # Distance function combined with a lookup. hzip = Zipcode.objects.get(code='77002') diff --git a/tests/gis_tests/rasterapp/test_rasterfield.py b/tests/gis_tests/rasterapp/test_rasterfield.py index 1e4ffbfbd7..68df5dc0aa 100644 --- a/tests/gis_tests/rasterapp/test_rasterfield.py +++ b/tests/gis_tests/rasterapp/test_rasterfield.py @@ -271,7 +271,7 @@ class RasterFieldTest(TransactionTestCase): def test_isvalid_lookup_with_raster_error(self): qs = RasterModel.objects.filter(rast__isvalid=True) - msg = 'Geometry functions not supported for raster fields.' + msg = 'IsValid function requires a GeometryField in position 1, got RasterField.' with self.assertRaisesMessage(TypeError, msg): qs.count() @@ -336,11 +336,11 @@ class RasterFieldTest(TransactionTestCase): """ point = GEOSGeometry("SRID=3086;POINT (-697024.9213808845 683729.1705516104)") rast = GDALRaster(json.loads(JSON_RASTER)) - msg = "Please provide a geometry object." + msg = "Distance function requires a geometric argument in position 2." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate(distance_from_point=Distance("geom", rast)) with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate(distance_from_point=Distance("rastprojected", rast)) - msg = "Geometry functions not supported for raster fields." + msg = "Distance function requires a GeometryField in position 1, got RasterField." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate(distance_from_point=Distance("rastprojected", point)).count() |
