mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Removed GeoManager and GeoQuerySet per deprecation timeline.
This commit is contained in:
parent
e90c745afd
commit
a0d166306f
25 changed files with 32 additions and 2194 deletions
|
@ -8,8 +8,6 @@ from ..utils import gisfield_may_be_null
|
|||
class NamedModel(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
objects = models.GeoManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
required_db_features = ['gis_enabled']
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from unittest import skipIf
|
||||
|
||||
from django.contrib.gis.db.models.functions import (
|
||||
Area, Distance, Length, Perimeter, Transform,
|
||||
)
|
||||
|
@ -9,8 +7,7 @@ from django.contrib.gis.geos import GEOSGeometry, LineString, Point
|
|||
from django.contrib.gis.measure import D # alias for Distance
|
||||
from django.db import connection
|
||||
from django.db.models import F, Q
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
|
||||
from ..utils import no_oracle, oracle, postgis, spatialite
|
||||
from .models import (
|
||||
|
@ -101,136 +98,6 @@ class DistanceTest(TestCase):
|
|||
else:
|
||||
self.assertListEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))))
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_distance_projected(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method on projected coordinate systems.
|
||||
"""
|
||||
# The point for La Grange, TX
|
||||
lagrange = GEOSGeometry('POINT(-96.876369 29.905320)', 4326)
|
||||
# Reference distances in feet and in meters. Got these values from
|
||||
# using the provided raw SQL statements.
|
||||
# SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 32140))
|
||||
# FROM distapp_southtexascity;
|
||||
m_distances = [147075.069813, 139630.198056, 140888.552826,
|
||||
138809.684197, 158309.246259, 212183.594374,
|
||||
70870.188967, 165337.758878, 139196.085105]
|
||||
# SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 2278))
|
||||
# FROM distapp_southtexascityft;
|
||||
# Oracle 11 thinks this is not a projected coordinate system, so it's
|
||||
# not tested.
|
||||
ft_distances = [482528.79154625, 458103.408123001, 462231.860397575,
|
||||
455411.438904354, 519386.252102563, 696139.009211594,
|
||||
232513.278304279, 542445.630586414, 456679.155883207]
|
||||
|
||||
# Testing using different variations of parameters and using models
|
||||
# with different projected coordinate systems.
|
||||
dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point').order_by('id')
|
||||
dist2 = SouthTexasCity.objects.distance(lagrange).order_by('id') # Using GEOSGeometry parameter
|
||||
if oracle:
|
||||
dist_qs = [dist1, dist2]
|
||||
else:
|
||||
dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt).order_by('id') # Using EWKT string parameter.
|
||||
dist4 = SouthTexasCityFt.objects.distance(lagrange).order_by('id')
|
||||
dist_qs = [dist1, dist2, dist3, dist4]
|
||||
|
||||
# Original query done on PostGIS, have to adjust AlmostEqual tolerance
|
||||
# for Oracle.
|
||||
tol = 2 if oracle else 5
|
||||
|
||||
# Ensuring expected distances are returned for each distance queryset.
|
||||
for qs in dist_qs:
|
||||
for i, c in enumerate(qs):
|
||||
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
|
||||
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
|
||||
|
||||
@skipIf(spatialite, "distance method doesn't support geodetic coordinates on SpatiaLite.")
|
||||
@skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_distance_geodetic(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method on geodetic coordinate systems.
|
||||
"""
|
||||
tol = 2 if oracle else 4
|
||||
|
||||
# Testing geodetic distance calculation with a non-point geometry
|
||||
# (a LineString of Wollongong and Shellharbour coords).
|
||||
ls = LineString(((150.902, -34.4245), (150.87, -34.5789)))
|
||||
|
||||
# Reference query:
|
||||
# SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326))
|
||||
# FROM distapp_australiacity ORDER BY name;
|
||||
distances = [1120954.92533513, 140575.720018241, 640396.662906304,
|
||||
60580.9693849269, 972807.955955075, 568451.8357838,
|
||||
40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
|
||||
qs = AustraliaCity.objects.distance(ls).order_by('name')
|
||||
for city, distance in zip(qs, distances):
|
||||
# Testing equivalence to within a meter.
|
||||
self.assertAlmostEqual(distance, city.distance.m, 0)
|
||||
|
||||
# Got the reference distances using the raw SQL statements:
|
||||
# SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326),
|
||||
# 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11));
|
||||
# SELECT ST_distance_sphere(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326))
|
||||
# FROM distapp_australiacity WHERE (NOT (id = 11)); st_distance_sphere
|
||||
spheroid_distances = [
|
||||
60504.0628957201, 77023.9489850262, 49154.8867574404,
|
||||
90847.4358768573, 217402.811919332, 709599.234564757,
|
||||
640011.483550888, 7772.00667991925, 1047861.78619339,
|
||||
1165126.55236034,
|
||||
]
|
||||
sphere_distances = [
|
||||
60580.9693849267, 77144.0435286473, 49199.4415344719,
|
||||
90804.7533823494, 217713.384600405, 709134.127242793,
|
||||
639828.157159169, 7786.82949717788, 1049204.06569028,
|
||||
1162623.7238134,
|
||||
]
|
||||
# Testing with spheroid distances first.
|
||||
hillsdale = AustraliaCity.objects.get(name='Hillsdale')
|
||||
qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point, spheroid=True).order_by('id')
|
||||
for i, c in enumerate(qs):
|
||||
self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol)
|
||||
if postgis:
|
||||
# PostGIS uses sphere-only distances by default, testing these as well.
|
||||
qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point).order_by('id')
|
||||
for i, c in enumerate(qs):
|
||||
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
|
||||
|
||||
@no_oracle # Oracle already handles geographic distance calculation.
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_distance_transform(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
|
||||
"""
|
||||
# We'll be using a Polygon (created by buffering the centroid
|
||||
# of 77005 to 100m) -- which aren't allowed in geographic distance
|
||||
# queries normally, however our field has been transformed to
|
||||
# a non-geographic system.
|
||||
z = SouthTexasZipcode.objects.get(name='77005')
|
||||
|
||||
# Reference query:
|
||||
# SELECT ST_Distance(ST_Transform("distapp_censuszipcode"."poly", 32140),
|
||||
# ST_GeomFromText('<buffer_wkt>', 32140))
|
||||
# FROM "distapp_censuszipcode";
|
||||
dists_m = [3553.30384972258, 1243.18391525602, 2186.15439472242]
|
||||
|
||||
# Having our buffer in the SRID of the transformation and of the field
|
||||
# -- should get the same results. The first buffer has no need for
|
||||
# transformation SQL because it is the same SRID as what was given
|
||||
# to `transform()`. The second buffer will need to be transformed,
|
||||
# however.
|
||||
buf1 = z.poly.centroid.buffer(100)
|
||||
buf2 = buf1.transform(4269, clone=True)
|
||||
ref_zips = ['77002', '77025', '77401']
|
||||
|
||||
for buf in [buf1, buf2]:
|
||||
qs = CensusZipcode.objects.exclude(name='77005').transform(32140).distance(buf).order_by('name')
|
||||
self.assertListEqual(ref_zips, self.get_names(qs))
|
||||
for i, z in enumerate(qs):
|
||||
self.assertAlmostEqual(z.distance.m, dists_m[i], 5)
|
||||
|
||||
@skipUnlessDBFeature("supports_distances_lookups")
|
||||
def test_distance_lookups(self):
|
||||
"""
|
||||
|
@ -347,86 +214,6 @@ class DistanceTest(TestCase):
|
|||
).order_by('name')
|
||||
self.assertEqual(self.get_names(qs), ['Canberra', 'Hobart', 'Melbourne'])
|
||||
|
||||
@skipUnlessDBFeature("has_area_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_area(self):
|
||||
"""
|
||||
Test the `area` GeoQuerySet method.
|
||||
"""
|
||||
# Reference queries:
|
||||
# SELECT ST_Area(poly) FROM distapp_southtexaszipcode;
|
||||
area_sq_m = [5437908.90234375, 10183031.4389648, 11254471.0073242, 9881708.91772461]
|
||||
# Tolerance has to be lower for Oracle
|
||||
tol = 2
|
||||
for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').area()):
|
||||
self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
|
||||
|
||||
@skipIf(spatialite, "length method doesn't support geodetic coordinates on SpatiaLite.")
|
||||
@skipUnlessDBFeature("has_length_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_length(self):
|
||||
"""
|
||||
Test the `length` GeoQuerySet method.
|
||||
"""
|
||||
# Reference query (should use `length_spheroid`).
|
||||
# SELECT ST_length_spheroid(ST_GeomFromText('<wkt>', 4326) 'SPHEROID["WGS 84",6378137,298.257223563,
|
||||
# AUTHORITY["EPSG","7030"]]');
|
||||
len_m1 = 473504.769553813
|
||||
len_m2 = 4617.668
|
||||
|
||||
if connection.features.supports_distance_geodetic:
|
||||
qs = Interstate.objects.length()
|
||||
tol = 2 if oracle else 3
|
||||
self.assertAlmostEqual(len_m1, qs[0].length.m, tol)
|
||||
else:
|
||||
# Does not support geodetic coordinate systems.
|
||||
with self.assertRaises(ValueError):
|
||||
Interstate.objects.length()
|
||||
|
||||
# Now doing length on a projected coordinate system.
|
||||
i10 = SouthTexasInterstate.objects.length().get(name='I-10')
|
||||
self.assertAlmostEqual(len_m2, i10.length.m, 2)
|
||||
|
||||
@skipUnlessDBFeature("has_perimeter_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_perimeter(self):
|
||||
"""
|
||||
Test the `perimeter` GeoQuerySet method.
|
||||
"""
|
||||
# Reference query:
|
||||
# SELECT ST_Perimeter(distapp_southtexaszipcode.poly) FROM distapp_southtexaszipcode;
|
||||
perim_m = [18404.3550889361, 15627.2108551001, 20632.5588368978, 17094.5996143697]
|
||||
tol = 2 if oracle else 7
|
||||
for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').perimeter()):
|
||||
self.assertAlmostEqual(perim_m[i], z.perimeter.m, tol)
|
||||
|
||||
# Running on points; should return 0.
|
||||
for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')):
|
||||
self.assertEqual(0, c.perim.m)
|
||||
|
||||
@skipUnlessDBFeature("has_area_method", "has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_measurement_null_fields(self):
|
||||
"""
|
||||
Test the measurement GeoQuerySet methods on fields with NULL values.
|
||||
"""
|
||||
# Creating SouthTexasZipcode w/NULL value.
|
||||
SouthTexasZipcode.objects.create(name='78212')
|
||||
# Performing distance/area queries against the NULL PolygonField,
|
||||
# and ensuring the result of the operations is None.
|
||||
htown = SouthTexasCity.objects.get(name='Downtown Houston')
|
||||
z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212')
|
||||
self.assertIsNone(z.distance)
|
||||
self.assertIsNone(z.area)
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_distance_order_by(self):
|
||||
qs = SouthTexasCity.objects.distance(Point(3, 3)).order_by(
|
||||
'distance'
|
||||
).values_list('name', flat=True).filter(name__in=('San Antonio', 'Pearland'))
|
||||
self.assertSequenceEqual(qs, ['San Antonio', 'Pearland'])
|
||||
|
||||
|
||||
'''
|
||||
=============================
|
||||
|
|
|
@ -6,8 +6,6 @@ from django.utils.encoding import python_2_unicode_compatible
|
|||
class NamedModel(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
objects = models.GeoManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
required_db_features = ['gis_enabled']
|
||||
|
|
|
@ -8,9 +8,8 @@ from django.contrib.gis.db.models.functions import (
|
|||
AsGeoJSON, AsKML, Length, Perimeter, Scale, Translate,
|
||||
)
|
||||
from django.contrib.gis.geos import GEOSGeometry, LineString, Point, Polygon
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
|
||||
from .models import (
|
||||
City3D, Interstate2D, Interstate3D, InterstateProj2D, InterstateProj3D,
|
||||
|
@ -171,30 +170,6 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
lm.save()
|
||||
self.assertEqual(3, MultiPoint3D.objects.count())
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_kml(self):
|
||||
"""
|
||||
Test GeoQuerySet.kml() with Z values.
|
||||
"""
|
||||
self._load_city_data()
|
||||
h = City3D.objects.kml(precision=6).get(name='Houston')
|
||||
# KML should be 3D.
|
||||
# `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>$')
|
||||
self.assertTrue(ref_kml_regex.match(h.kml))
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test_geojson(self):
|
||||
"""
|
||||
Test GeoQuerySet.geojson() with Z values.
|
||||
"""
|
||||
self._load_city_data()
|
||||
h = City3D.objects.geojson(precision=6).get(name='Houston')
|
||||
# GeoJSON should be 3D
|
||||
# `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+)?\]}$')
|
||||
self.assertTrue(ref_json_regex.match(h.geojson))
|
||||
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_union(self):
|
||||
"""
|
||||
|
@ -231,84 +206,6 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
check_extent3d(extent)
|
||||
self.assertIsNone(City3D.objects.none().aggregate(Extent3D('point'))['point__extent3d'])
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_perimeter(self):
|
||||
"""
|
||||
Testing GeoQuerySet.perimeter() on 3D fields.
|
||||
"""
|
||||
self._load_polygon_data()
|
||||
# Reference query for values below:
|
||||
# `SELECT ST_Perimeter3D(poly), ST_Perimeter2D(poly) FROM geo3d_polygon3d;`
|
||||
ref_perim_3d = 76859.2620451
|
||||
ref_perim_2d = 76859.2577803
|
||||
tol = 6
|
||||
self.assertAlmostEqual(ref_perim_2d,
|
||||
Polygon2D.objects.perimeter().get(name='2D BBox').perimeter.m,
|
||||
tol)
|
||||
self.assertAlmostEqual(ref_perim_3d,
|
||||
Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m,
|
||||
tol)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_length(self):
|
||||
"""
|
||||
Testing GeoQuerySet.length() on 3D fields.
|
||||
"""
|
||||
# ST_Length_Spheroid Z-aware, and thus does not need to use
|
||||
# a separate function internally.
|
||||
# `SELECT ST_Length_Spheroid(line, 'SPHEROID["GRS 1980",6378137,298.257222101]')
|
||||
# FROM geo3d_interstate[2d|3d];`
|
||||
self._load_interstate_data()
|
||||
tol = 3
|
||||
ref_length_2d = 4368.1721949481
|
||||
ref_length_3d = 4368.62547052088
|
||||
self.assertAlmostEqual(ref_length_2d,
|
||||
Interstate2D.objects.length().get(name='I-45').length.m,
|
||||
tol)
|
||||
self.assertAlmostEqual(ref_length_3d,
|
||||
Interstate3D.objects.length().get(name='I-45').length.m,
|
||||
tol)
|
||||
|
||||
# Making sure `ST_Length3D` is used on for a projected
|
||||
# and 3D model rather than `ST_Length`.
|
||||
# `SELECT ST_Length(line) FROM geo3d_interstateproj2d;`
|
||||
ref_length_2d = 4367.71564892392
|
||||
# `SELECT ST_Length3D(line) FROM geo3d_interstateproj3d;`
|
||||
ref_length_3d = 4368.16897234101
|
||||
self.assertAlmostEqual(ref_length_2d,
|
||||
InterstateProj2D.objects.length().get(name='I-45').length.m,
|
||||
tol)
|
||||
self.assertAlmostEqual(ref_length_3d,
|
||||
InterstateProj3D.objects.length().get(name='I-45').length.m,
|
||||
tol)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_scale(self):
|
||||
"""
|
||||
Testing GeoQuerySet.scale() on Z values.
|
||||
"""
|
||||
self._load_city_data()
|
||||
# Mapping of City name to reference Z values.
|
||||
zscales = (-3, 4, 23)
|
||||
for zscale in zscales:
|
||||
for city in City3D.objects.scale(1.0, 1.0, zscale):
|
||||
self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_translate(self):
|
||||
"""
|
||||
Testing GeoQuerySet.translate() on Z values.
|
||||
"""
|
||||
self._load_city_data()
|
||||
ztranslations = (5.23, 23, -17)
|
||||
for ztrans in ztranslations:
|
||||
for city in City3D.objects.translate(0, 0, ztrans):
|
||||
self.assertEqual(city_dict[city.name][2] + ztrans, city.translate.z)
|
||||
|
||||
|
||||
@skipUnlessDBFeature("gis_enabled", "supports_3d_functions")
|
||||
class Geo3DFunctionsTests(Geo3DLoadingHelper, TestCase):
|
||||
|
|
|
@ -8,8 +8,6 @@ from ..utils import gisfield_may_be_null
|
|||
class NamedModel(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
objects = models.GeoManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
required_db_features = ['gis_enabled']
|
||||
|
|
|
@ -19,7 +19,6 @@ from .models import City, Country, CountryWebMercator, State, Track
|
|||
class GISFunctionsTests(TestCase):
|
||||
"""
|
||||
Testing functions from django/contrib/gis/db/models/functions.py.
|
||||
Several tests are taken and adapted from GeoQuerySetTest.
|
||||
Area/Distance/Length/Perimeter are tested in distapp/tests.
|
||||
|
||||
Please keep the tests in function's alphabetic order.
|
||||
|
@ -462,7 +461,6 @@ class GISFunctionsTests(TestCase):
|
|||
"has_Difference_function", "has_Intersection_function",
|
||||
"has_SymDifference_function", "has_Union_function")
|
||||
def test_diff_intersection_union(self):
|
||||
"Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
|
||||
geom = Point(5, 23, srid=4326)
|
||||
qs = Country.objects.all().annotate(
|
||||
difference=functions.Difference('mpoly', geom),
|
||||
|
|
|
@ -17,7 +17,7 @@ class GeoRegressionTests(TestCase):
|
|||
fixtures = ['initial']
|
||||
|
||||
def test_update(self):
|
||||
"Testing GeoQuerySet.update(). See #10411."
|
||||
"Testing QuerySet.update() (#10411)."
|
||||
pnt = City.objects.get(name='Pueblo').point
|
||||
bak = pnt.clone()
|
||||
pnt.y += 0.005
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
from django.contrib.gis import gdal
|
||||
from django.contrib.gis.db.models import Extent, MakeLine, Union
|
||||
from django.contrib.gis.db.models import Extent, MakeLine, Union, functions
|
||||
from django.contrib.gis.geos import (
|
||||
GeometryCollection, GEOSGeometry, LinearRing, LineString, MultiLineString,
|
||||
MultiPoint, MultiPolygon, Point, Polygon, fromstr,
|
||||
)
|
||||
from django.core.management import call_command
|
||||
from django.db import connection
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
|
||||
from ..utils import oracle, postgis, skipUnlessGISLookup, spatialite
|
||||
from ..utils import no_oracle, oracle, postgis, skipUnlessGISLookup, spatialite
|
||||
from .models import (
|
||||
City, Country, Feature, MinusOneSRID, NonConcreteModel, PennsylvaniaCity,
|
||||
State, Track,
|
||||
|
@ -155,19 +153,22 @@ class GeoModelTest(TestCase):
|
|||
self.assertIsInstance(f_4.geom, GeometryCollection)
|
||||
self.assertEqual(f_3.geom, f_4.geom[2])
|
||||
|
||||
# TODO: fix on Oracle: ORA-22901: cannot compare nested table or VARRAY or
|
||||
# LOB attributes of an object type.
|
||||
@no_oracle
|
||||
@skipUnlessDBFeature("supports_transform")
|
||||
def test_inherited_geofields(self):
|
||||
"Test GeoQuerySet methods on inherited Geometry fields."
|
||||
"Database functions on inherited Geometry fields."
|
||||
# Creating a Pennsylvanian city.
|
||||
PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
|
||||
|
||||
# All transformation SQL will need to be performed on the
|
||||
# _parent_ table.
|
||||
qs = PennsylvaniaCity.objects.transform(32128)
|
||||
qs = PennsylvaniaCity.objects.annotate(new_point=functions.Transform('point', srid=32128))
|
||||
|
||||
self.assertEqual(1, qs.count())
|
||||
for pc in qs:
|
||||
self.assertEqual(32128, pc.point.srid)
|
||||
self.assertEqual(32128, pc.new_point.srid)
|
||||
|
||||
def test_raw_sql_query(self):
|
||||
"Testing raw SQL query."
|
||||
|
@ -412,8 +413,8 @@ class GeoLookupTest(TestCase):
|
|||
pnt1 = fromstr('POINT (649287.0363174 4177429.4494686)', srid=2847)
|
||||
pnt2 = fromstr('POINT(-98.4919715741052 29.4333344025053)', srid=4326)
|
||||
|
||||
# Not passing in a geometry as first param should
|
||||
# raise a type error when initializing the GeoQuerySet
|
||||
# Not passing in a geometry as first param raises a TypeError when
|
||||
# initializing the QuerySet.
|
||||
with self.assertRaises(ValueError):
|
||||
Country.objects.filter(mpoly__relate=(23, 'foo'))
|
||||
|
||||
|
@ -451,66 +452,10 @@ class GeoLookupTest(TestCase):
|
|||
|
||||
|
||||
@skipUnlessDBFeature("gis_enabled")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
class GeoQuerySetTest(TestCase):
|
||||
# TODO: GeoQuerySet is removed, organize these test better.
|
||||
fixtures = ['initial']
|
||||
|
||||
# Please keep the tests in GeoQuerySet method's alphabetic order
|
||||
|
||||
@skipUnlessDBFeature("has_centroid_method")
|
||||
def test_centroid(self):
|
||||
"Testing the `centroid` GeoQuerySet method."
|
||||
qs = State.objects.exclude(poly__isnull=True).centroid()
|
||||
if oracle:
|
||||
tol = 0.1
|
||||
elif spatialite:
|
||||
tol = 0.000001
|
||||
else:
|
||||
tol = 0.000000001
|
||||
for s in qs:
|
||||
self.assertTrue(s.poly.centroid.equals_exact(s.centroid, tol))
|
||||
|
||||
@skipUnlessDBFeature(
|
||||
"has_difference_method", "has_intersection_method",
|
||||
"has_sym_difference_method", "has_union_method")
|
||||
def test_diff_intersection_union(self):
|
||||
"Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
|
||||
geom = Point(5, 23)
|
||||
qs = Country.objects.all().difference(geom).sym_difference(geom).union(geom)
|
||||
|
||||
# XXX For some reason SpatiaLite does something screwy with the Texas geometry here. Also,
|
||||
# XXX it doesn't like the null intersection.
|
||||
if spatialite:
|
||||
qs = qs.exclude(name='Texas')
|
||||
else:
|
||||
qs = qs.intersection(geom)
|
||||
|
||||
for c in qs:
|
||||
if oracle:
|
||||
# Should be able to execute the queries; however, they won't be the same
|
||||
# as GEOS (because Oracle doesn't use GEOS internally like PostGIS or
|
||||
# SpatiaLite).
|
||||
pass
|
||||
else:
|
||||
if spatialite:
|
||||
# Spatialite `difference` doesn't have an SRID
|
||||
self.assertEqual(c.mpoly.difference(geom).wkt, c.difference.wkt)
|
||||
else:
|
||||
self.assertEqual(c.mpoly.difference(geom), c.difference)
|
||||
self.assertEqual(c.mpoly.intersection(geom), c.intersection)
|
||||
# Ordering might differ in collections
|
||||
self.assertSetEqual(set(g.wkt for g in c.mpoly.sym_difference(geom)),
|
||||
set(g.wkt for g in c.sym_difference))
|
||||
self.assertSetEqual(set(g.wkt for g in c.mpoly.union(geom)),
|
||||
set(g.wkt for g in c.union))
|
||||
|
||||
@skipUnlessDBFeature("has_envelope_method")
|
||||
def test_envelope(self):
|
||||
"Testing the `envelope` GeoQuerySet method."
|
||||
countries = Country.objects.all().envelope()
|
||||
for country in countries:
|
||||
self.assertIsInstance(country.envelope, Polygon)
|
||||
|
||||
@skipUnlessDBFeature("supports_extent_aggr")
|
||||
def test_extent(self):
|
||||
"""
|
||||
|
@ -536,132 +481,6 @@ class GeoQuerySetTest(TestCase):
|
|||
extent2 = City.objects.all()[:3].aggregate(Extent('point'))['point__extent']
|
||||
self.assertNotEqual(extent1, extent2)
|
||||
|
||||
@skipUnlessDBFeature("has_force_rhr_method")
|
||||
def test_force_rhr(self):
|
||||
"Testing GeoQuerySet.force_rhr()."
|
||||
rings = (
|
||||
((0, 0), (5, 0), (0, 5), (0, 0)),
|
||||
((1, 1), (1, 3), (3, 1), (1, 1)),
|
||||
)
|
||||
rhr_rings = (
|
||||
((0, 0), (0, 5), (5, 0), (0, 0)),
|
||||
((1, 1), (3, 1), (1, 3), (1, 1)),
|
||||
)
|
||||
State.objects.create(name='Foo', poly=Polygon(*rings))
|
||||
s = State.objects.force_rhr().get(name='Foo')
|
||||
self.assertEqual(rhr_rings, s.force_rhr.coords)
|
||||
|
||||
@skipUnlessDBFeature("has_geohash_method")
|
||||
def test_geohash(self):
|
||||
"Testing GeoQuerySet.geohash()."
|
||||
# Reference query:
|
||||
# SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston';
|
||||
# SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston';
|
||||
ref_hash = '9vk1mfq8jx0c8e0386z6'
|
||||
h1 = City.objects.geohash().get(name='Houston')
|
||||
h2 = City.objects.geohash(precision=5).get(name='Houston')
|
||||
self.assertEqual(ref_hash, h1.geohash)
|
||||
self.assertEqual(ref_hash[:5], h2.geohash)
|
||||
|
||||
def test_geojson(self):
|
||||
"Testing GeoJSON output from the database using GeoQuerySet.geojson()."
|
||||
# Only PostGIS and SpatiaLite support GeoJSON.
|
||||
if not connection.ops.geojson:
|
||||
with self.assertRaises(NotImplementedError):
|
||||
Country.objects.all().geojson(field_name='mpoly')
|
||||
return
|
||||
|
||||
pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}'
|
||||
houston_json = (
|
||||
'{"type":"Point","crs":{"type":"name","properties":'
|
||||
'{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}'
|
||||
)
|
||||
victoria_json = (
|
||||
'{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],'
|
||||
'"coordinates":[-123.305196,48.462611]}'
|
||||
)
|
||||
chicago_json = (
|
||||
'{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},'
|
||||
'"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
|
||||
)
|
||||
if spatialite:
|
||||
victoria_json = (
|
||||
'{"type":"Point","bbox":[-123.305196,48.462611,-123.305196,48.462611],'
|
||||
'"coordinates":[-123.305196,48.462611]}'
|
||||
)
|
||||
|
||||
# Precision argument should only be an integer
|
||||
with self.assertRaises(TypeError):
|
||||
City.objects.geojson(precision='foo')
|
||||
|
||||
# Reference queries and values.
|
||||
# SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0)
|
||||
# FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo';
|
||||
self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson)
|
||||
|
||||
# SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city"
|
||||
# WHERE "geoapp_city"."name" = 'Houston';
|
||||
# This time we want to include the CRS by using the `crs` keyword.
|
||||
self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json)
|
||||
|
||||
# SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city"
|
||||
# WHERE "geoapp_city"."name" = 'Houston';
|
||||
# This time we include the bounding box by using the `bbox` keyword.
|
||||
self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson)
|
||||
|
||||
# SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city"
|
||||
# WHERE "geoapp_city"."name" = 'Chicago';
|
||||
# Finally, we set every available keyword.
|
||||
self.assertEqual(
|
||||
chicago_json,
|
||||
City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature("has_gml_method")
|
||||
def test_gml(self):
|
||||
"Testing GML output from the database using GeoQuerySet.gml()."
|
||||
# Should throw a TypeError when trying to obtain GML from a
|
||||
# non-geometry field.
|
||||
qs = City.objects.all()
|
||||
with self.assertRaises(TypeError):
|
||||
qs.gml(field_name='name')
|
||||
ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo')
|
||||
ptown2 = City.objects.gml(precision=9).get(name='Pueblo')
|
||||
|
||||
if oracle:
|
||||
# No precision parameter for Oracle :-/
|
||||
gml_regex = re.compile(
|
||||
r'^<gml:Point srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml">'
|
||||
r'<gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ '
|
||||
r'</gml:coordinates></gml:Point>'
|
||||
)
|
||||
else:
|
||||
gml_regex = re.compile(
|
||||
r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>'
|
||||
r'-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>'
|
||||
)
|
||||
|
||||
for ptown in [ptown1, ptown2]:
|
||||
self.assertTrue(gml_regex.match(ptown.gml))
|
||||
|
||||
if postgis:
|
||||
self.assertIn('<gml:pos srsDimension="2">', City.objects.gml(version=3).get(name='Pueblo').gml)
|
||||
|
||||
@skipUnlessDBFeature("has_kml_method")
|
||||
def test_kml(self):
|
||||
"Testing KML output from the database using GeoQuerySet.kml()."
|
||||
# Should throw a TypeError when trying to obtain KML from a
|
||||
# non-geometry field.
|
||||
qs = City.objects.all()
|
||||
with self.assertRaises(TypeError):
|
||||
qs.kml('name')
|
||||
|
||||
# Ensuring the KML is as expected.
|
||||
ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo')
|
||||
ptown2 = City.objects.kml(precision=9).get(name='Pueblo')
|
||||
for ptown in [ptown1, ptown2]:
|
||||
self.assertEqual('<Point><coordinates>-104.609252,38.255001</coordinates></Point>', ptown.kml)
|
||||
|
||||
def test_make_line(self):
|
||||
"""
|
||||
Testing the `MakeLine` aggregate.
|
||||
|
@ -689,181 +508,6 @@ class GeoQuerySetTest(TestCase):
|
|||
"%s != %s" % (ref_line, line)
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature("has_num_geom_method")
|
||||
def test_num_geom(self):
|
||||
"Testing the `num_geom` GeoQuerySet method."
|
||||
# Both 'countries' only have two geometries.
|
||||
for c in Country.objects.num_geom():
|
||||
self.assertEqual(2, c.num_geom)
|
||||
|
||||
for c in City.objects.filter(point__isnull=False).num_geom():
|
||||
# Oracle and PostGIS 2.0+ will return 1 for the number of
|
||||
# geometries on non-collections.
|
||||
self.assertEqual(1, c.num_geom)
|
||||
|
||||
@skipUnlessDBFeature("supports_num_points_poly")
|
||||
def test_num_points(self):
|
||||
"Testing the `num_points` GeoQuerySet method."
|
||||
for c in Country.objects.num_points():
|
||||
self.assertEqual(c.mpoly.num_points, c.num_points)
|
||||
|
||||
if not oracle:
|
||||
# Oracle cannot count vertices in Point geometries.
|
||||
for c in City.objects.num_points():
|
||||
self.assertEqual(1, c.num_points)
|
||||
|
||||
@skipUnlessDBFeature("has_point_on_surface_method")
|
||||
def test_point_on_surface(self):
|
||||
"Testing the `point_on_surface` GeoQuerySet method."
|
||||
# Reference values.
|
||||
if oracle:
|
||||
# SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05))
|
||||
# FROM GEOAPP_COUNTRY;
|
||||
ref = {'New Zealand': fromstr('POINT (174.616364 -36.100861)', srid=4326),
|
||||
'Texas': fromstr('POINT (-103.002434 36.500397)', srid=4326),
|
||||
}
|
||||
|
||||
else:
|
||||
# Using GEOSGeometry to compute the reference point on surface values
|
||||
# -- since PostGIS also uses GEOS these should be the same.
|
||||
ref = {'New Zealand': Country.objects.get(name='New Zealand').mpoly.point_on_surface,
|
||||
'Texas': Country.objects.get(name='Texas').mpoly.point_on_surface
|
||||
}
|
||||
|
||||
for c in Country.objects.point_on_surface():
|
||||
if spatialite:
|
||||
# XXX This seems to be a WKT-translation-related precision issue?
|
||||
tol = 0.00001
|
||||
else:
|
||||
tol = 0.000000001
|
||||
self.assertTrue(ref[c.name].equals_exact(c.point_on_surface, tol))
|
||||
|
||||
@skipUnlessDBFeature("has_reverse_method")
|
||||
def test_reverse_geom(self):
|
||||
"Testing GeoQuerySet.reverse_geom()."
|
||||
coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)]
|
||||
Track.objects.create(name='Foo', line=LineString(coords))
|
||||
t = Track.objects.reverse_geom().get(name='Foo')
|
||||
coords.reverse()
|
||||
self.assertEqual(tuple(coords), t.reverse_geom.coords)
|
||||
if oracle:
|
||||
with self.assertRaises(TypeError):
|
||||
State.objects.reverse_geom()
|
||||
|
||||
@skipUnlessDBFeature("has_scale_method")
|
||||
def test_scale(self):
|
||||
"Testing the `scale` GeoQuerySet method."
|
||||
xfac, yfac = 2, 3
|
||||
tol = 5 # XXX The low precision tolerance is for SpatiaLite
|
||||
qs = Country.objects.scale(xfac, yfac, model_att='scaled')
|
||||
for c in qs:
|
||||
for p1, p2 in zip(c.mpoly, c.scaled):
|
||||
for r1, r2 in zip(p1, p2):
|
||||
for c1, c2 in zip(r1.coords, r2.coords):
|
||||
self.assertAlmostEqual(c1[0] * xfac, c2[0], tol)
|
||||
self.assertAlmostEqual(c1[1] * yfac, c2[1], tol)
|
||||
|
||||
@skipUnlessDBFeature("has_snap_to_grid_method")
|
||||
def test_snap_to_grid(self):
|
||||
"Testing GeoQuerySet.snap_to_grid()."
|
||||
# Let's try and break snap_to_grid() with bad combinations of arguments.
|
||||
for bad_args in ((), range(3), range(5)):
|
||||
with self.assertRaises(ValueError):
|
||||
Country.objects.snap_to_grid(*bad_args)
|
||||
for bad_args in (('1.0',), (1.0, None), tuple(map(six.text_type, range(4)))):
|
||||
with self.assertRaises(TypeError):
|
||||
Country.objects.snap_to_grid(*bad_args)
|
||||
|
||||
# Boundary for San Marino, courtesy of Bjorn Sandvik of thematicmapping.org
|
||||
# from the world borders dataset he provides.
|
||||
wkt = ('MULTIPOLYGON(((12.41580 43.95795,12.45055 43.97972,12.45389 43.98167,'
|
||||
'12.46250 43.98472,12.47167 43.98694,12.49278 43.98917,'
|
||||
'12.50555 43.98861,12.51000 43.98694,12.51028 43.98277,'
|
||||
'12.51167 43.94333,12.51056 43.93916,12.49639 43.92333,'
|
||||
'12.49500 43.91472,12.48778 43.90583,12.47444 43.89722,'
|
||||
'12.46472 43.89555,12.45917 43.89611,12.41639 43.90472,'
|
||||
'12.41222 43.90610,12.40782 43.91366,12.40389 43.92667,'
|
||||
'12.40500 43.94833,12.40889 43.95499,12.41580 43.95795)))')
|
||||
Country.objects.create(name='San Marino', mpoly=fromstr(wkt))
|
||||
|
||||
# Because floating-point arithmetic isn't exact, we set a tolerance
|
||||
# to pass into GEOS `equals_exact`.
|
||||
tol = 0.000000001
|
||||
|
||||
# SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.1)) FROM "geoapp_country"
|
||||
# WHERE "geoapp_country"."name" = 'San Marino';
|
||||
ref = fromstr('MULTIPOLYGON(((12.4 44,12.5 44,12.5 43.9,12.4 43.9,12.4 44)))')
|
||||
self.assertTrue(ref.equals_exact(Country.objects.snap_to_grid(0.1).get(name='San Marino').snap_to_grid, tol))
|
||||
|
||||
# SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.05, 0.23)) FROM "geoapp_country"
|
||||
# WHERE "geoapp_country"."name" = 'San Marino';
|
||||
ref = fromstr('MULTIPOLYGON(((12.4 43.93,12.45 43.93,12.5 43.93,12.45 43.93,12.4 43.93)))')
|
||||
self.assertTrue(
|
||||
ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23).get(name='San Marino').snap_to_grid, tol)
|
||||
)
|
||||
|
||||
# SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.5, 0.17, 0.05, 0.23)) FROM "geoapp_country"
|
||||
# WHERE "geoapp_country"."name" = 'San Marino';
|
||||
ref = fromstr(
|
||||
'MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))'
|
||||
)
|
||||
self.assertTrue(
|
||||
ref.equals_exact(
|
||||
Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid,
|
||||
tol
|
||||
)
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature("has_svg_method")
|
||||
def test_svg(self):
|
||||
"Testing SVG output using GeoQuerySet.svg()."
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
City.objects.svg(precision='foo')
|
||||
# SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo';
|
||||
svg1 = 'cx="-104.609252" cy="-38.255001"'
|
||||
# Even though relative, only one point so it's practically the same except for
|
||||
# the 'c' letter prefix on the x,y values.
|
||||
svg2 = svg1.replace('c', '')
|
||||
self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg)
|
||||
self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg)
|
||||
|
||||
@skipUnlessDBFeature("has_transform_method")
|
||||
def test_transform(self):
|
||||
"Testing the transform() GeoQuerySet method."
|
||||
# Pre-transformed points for Houston and Pueblo.
|
||||
htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084)
|
||||
ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774)
|
||||
prec = 3 # Precision is low due to version variations in PROJ and GDAL.
|
||||
|
||||
# Asserting the result of the transform operation with the values in
|
||||
# the pre-transformed points. Oracle does not have the 3084 SRID.
|
||||
if not oracle:
|
||||
h = City.objects.transform(htown.srid).get(name='Houston')
|
||||
self.assertEqual(3084, h.point.srid)
|
||||
self.assertAlmostEqual(htown.x, h.point.x, prec)
|
||||
self.assertAlmostEqual(htown.y, h.point.y, prec)
|
||||
|
||||
p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo')
|
||||
p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo')
|
||||
for p in [p1, p2]:
|
||||
self.assertEqual(2774, p.point.srid)
|
||||
self.assertAlmostEqual(ptown.x, p.point.x, prec)
|
||||
self.assertAlmostEqual(ptown.y, p.point.y, prec)
|
||||
|
||||
@skipUnlessDBFeature("has_translate_method")
|
||||
def test_translate(self):
|
||||
"Testing the `translate` GeoQuerySet method."
|
||||
xfac, yfac = 5, -23
|
||||
qs = Country.objects.translate(xfac, yfac, model_att='translated')
|
||||
for c in qs:
|
||||
for p1, p2 in zip(c.mpoly, c.translated):
|
||||
for r1, r2 in zip(p1, p2):
|
||||
for c1, c2 in zip(r1.coords, r2.coords):
|
||||
# XXX The low precision is for SpatiaLite
|
||||
self.assertAlmostEqual(c1[0] + xfac, c2[0], 5)
|
||||
self.assertAlmostEqual(c1[1] + yfac, c2[1], 5)
|
||||
|
||||
@skipUnlessDBFeature('supports_union_aggr')
|
||||
def test_unionagg(self):
|
||||
"""
|
||||
|
|
|
@ -6,8 +6,6 @@ from django.utils.encoding import python_2_unicode_compatible
|
|||
class NamedModel(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
objects = models.GeoManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
required_db_features = ['gis_enabled']
|
||||
|
|
|
@ -11,11 +11,8 @@ from django.contrib.gis.db.models.functions import Area, Distance
|
|||
from django.contrib.gis.measure import D
|
||||
from django.db import connection
|
||||
from django.db.models.functions import Cast
|
||||
from django.test import (
|
||||
TestCase, ignore_warnings, skipIfDBFeature, skipUnlessDBFeature,
|
||||
)
|
||||
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
|
||||
from ..utils import oracle, postgis, spatialite
|
||||
from .models import City, County, Zipcode
|
||||
|
@ -32,7 +29,7 @@ class GeographyTest(TestCase):
|
|||
@skipIf(spatialite, "SpatiaLite doesn't support distance lookups with Distance objects.")
|
||||
@skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
|
||||
def test02_distance_lookup(self):
|
||||
"Testing GeoQuerySet distance lookup support on non-point geography fields."
|
||||
"Testing distance lookup support on non-point geography fields."
|
||||
z = Zipcode.objects.get(code='77002')
|
||||
cities1 = list(City.objects
|
||||
.filter(point__distance_lte=(z.poly, D(mi=500)))
|
||||
|
@ -45,15 +42,6 @@ class GeographyTest(TestCase):
|
|||
for cities in [cities1, cities2]:
|
||||
self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
|
||||
|
||||
@skipIf(spatialite, "distance() doesn't support geodetic coordinates on SpatiaLite.")
|
||||
@skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test03_distance_method(self):
|
||||
"Testing GeoQuerySet.distance() support on non-point geography fields."
|
||||
# `GeoQuerySet.distance` is not allowed geometry fields.
|
||||
htown = City.objects.get(name='Houston')
|
||||
Zipcode.objects.distance(htown.point)
|
||||
|
||||
@skipUnless(postgis, "This is a PostGIS-specific test")
|
||||
def test04_invalid_operators_functions(self):
|
||||
"Ensuring exceptions are raised for operators & functions invalid on geography fields."
|
||||
|
@ -101,19 +89,6 @@ class GeographyTest(TestCase):
|
|||
self.assertEqual(name, c.name)
|
||||
self.assertEqual(state, c.state)
|
||||
|
||||
@skipIf(spatialite, "area() doesn't support geodetic coordinates on SpatiaLite.")
|
||||
@skipUnlessDBFeature("has_area_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
def test06_geography_area(self):
|
||||
"Testing that Area calculations work on geography columns."
|
||||
# SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
|
||||
z = Zipcode.objects.area().get(code='77002')
|
||||
# Round to the nearest thousand as possible values (depending on
|
||||
# the database and geolib) include 5439084, 5439100, 5439101.
|
||||
rounded_value = z.area.sq_m
|
||||
rounded_value -= z.area.sq_m % 1000
|
||||
self.assertEqual(rounded_value, 5439000)
|
||||
|
||||
|
||||
@skipUnlessDBFeature("gis_enabled")
|
||||
class GeographyFunctionTests(TestCase):
|
||||
|
|
|
@ -3,9 +3,6 @@ from django.utils.encoding import python_2_unicode_compatible
|
|||
|
||||
|
||||
class SimpleModel(models.Model):
|
||||
|
||||
objects = models.GeoManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
required_db_features = ['gis_enabled']
|
||||
|
|
|
@ -38,33 +38,6 @@ class RelatedGeoModelTest(TestCase):
|
|||
self.assertEqual(st, c.state)
|
||||
self.assertEqual(Point(lon, lat, srid=c.location.point.srid), c.location.point)
|
||||
|
||||
@skipUnlessDBFeature("has_transform_method")
|
||||
def test03_transform_related(self):
|
||||
"Testing the `transform` GeoQuerySet method on related geographic models."
|
||||
# All the transformations are to state plane coordinate systems using
|
||||
# US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot).
|
||||
tol = 0
|
||||
|
||||
def check_pnt(ref, pnt):
|
||||
self.assertAlmostEqual(ref.x, pnt.x, tol)
|
||||
self.assertAlmostEqual(ref.y, pnt.y, tol)
|
||||
self.assertEqual(ref.srid, pnt.srid)
|
||||
|
||||
# Each city transformed to the SRID of their state plane coordinate system.
|
||||
transformed = (('Kecksburg', 2272, 'POINT(1490553.98959621 314792.131023984)'),
|
||||
('Roswell', 2257, 'POINT(481902.189077221 868477.766629735)'),
|
||||
('Aurora', 2276, 'POINT(2269923.2484839 7069381.28722222)'),
|
||||
)
|
||||
|
||||
for name, srid, wkt in transformed:
|
||||
# Doing this implicitly sets `select_related` select the location.
|
||||
# TODO: Fix why this breaks on Oracle.
|
||||
qs = list(City.objects.filter(name=name).transform(srid, field_name='location__point'))
|
||||
check_pnt(GEOSGeometry(wkt, srid), qs[0].location.point)
|
||||
|
||||
# Relations more than one level deep can be queried.
|
||||
self.assertEqual(list(Parcel.objects.transform(srid, field_name='city__location__point')), [])
|
||||
|
||||
@skipUnlessDBFeature("supports_extent_aggr")
|
||||
def test_related_extent_aggregate(self):
|
||||
"Testing the `Extent` aggregate on related geographic models."
|
||||
|
@ -190,13 +163,13 @@ class RelatedGeoModelTest(TestCase):
|
|||
self.assertEqual('P1', qs[0].name)
|
||||
|
||||
def test07_values(self):
|
||||
"Testing values() and values_list() and GeoQuerySets."
|
||||
"Testing values() and values_list()."
|
||||
gqs = Location.objects.all()
|
||||
gvqs = Location.objects.values()
|
||||
gvlqs = Location.objects.values_list()
|
||||
|
||||
# Incrementing through each of the models, dictionaries, and tuples
|
||||
# returned by the different types of GeoQuerySets.
|
||||
# returned by each QuerySet.
|
||||
for m, d, t in zip(gqs, gvqs, gvlqs):
|
||||
# The values should be Geometry objects and not raw strings returned
|
||||
# by the spatial database.
|
||||
|
@ -234,7 +207,7 @@ class RelatedGeoModelTest(TestCase):
|
|||
# TODO: fix on Oracle -- qs2 returns an empty result for an unknown reason
|
||||
@no_oracle
|
||||
def test10_combine(self):
|
||||
"Testing the combination of two GeoQuerySets. See #10807."
|
||||
"Testing the combination of two QuerySets (#10807)."
|
||||
buf1 = City.objects.get(name='Aurora').location.point.buffer(0.1)
|
||||
buf2 = City.objects.get(name='Kecksburg').location.point.buffer(0.1)
|
||||
qs1 = City.objects.filter(location__point__within=buf1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue