summaryrefslogtreecommitdiff
path: root/tests/gis_tests
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/gis_tests
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/gis_tests')
-rw-r--r--tests/gis_tests/distapp/tests.py500
-rw-r--r--tests/gis_tests/gdal_tests/test_driver.py44
-rw-r--r--tests/gis_tests/gdal_tests/test_ds.py162
-rw-r--r--tests/gis_tests/gdal_tests/test_envelope.py11
-rw-r--r--tests/gis_tests/gdal_tests/test_geom.py275
-rw-r--r--tests/gis_tests/gdal_tests/test_raster.py802
-rw-r--r--tests/gis_tests/gdal_tests/test_srs.py160
-rw-r--r--tests/gis_tests/gdal_tests/tests.py10
-rw-r--r--tests/gis_tests/geo3d/models.py13
-rw-r--r--tests/gis_tests/geo3d/tests.py174
-rw-r--r--tests/gis_tests/geoadmin/models.py14
-rw-r--r--tests/gis_tests/geoadmin/tests.py44
-rw-r--r--tests/gis_tests/geoadmin/urls.py2
-rw-r--r--tests/gis_tests/geoadmin_deprecated/models.py4
-rw-r--r--tests/gis_tests/geoadmin_deprecated/tests.py54
-rw-r--r--tests/gis_tests/geoadmin_deprecated/urls.py2
-rw-r--r--tests/gis_tests/geoapp/feeds.py21
-rw-r--r--tests/gis_tests/geoapp/models.py15
-rw-r--r--tests/gis_tests/geoapp/sitemaps.py4
-rw-r--r--tests/gis_tests/geoapp/test_expressions.py42
-rw-r--r--tests/gis_tests/geoapp/test_feeds.py75
-rw-r--r--tests/gis_tests/geoapp/test_functions.py465
-rw-r--r--tests/gis_tests/geoapp/test_indexes.py28
-rw-r--r--tests/gis_tests/geoapp/test_regress.py56
-rw-r--r--tests/gis_tests/geoapp/test_serializers.py65
-rw-r--r--tests/gis_tests/geoapp/test_sitemaps.py45
-rw-r--r--tests/gis_tests/geoapp/tests.py471
-rw-r--r--tests/gis_tests/geoapp/urls.py14
-rw-r--r--tests/gis_tests/geogapp/models.py6
-rw-r--r--tests/gis_tests/geogapp/tests.py85
-rw-r--r--tests/gis_tests/geos_tests/test_coordseq.py3
-rw-r--r--tests/gis_tests/geos_tests/test_geos.py460
-rw-r--r--tests/gis_tests/geos_tests/test_geos_mutation.py123
-rw-r--r--tests/gis_tests/geos_tests/test_io.py115
-rw-r--r--tests/gis_tests/geos_tests/test_mutable_list.py196
-rw-r--r--tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py4
-rw-r--r--tests/gis_tests/gis_migrations/migrations/0002_create_models.py104
-rw-r--r--tests/gis_tests/gis_migrations/test_commands.py6
-rw-r--r--tests/gis_tests/gis_migrations/test_operations.py195
-rw-r--r--tests/gis_tests/inspectapp/models.py2
-rw-r--r--tests/gis_tests/inspectapp/tests.py204
-rw-r--r--tests/gis_tests/layermap/models.py46
-rw-r--r--tests/gis_tests/layermap/tests.py168
-rw-r--r--tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py4
-rw-r--r--tests/gis_tests/rasterapp/migrations/0002_rastermodels.py71
-rw-r--r--tests/gis_tests/rasterapp/models.py10
-rw-r--r--tests/gis_tests/rasterapp/test_rasterfield.py215
-rw-r--r--tests/gis_tests/relatedapp/models.py4
-rw-r--r--tests/gis_tests/relatedapp/tests.py162
-rw-r--r--tests/gis_tests/test_data.py16
-rw-r--r--tests/gis_tests/test_fields.py36
-rw-r--r--tests/gis_tests/test_geoforms.py371
-rw-r--r--tests/gis_tests/test_geoip2.py119
-rw-r--r--tests/gis_tests/test_gis_tests_utils.py19
-rw-r--r--tests/gis_tests/test_measure.py48
-rw-r--r--tests/gis_tests/test_ptr.py7
-rw-r--r--tests/gis_tests/test_spatialrefsys.py124
-rw-r--r--tests/gis_tests/tests.py28
-rw-r--r--tests/gis_tests/utils.py24
59 files changed, 3959 insertions, 2588 deletions
diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py
index 244c99a1d7..a28a698a81 100644
--- a/tests/gis_tests/distapp/tests.py
+++ b/tests/gis_tests/distapp/tests.py
@@ -1,32 +1,52 @@
from django.contrib.gis.db.models.functions import (
- Area, Distance, Length, Perimeter, Transform, Union,
+ Area,
+ Distance,
+ Length,
+ Perimeter,
+ Transform,
+ Union,
)
from django.contrib.gis.geos import GEOSGeometry, LineString, Point
from django.contrib.gis.measure import D # alias for Distance
from django.db import NotSupportedError, connection
from django.db.models import (
- Case, Count, Exists, F, IntegerField, OuterRef, Q, Value, When,
+ Case,
+ Count,
+ Exists,
+ F,
+ IntegerField,
+ OuterRef,
+ Q,
+ Value,
+ When,
)
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
from ..utils import FuncTestMixin
from .models import (
- AustraliaCity, CensusZipcode, Interstate, SouthTexasCity, SouthTexasCityFt,
- SouthTexasInterstate, SouthTexasZipcode,
+ AustraliaCity,
+ CensusZipcode,
+ Interstate,
+ SouthTexasCity,
+ SouthTexasCityFt,
+ SouthTexasInterstate,
+ SouthTexasZipcode,
)
class DistanceTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def setUp(self):
# A point we are testing distances with -- using a WGS84
# coordinate that'll be implicitly transformed to that to
# the coordinate system of the field, EPSG:32140 (Texas South Central
# w/units in meters)
- self.stx_pnt = GEOSGeometry('POINT (-95.370401017314293 29.704867409475465)', 4326)
+ self.stx_pnt = GEOSGeometry(
+ "POINT (-95.370401017314293 29.704867409475465)", 4326
+ )
# Another one for Australia
- self.au_pnt = GEOSGeometry('POINT (150.791 -34.4919)', 4326)
+ self.au_pnt = GEOSGeometry("POINT (150.791 -34.4919)", 4326)
def get_names(self, qs):
cities = [c.name for c in qs]
@@ -57,8 +77,8 @@ class DistanceTest(TestCase):
au_dists = [(0.5, 32000), D(km=32), D(mi=19.884)]
# Expected cities for Australia and Texas.
- tx_cities = ['Downtown Houston', 'Southside Place']
- au_cities = ['Mittagong', 'Shellharbour', 'Thirroul', 'Wollongong']
+ tx_cities = ["Downtown Houston", "Southside Place"]
+ au_cities = ["Mittagong", "Shellharbour", "Thirroul", "Wollongong"]
# Performing distance queries on two projected coordinate systems one
# with units in meters and the other in units of U.S. survey feet.
@@ -74,7 +94,9 @@ class DistanceTest(TestCase):
self.assertEqual(tx_cities, self.get_names(qs))
# With a complex geometry expression
- self.assertFalse(SouthTexasCity.objects.exclude(point__dwithin=(Union('point', 'point'), 0)))
+ self.assertFalse(
+ SouthTexasCity.objects.exclude(point__dwithin=(Union("point", "point"), 0))
+ )
# Now performing the `dwithin` queries on a geodetic coordinate system.
for dist in au_dists:
@@ -89,15 +111,20 @@ class DistanceTest(TestCase):
dist = dist[0]
# Creating the query set.
- qs = AustraliaCity.objects.order_by('name')
+ qs = AustraliaCity.objects.order_by("name")
if type_error:
# A ValueError should be raised on PostGIS when trying to
# pass Distance objects into a DWithin query using a
# geodetic field.
with self.assertRaises(ValueError):
- AustraliaCity.objects.filter(point__dwithin=(self.au_pnt, dist)).count()
+ AustraliaCity.objects.filter(
+ point__dwithin=(self.au_pnt, dist)
+ ).count()
else:
- self.assertEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))))
+ self.assertEqual(
+ au_cities,
+ self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))),
+ )
@skipUnlessDBFeature("supports_distances_lookups")
def test_distance_lookups(self):
@@ -108,20 +135,26 @@ class DistanceTest(TestCase):
# (thus, Houston and Southside place will be excluded as tested in
# the `test02_dwithin` above).
for model in [SouthTexasCity, SouthTexasCityFt]:
- stx_pnt = self.stx_pnt.transform(model._meta.get_field('point').srid, clone=True)
+ stx_pnt = self.stx_pnt.transform(
+ model._meta.get_field("point").srid, clone=True
+ )
qs = model.objects.filter(point__distance_gte=(stx_pnt, D(km=7))).filter(
point__distance_lte=(stx_pnt, D(km=20)),
)
cities = self.get_names(qs)
- self.assertEqual(cities, ['Bellaire', 'Pearland', 'West University Place'])
+ self.assertEqual(cities, ["Bellaire", "Pearland", "West University Place"])
# Doing a distance query using Polygons instead of a Point.
- z = SouthTexasZipcode.objects.get(name='77005')
- qs = SouthTexasZipcode.objects.exclude(name='77005').filter(poly__distance_lte=(z.poly, D(m=275)))
- self.assertEqual(['77025', '77401'], self.get_names(qs))
+ z = SouthTexasZipcode.objects.get(name="77005")
+ qs = SouthTexasZipcode.objects.exclude(name="77005").filter(
+ poly__distance_lte=(z.poly, D(m=275))
+ )
+ self.assertEqual(["77025", "77401"], self.get_names(qs))
# If we add a little more distance 77002 should be included.
- qs = SouthTexasZipcode.objects.exclude(name='77005').filter(poly__distance_lte=(z.poly, D(m=300)))
- self.assertEqual(['77002', '77025', '77401'], self.get_names(qs))
+ qs = SouthTexasZipcode.objects.exclude(name="77005").filter(
+ poly__distance_lte=(z.poly, D(m=300))
+ )
+ self.assertEqual(["77002", "77025", "77401"], self.get_names(qs))
@skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
def test_geodetic_distance_lookups(self):
@@ -130,12 +163,18 @@ class DistanceTest(TestCase):
"""
# Line is from Canberra to Sydney. Query is for all other cities within
# a 100km of that line (which should exclude only Hobart & Adelaide).
- line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)', 4326)
+ line = GEOSGeometry("LINESTRING(144.9630 -37.8143,151.2607 -33.8870)", 4326)
dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100)))
expected_cities = [
- 'Batemans Bay', 'Canberra', 'Hillsdale',
- 'Melbourne', 'Mittagong', 'Shellharbour',
- 'Sydney', 'Thirroul', 'Wollongong',
+ "Batemans Bay",
+ "Canberra",
+ "Hillsdale",
+ "Melbourne",
+ "Mittagong",
+ "Shellharbour",
+ "Sydney",
+ "Thirroul",
+ "Wollongong",
]
if connection.ops.spatialite:
# SpatiaLite is less accurate and returns 102.8km for Batemans Bay.
@@ -144,141 +183,185 @@ class DistanceTest(TestCase):
msg = "2, 3, or 4-element tuple required for 'distance_lte' lookup."
with self.assertRaisesMessage(ValueError, msg): # Too many params.
- len(AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)', D(km=100), 'spheroid', '4', None)))
+ len(
+ AustraliaCity.objects.filter(
+ point__distance_lte=(
+ "POINT(5 23)",
+ D(km=100),
+ "spheroid",
+ "4",
+ None,
+ )
+ )
+ )
with self.assertRaisesMessage(ValueError, msg): # Too few params.
- len(AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)',)))
+ len(AustraliaCity.objects.filter(point__distance_lte=("POINT(5 23)",)))
msg = "For 4-element tuples the last argument must be the 'spheroid' directive."
with self.assertRaisesMessage(ValueError, msg):
- len(AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)', D(km=100), 'spheroid', '4')))
+ len(
+ AustraliaCity.objects.filter(
+ point__distance_lte=("POINT(5 23)", D(km=100), "spheroid", "4")
+ )
+ )
# Getting all cities w/in 550 miles of Hobart.
- hobart = AustraliaCity.objects.get(name='Hobart')
- qs = AustraliaCity.objects.exclude(name='Hobart').filter(point__distance_lte=(hobart.point, D(mi=550)))
+ hobart = AustraliaCity.objects.get(name="Hobart")
+ qs = AustraliaCity.objects.exclude(name="Hobart").filter(
+ point__distance_lte=(hobart.point, D(mi=550))
+ )
cities = self.get_names(qs)
- self.assertEqual(cities, ['Batemans Bay', 'Canberra', 'Melbourne'])
+ self.assertEqual(cities, ["Batemans Bay", "Canberra", "Melbourne"])
# Cities that are either really close or really far from Wollongong --
# and using different units of distance.
- wollongong = AustraliaCity.objects.get(name='Wollongong')
+ wollongong = AustraliaCity.objects.get(name="Wollongong")
d1, d2 = D(yd=19500), D(nm=400) # Yards (~17km) & Nautical miles.
# Normal geodetic distance lookup (uses `distance_sphere` on PostGIS.
gq1 = Q(point__distance_lte=(wollongong.point, d1))
gq2 = Q(point__distance_gte=(wollongong.point, d2))
- qs1 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq1 | gq2)
+ qs1 = AustraliaCity.objects.exclude(name="Wollongong").filter(gq1 | gq2)
# Geodetic distance lookup but telling GeoDjango to use `distance_spheroid`
# instead (we should get the same results b/c accuracy variance won't matter
# in this test case).
querysets = [qs1]
if connection.features.has_DistanceSpheroid_function:
- gq3 = Q(point__distance_lte=(wollongong.point, d1, 'spheroid'))
- gq4 = Q(point__distance_gte=(wollongong.point, d2, 'spheroid'))
- qs2 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq3 | gq4)
+ gq3 = Q(point__distance_lte=(wollongong.point, d1, "spheroid"))
+ gq4 = Q(point__distance_gte=(wollongong.point, d2, "spheroid"))
+ qs2 = AustraliaCity.objects.exclude(name="Wollongong").filter(gq3 | gq4)
querysets.append(qs2)
for qs in querysets:
cities = self.get_names(qs)
- self.assertEqual(cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
+ self.assertEqual(cities, ["Adelaide", "Hobart", "Shellharbour", "Thirroul"])
@skipUnlessDBFeature("supports_distances_lookups")
def test_distance_lookups_with_expression_rhs(self):
- stx_pnt = self.stx_pnt.transform(SouthTexasCity._meta.get_field('point').srid, clone=True)
+ stx_pnt = self.stx_pnt.transform(
+ SouthTexasCity._meta.get_field("point").srid, clone=True
+ )
qs = SouthTexasCity.objects.filter(
- point__distance_lte=(stx_pnt, F('radius')),
- ).order_by('name')
+ point__distance_lte=(stx_pnt, F("radius")),
+ ).order_by("name")
self.assertEqual(
self.get_names(qs),
- ['Bellaire', 'Downtown Houston', 'Southside Place', 'West University Place']
+ [
+ "Bellaire",
+ "Downtown Houston",
+ "Southside Place",
+ "West University Place",
+ ],
)
# With a combined expression
qs = SouthTexasCity.objects.filter(
- point__distance_lte=(stx_pnt, F('radius') * 2),
- ).order_by('name')
+ point__distance_lte=(stx_pnt, F("radius") * 2),
+ ).order_by("name")
self.assertEqual(len(qs), 5)
- self.assertIn('Pearland', self.get_names(qs))
+ self.assertIn("Pearland", self.get_names(qs))
# With spheroid param
if connection.features.supports_distance_geodetic:
- hobart = AustraliaCity.objects.get(name='Hobart')
+ hobart = AustraliaCity.objects.get(name="Hobart")
AustraliaCity.objects.update(ref_point=hobart.point)
- for ref_point in [hobart.point, F('ref_point')]:
+ for ref_point in [hobart.point, F("ref_point")]:
qs = AustraliaCity.objects.filter(
- point__distance_lte=(ref_point, F('radius') * 70, 'spheroid'),
- ).order_by('name')
- self.assertEqual(self.get_names(qs), ['Canberra', 'Hobart', 'Melbourne'])
+ point__distance_lte=(ref_point, F("radius") * 70, "spheroid"),
+ ).order_by("name")
+ self.assertEqual(
+ self.get_names(qs), ["Canberra", "Hobart", "Melbourne"]
+ )
# With a complex geometry expression
- self.assertFalse(SouthTexasCity.objects.filter(point__distance_gt=(Union('point', 'point'), 0)))
+ self.assertFalse(
+ SouthTexasCity.objects.filter(
+ point__distance_gt=(Union("point", "point"), 0)
+ )
+ )
self.assertEqual(
- SouthTexasCity.objects.filter(point__distance_lte=(Union('point', 'point'), 0)).count(),
+ SouthTexasCity.objects.filter(
+ point__distance_lte=(Union("point", "point"), 0)
+ ).count(),
SouthTexasCity.objects.count(),
)
- @skipUnlessDBFeature('supports_distances_lookups')
+ @skipUnlessDBFeature("supports_distances_lookups")
def test_distance_annotation_group_by(self):
stx_pnt = self.stx_pnt.transform(
- SouthTexasCity._meta.get_field('point').srid,
+ SouthTexasCity._meta.get_field("point").srid,
clone=True,
)
- qs = SouthTexasCity.objects.annotate(
- relative_distance=Case(
- When(point__distance_lte=(stx_pnt, D(km=20)), then=Value(20)),
- default=Value(100),
- output_field=IntegerField(),
- ),
- ).values('relative_distance').annotate(count=Count('pk'))
- self.assertCountEqual(qs, [
- {'relative_distance': 20, 'count': 5},
- {'relative_distance': 100, 'count': 4},
- ])
+ qs = (
+ SouthTexasCity.objects.annotate(
+ relative_distance=Case(
+ When(point__distance_lte=(stx_pnt, D(km=20)), then=Value(20)),
+ default=Value(100),
+ output_field=IntegerField(),
+ ),
+ )
+ .values("relative_distance")
+ .annotate(count=Count("pk"))
+ )
+ self.assertCountEqual(
+ qs,
+ [
+ {"relative_distance": 20, "count": 5},
+ {"relative_distance": 100, "count": 4},
+ ],
+ )
def test_mysql_geodetic_distance_error(self):
if not connection.ops.mysql:
- self.skipTest('This is a MySQL-specific test.')
- msg = 'Only numeric values of degree units are allowed on geodetic distance queries.'
+ self.skipTest("This is a MySQL-specific test.")
+ msg = "Only numeric values of degree units are allowed on geodetic distance queries."
with self.assertRaisesMessage(ValueError, msg):
- AustraliaCity.objects.filter(point__distance_lte=(Point(0, 0), D(m=100))).exists()
+ AustraliaCity.objects.filter(
+ point__distance_lte=(Point(0, 0), D(m=100))
+ ).exists()
- @skipUnlessDBFeature('supports_dwithin_lookup')
+ @skipUnlessDBFeature("supports_dwithin_lookup")
def test_dwithin_subquery(self):
"""dwithin lookup in a subquery using OuterRef as a parameter."""
qs = CensusZipcode.objects.annotate(
- annotated_value=Exists(SouthTexasCity.objects.filter(
- point__dwithin=(OuterRef('poly'), D(m=10)),
- ))
+ annotated_value=Exists(
+ SouthTexasCity.objects.filter(
+ point__dwithin=(OuterRef("poly"), D(m=10)),
+ )
+ )
).filter(annotated_value=True)
- self.assertEqual(self.get_names(qs), ['77002', '77025', '77401'])
+ self.assertEqual(self.get_names(qs), ["77002", "77025", "77401"])
- @skipUnlessDBFeature('supports_dwithin_lookup', 'supports_dwithin_distance_expr')
+ @skipUnlessDBFeature("supports_dwithin_lookup", "supports_dwithin_distance_expr")
def test_dwithin_with_expression_rhs(self):
# LineString of Wollongong and Adelaide coords.
ls = LineString(((150.902, -34.4245), (138.6, -34.9258)), srid=4326)
qs = AustraliaCity.objects.filter(
- point__dwithin=(ls, F('allowed_distance')),
- ).order_by('name')
+ point__dwithin=(ls, F("allowed_distance")),
+ ).order_by("name")
self.assertEqual(
self.get_names(qs),
- ['Adelaide', 'Mittagong', 'Shellharbour', 'Thirroul', 'Wollongong'],
+ ["Adelaide", "Mittagong", "Shellharbour", "Thirroul", "Wollongong"],
)
- @skipIfDBFeature('supports_dwithin_distance_expr')
+ @skipIfDBFeature("supports_dwithin_distance_expr")
def test_dwithin_with_expression_rhs_not_supported(self):
ls = LineString(((150.902, -34.4245), (138.6, -34.9258)), srid=4326)
msg = (
- 'This backend does not support expressions for specifying '
- 'distance in the dwithin lookup.'
+ "This backend does not support expressions for specifying "
+ "distance in the dwithin lookup."
)
with self.assertRaisesMessage(NotSupportedError, msg):
- list(AustraliaCity.objects.filter(
- point__dwithin=(ls, F('allowed_distance')),
- ))
+ list(
+ AustraliaCity.objects.filter(
+ point__dwithin=(ls, F("allowed_distance")),
+ )
+ )
-'''
+"""
=============================
Distance functions on PostGIS
=============================
@@ -310,20 +393,27 @@ ST_Distance(geom1, geom2, use_ellipsoid=False) | N/A | OK (
Perimeter(geom1) | OK | :-( (degrees)
-''' # NOQA
+""" # NOQA
class DistanceFunctionsTests(FuncTestMixin, TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
@skipUnlessDBFeature("has_Area_function")
def test_area(self):
# Reference queries:
# SELECT ST_Area(poly) FROM distapp_southtexaszipcode;
- area_sq_m = [5437908.90234375, 10183031.4389648, 11254471.0073242, 9881708.91772461]
+ 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.annotate(area=Area('poly')).order_by('name')):
+ for i, z in enumerate(
+ SouthTexasZipcode.objects.annotate(area=Area("poly")).order_by("name")
+ ):
self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
@skipUnlessDBFeature("has_Distance_function")
@@ -332,14 +422,14 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
Test a simple distance query, with projected coordinates and without
transformation.
"""
- lagrange = GEOSGeometry('POINT(805066.295722839 4231496.29461335)', 32140)
- houston = SouthTexasCity.objects.annotate(dist=Distance('point', lagrange)).order_by('id').first()
- tol = 2 if connection.ops.oracle else 5
- self.assertAlmostEqual(
- houston.dist.m,
- 147075.069813,
- tol
+ lagrange = GEOSGeometry("POINT(805066.295722839 4231496.29461335)", 32140)
+ houston = (
+ SouthTexasCity.objects.annotate(dist=Distance("point", lagrange))
+ .order_by("id")
+ .first()
)
+ tol = 2 if connection.ops.oracle else 5
+ self.assertAlmostEqual(houston.dist.m, 147075.069813, tol)
@skipUnlessDBFeature("has_Distance_function", "has_Transform_function")
def test_distance_projected(self):
@@ -347,24 +437,44 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
Test the `Distance` function on projected coordinate systems.
"""
# The point for La Grange, TX
- lagrange = GEOSGeometry('POINT(-96.876369 29.905320)', 4326)
+ 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]
+ 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;
- ft_distances = [482528.79154625, 458103.408123001, 462231.860397575,
- 455411.438904354, 519386.252102563, 696139.009211594,
- 232513.278304279, 542445.630586414, 456679.155883207]
+ 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.annotate(distance=Distance('point', lagrange)).order_by('id')
- dist2 = SouthTexasCityFt.objects.annotate(distance=Distance('point', lagrange)).order_by('id')
+ dist1 = SouthTexasCity.objects.annotate(
+ distance=Distance("point", lagrange)
+ ).order_by("id")
+ dist2 = SouthTexasCityFt.objects.annotate(
+ distance=Distance("point", lagrange)
+ ).order_by("id")
dist_qs = [dist1, dist2]
# Ensuring expected distances are returned for each distance queryset.
@@ -386,10 +496,22 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
# 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.annotate(distance=Distance('point', ls)).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.annotate(distance=Distance("point", ls)).order_by(
+ "name"
+ )
for city, distance in zip(qs, distances):
with self.subTest(city=city, distance=distance):
# Testing equivalence to within a meter (kilometer on SpatiaLite).
@@ -406,30 +528,46 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
# 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,
+ 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,
+ 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).annotate(
- distance=Distance('point', hillsdale.point, spheroid=True)
- ).order_by('id')
+ hillsdale = AustraliaCity.objects.get(name="Hillsdale")
+ qs = (
+ AustraliaCity.objects.exclude(id=hillsdale.id)
+ .annotate(distance=Distance("point", hillsdale.point, spheroid=True))
+ .order_by("id")
+ )
for i, c in enumerate(qs):
with self.subTest(c=c):
self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol)
if connection.ops.postgis or connection.ops.spatialite:
# PostGIS uses sphere-only distances by default, testing these as well.
- qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate(
- distance=Distance('point', hillsdale.point)
- ).order_by('id')
+ qs = (
+ AustraliaCity.objects.exclude(id=hillsdale.id)
+ .annotate(distance=Distance("point", hillsdale.point))
+ .order_by("id")
+ )
for i, c in enumerate(qs):
with self.subTest(c=c):
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
@@ -437,9 +575,13 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
@skipIfDBFeature("supports_distance_geodetic")
@skipUnlessDBFeature("has_Distance_function")
def test_distance_function_raw_result(self):
- distance = Interstate.objects.annotate(
- d=Distance(Point(0, 0, srid=4326), Point(0, 1, srid=4326)),
- ).first().d
+ distance = (
+ Interstate.objects.annotate(
+ d=Distance(Point(0, 0, srid=4326), Point(0, 1, srid=4326)),
+ )
+ .first()
+ .d
+ )
self.assertEqual(distance, 1)
@skipUnlessDBFeature("has_Distance_function")
@@ -449,29 +591,37 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
).filter(d=D(m=1))
self.assertTrue(qs.exists())
- @skipUnlessDBFeature('supports_tolerance_parameter')
+ @skipUnlessDBFeature("supports_tolerance_parameter")
def test_distance_function_tolerance_escaping(self):
- qs = Interstate.objects.annotate(
- d=Distance(
- Point(500, 500, srid=3857),
- Point(0, 0, srid=3857),
- tolerance='0.05) = 1 OR 1=1 OR (1+1',
- ),
- ).filter(d=D(m=1)).values('pk')
- msg = 'The tolerance parameter has the wrong type'
+ qs = (
+ Interstate.objects.annotate(
+ d=Distance(
+ Point(500, 500, srid=3857),
+ Point(0, 0, srid=3857),
+ tolerance="0.05) = 1 OR 1=1 OR (1+1",
+ ),
+ )
+ .filter(d=D(m=1))
+ .values("pk")
+ )
+ msg = "The tolerance parameter has the wrong type"
with self.assertRaisesMessage(TypeError, msg):
qs.exists()
- @skipUnlessDBFeature('supports_tolerance_parameter')
+ @skipUnlessDBFeature("supports_tolerance_parameter")
def test_distance_function_tolerance(self):
# Tolerance is greater than distance.
- qs = Interstate.objects.annotate(
- d=Distance(
- Point(0, 0, srid=3857),
- Point(1, 1, srid=3857),
- tolerance=1.5,
- ),
- ).filter(d=0).values('pk')
+ qs = (
+ Interstate.objects.annotate(
+ d=Distance(
+ Point(0, 0, srid=3857),
+ Point(1, 1, srid=3857),
+ tolerance=1.5,
+ ),
+ )
+ .filter(d=0)
+ .values("pk")
+ )
self.assertIs(qs.exists(), True)
@skipIfDBFeature("supports_distance_geodetic")
@@ -480,11 +630,11 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
qs = Interstate.objects.annotate(
d=Distance(Point(0, 0, srid=4326), Point(0, 1, srid=4326)),
).filter(d=D(m=1))
- msg = 'Distance measure is supplied, but units are unknown for result.'
+ msg = "Distance measure is supplied, but units are unknown for result."
with self.assertRaisesMessage(ValueError, msg):
list(qs)
- @skipUnlessDBFeature("has_Distance_function", 'has_Transform_function')
+ @skipUnlessDBFeature("has_Distance_function", "has_Transform_function")
def test_distance_transform(self):
"""
Test the `Distance` function used with `Transform` on a geographic field.
@@ -493,7 +643,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
# 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')
+ z = SouthTexasZipcode.objects.get(name="77005")
# Reference query:
# SELECT ST_Distance(ST_Transform("distapp_censuszipcode"."poly", 32140),
@@ -508,22 +658,29 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
# however.
buf1 = z.poly.centroid.buffer(100)
buf2 = buf1.transform(4269, clone=True)
- ref_zips = ['77002', '77025', '77401']
+ ref_zips = ["77002", "77025", "77401"]
for buf in [buf1, buf2]:
- qs = CensusZipcode.objects.exclude(name='77005').annotate(
- distance=Distance(Transform('poly', 32140), buf)
- ).order_by('name')
+ qs = (
+ CensusZipcode.objects.exclude(name="77005")
+ .annotate(distance=Distance(Transform("poly", 32140), buf))
+ .order_by("name")
+ )
self.assertEqual(ref_zips, sorted(c.name for c in qs))
for i, z in enumerate(qs):
self.assertAlmostEqual(z.distance.m, dists_m[i], 5)
@skipUnlessDBFeature("has_Distance_function")
def test_distance_order_by(self):
- qs = SouthTexasCity.objects.annotate(distance=Distance('point', Point(3, 3, srid=32140))).order_by(
- 'distance'
- ).values_list('name', flat=True).filter(name__in=('San Antonio', 'Pearland'))
- self.assertSequenceEqual(qs, ['San Antonio', 'Pearland'])
+ qs = (
+ SouthTexasCity.objects.annotate(
+ distance=Distance("point", Point(3, 3, srid=32140))
+ )
+ .order_by("distance")
+ .values_list("name", flat=True)
+ .filter(name__in=("San Antonio", "Pearland"))
+ )
+ self.assertSequenceEqual(qs, ["San Antonio", "Pearland"])
@skipUnlessDBFeature("has_Length_function")
def test_length(self):
@@ -537,20 +694,24 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
len_m2 = 4617.668
if connection.features.supports_length_geodetic:
- qs = Interstate.objects.annotate(length=Length('path'))
+ qs = Interstate.objects.annotate(length=Length("path"))
tol = 2 if connection.ops.oracle else 3
self.assertAlmostEqual(len_m1, qs[0].length.m, tol)
# TODO: test with spheroid argument (True and False)
else:
# Does not support geodetic coordinate systems.
with self.assertRaises(NotSupportedError):
- list(Interstate.objects.annotate(length=Length('path')))
+ list(Interstate.objects.annotate(length=Length("path")))
# Now doing length on a projected coordinate system.
- i10 = SouthTexasInterstate.objects.annotate(length=Length('path')).get(name='I-10')
+ i10 = SouthTexasInterstate.objects.annotate(length=Length("path")).get(
+ name="I-10"
+ )
self.assertAlmostEqual(len_m2, i10.length.m, 2)
self.assertTrue(
- SouthTexasInterstate.objects.annotate(length=Length('path')).filter(length__gt=4000).exists()
+ 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))
@@ -563,14 +724,21 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
"""
# Reference query:
# SELECT ST_Perimeter(distapp_southtexaszipcode.poly) FROM distapp_southtexaszipcode;
- perim_m = [18404.3550889361, 15627.2108551001, 20632.5588368978, 17094.5996143697]
+ perim_m = [
+ 18404.3550889361,
+ 15627.2108551001,
+ 20632.5588368978,
+ 17094.5996143697,
+ ]
tol = 2 if connection.ops.oracle else 7
- qs = SouthTexasZipcode.objects.annotate(perimeter=Perimeter('poly')).order_by('name')
+ qs = SouthTexasZipcode.objects.annotate(perimeter=Perimeter("poly")).order_by(
+ "name"
+ )
for i, z in enumerate(qs):
self.assertAlmostEqual(perim_m[i], z.perimeter.m, tol)
# Running on points; should return 0.
- qs = SouthTexasCity.objects.annotate(perim=Perimeter('point'))
+ qs = SouthTexasCity.objects.annotate(perim=Perimeter("point"))
for city in qs:
self.assertEqual(0, city.perim.m)
@@ -578,28 +746,32 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
def test_perimeter_geodetic(self):
# Currently only Oracle supports calculating the perimeter on geodetic
# geometries (without being transformed).
- qs1 = CensusZipcode.objects.annotate(perim=Perimeter('poly'))
+ qs1 = CensusZipcode.objects.annotate(perim=Perimeter("poly"))
if connection.features.supports_perimeter_geodetic:
self.assertAlmostEqual(qs1[0].perim.m, 18406.3818954314, 3)
else:
with self.assertRaises(NotSupportedError):
list(qs1)
# But should work fine when transformed to projected coordinates
- qs2 = CensusZipcode.objects.annotate(perim=Perimeter(Transform('poly', 32140))).filter(name='77002')
+ qs2 = CensusZipcode.objects.annotate(
+ perim=Perimeter(Transform("poly", 32140))
+ ).filter(name="77002")
self.assertAlmostEqual(qs2[0].perim.m, 18404.355, 3)
- @skipUnlessDBFeature("supports_null_geometries", "has_Area_function", "has_Distance_function")
+ @skipUnlessDBFeature(
+ "supports_null_geometries", "has_Area_function", "has_Distance_function"
+ )
def test_measurement_null_fields(self):
"""
Test the measurement functions on fields with NULL values.
"""
# Creating SouthTexasZipcode w/NULL value.
- SouthTexasZipcode.objects.create(name='78212')
+ 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')
+ htown = SouthTexasCity.objects.get(name="Downtown Houston")
z = SouthTexasZipcode.objects.annotate(
- distance=Distance('poly', htown.point), area=Area('poly')
- ).get(name='78212')
+ distance=Distance("poly", htown.point), area=Area("poly")
+ ).get(name="78212")
self.assertIsNone(z.distance)
self.assertIsNone(z.area)
diff --git a/tests/gis_tests/gdal_tests/test_driver.py b/tests/gis_tests/gdal_tests/test_driver.py
index c2dcc80d65..e7c03ae98d 100644
--- a/tests/gis_tests/gdal_tests/test_driver.py
+++ b/tests/gis_tests/gdal_tests/test_driver.py
@@ -5,28 +5,37 @@ from django.contrib.gis.gdal import Driver, GDALException
valid_drivers = (
# vector
- 'ESRI Shapefile', 'MapInfo File', 'TIGER', 'S57', 'DGN', 'Memory', 'CSV',
- 'GML', 'KML',
+ "ESRI Shapefile",
+ "MapInfo File",
+ "TIGER",
+ "S57",
+ "DGN",
+ "Memory",
+ "CSV",
+ "GML",
+ "KML",
# raster
- 'GTiff', 'JPEG', 'MEM', 'PNG',
+ "GTiff",
+ "JPEG",
+ "MEM",
+ "PNG",
)
-invalid_drivers = ('Foo baz', 'clucka', 'ESRI Shp', 'ESRI rast')
+invalid_drivers = ("Foo baz", "clucka", "ESRI Shp", "ESRI rast")
aliases = {
- 'eSrI': 'ESRI Shapefile',
- 'TigER/linE': 'TIGER',
- 'SHAPE': 'ESRI Shapefile',
- 'sHp': 'ESRI Shapefile',
- 'tiFf': 'GTiff',
- 'tIf': 'GTiff',
- 'jPEg': 'JPEG',
- 'jpG': 'JPEG',
+ "eSrI": "ESRI Shapefile",
+ "TigER/linE": "TIGER",
+ "SHAPE": "ESRI Shapefile",
+ "sHp": "ESRI Shapefile",
+ "tiFf": "GTiff",
+ "tIf": "GTiff",
+ "jPEg": "JPEG",
+ "jpG": "JPEG",
}
class DriverTest(unittest.TestCase):
-
def test01_valid_driver(self):
"Testing valid GDAL/OGR Data Source Drivers."
for d in valid_drivers:
@@ -45,15 +54,16 @@ class DriverTest(unittest.TestCase):
dr = Driver(alias)
self.assertEqual(full_name, str(dr))
- @mock.patch('django.contrib.gis.gdal.driver.vcapi.get_driver_count')
- @mock.patch('django.contrib.gis.gdal.driver.rcapi.get_driver_count')
- @mock.patch('django.contrib.gis.gdal.driver.vcapi.register_all')
- @mock.patch('django.contrib.gis.gdal.driver.rcapi.register_all')
+ @mock.patch("django.contrib.gis.gdal.driver.vcapi.get_driver_count")
+ @mock.patch("django.contrib.gis.gdal.driver.rcapi.get_driver_count")
+ @mock.patch("django.contrib.gis.gdal.driver.vcapi.register_all")
+ @mock.patch("django.contrib.gis.gdal.driver.rcapi.register_all")
def test_registered(self, rreg, vreg, rcount, vcount):
"""
Prototypes are registered only if their respective driver counts are
zero.
"""
+
def check(rcount_val, vcount_val):
vreg.reset_mock()
rreg.reset_mock()
diff --git a/tests/gis_tests/gdal_tests/test_ds.py b/tests/gis_tests/gdal_tests/test_ds.py
index 2632e817b4..fae11cfea9 100644
--- a/tests/gis_tests/gdal_tests/test_ds.py
+++ b/tests/gis_tests/gdal_tests/test_ds.py
@@ -3,12 +3,8 @@ import re
from datetime import datetime
from pathlib import Path
-from django.contrib.gis.gdal import (
- DataSource, Envelope, GDALException, OGRGeometry,
-)
-from django.contrib.gis.gdal.field import (
- OFTDateTime, OFTInteger, OFTReal, OFTString,
-)
+from django.contrib.gis.gdal import DataSource, Envelope, GDALException, OGRGeometry
+from django.contrib.gis.gdal.field import OFTDateTime, OFTInteger, OFTReal, OFTString
from django.contrib.gis.geos import GEOSGeometry
from django.test import SimpleTestCase
@@ -17,87 +13,105 @@ from ..test_data import TEST_DATA, TestDS, get_ds_file
wgs_84_wkt = (
'GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",'
'6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",'
- '0.017453292519943295]]'
+ "0.017453292519943295]]"
)
# Using a regex because of small differences depending on GDAL versions.
wgs_84_wkt_regex = r'^GEOGCS\["(GCS_)?WGS[ _](19)?84".*$'
-datetime_format = '%Y-%m-%dT%H:%M:%S'
+datetime_format = "%Y-%m-%dT%H:%M:%S"
# List of acceptable data sources.
ds_list = (
TestDS(
- 'test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='ESRI Shapefile',
- fields={'dbl': OFTReal, 'int': OFTInteger, 'str': OFTString},
+ "test_point",
+ nfeat=5,
+ nfld=3,
+ geom="POINT",
+ gtype=1,
+ driver="ESRI Shapefile",
+ fields={"dbl": OFTReal, "int": OFTInteger, "str": OFTString},
extent=(-1.35011, 0.166623, -0.524093, 0.824508), # Got extent from QGIS
srs_wkt=wgs_84_wkt,
field_values={
- 'dbl': [float(i) for i in range(1, 6)],
- 'int': list(range(1, 6)),
- 'str': [str(i) for i in range(1, 6)],
+ "dbl": [float(i) for i in range(1, 6)],
+ "int": list(range(1, 6)),
+ "str": [str(i) for i in range(1, 6)],
},
- fids=range(5)
+ fids=range(5),
),
TestDS(
- 'test_vrt', ext='vrt', nfeat=3, nfld=3, geom='POINT', gtype='Point25D',
- driver='OGR_VRT',
+ "test_vrt",
+ ext="vrt",
+ nfeat=3,
+ nfld=3,
+ geom="POINT",
+ gtype="Point25D",
+ driver="OGR_VRT",
fields={
- 'POINT_X': OFTString,
- 'POINT_Y': OFTString,
- 'NUM': OFTString,
+ "POINT_X": OFTString,
+ "POINT_Y": OFTString,
+ "NUM": OFTString,
}, # VRT uses CSV, which all types are OFTString.
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'],
+ "POINT_X": ["1.0", "5.0", "100.0"],
+ "POINT_Y": ["2.0", "23.0", "523.5"],
+ "NUM": ["5", "17", "23"],
},
- fids=range(1, 4)
+ fids=range(1, 4),
),
TestDS(
- 'test_poly', nfeat=3, nfld=3, geom='POLYGON', gtype=3,
- driver='ESRI Shapefile',
- fields={'float': OFTReal, 'int': OFTInteger, 'str': OFTString},
+ "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
srs_wkt=wgs_84_wkt,
),
TestDS(
- 'has_nulls', nfeat=3, nfld=6, geom='POLYGON', gtype=3,
- driver='GeoJSON', ext='geojson',
+ "has_nulls",
+ nfeat=3,
+ nfld=6,
+ geom="POLYGON",
+ gtype=3,
+ driver="GeoJSON",
+ ext="geojson",
fields={
- 'uuid': OFTString,
- 'name': OFTString,
- 'num': OFTReal,
- 'integer': OFTInteger,
- 'datetime': OFTDateTime,
- 'boolean': OFTInteger,
+ "uuid": OFTString,
+ "name": OFTString,
+ "num": OFTReal,
+ "integer": OFTInteger,
+ "datetime": OFTDateTime,
+ "boolean": OFTInteger,
},
extent=(-75.274200, 39.846504, -74.959717, 40.119040), # Got extent from QGIS
field_values={
- 'uuid': [
- '1378c26f-cbe6-44b0-929f-eb330d4991f5',
- 'fa2ba67c-a135-4338-b924-a9622b5d869f',
- '4494c1f3-55ab-4256-b365-12115cb388d5',
+ "uuid": [
+ "1378c26f-cbe6-44b0-929f-eb330d4991f5",
+ "fa2ba67c-a135-4338-b924-a9622b5d869f",
+ "4494c1f3-55ab-4256-b365-12115cb388d5",
],
- 'name': ['Philadelphia', None, 'north'],
- 'num': [1.001, None, 0.0],
- 'integer': [5, None, 8],
- 'boolean': [True, None, False],
- 'datetime': [
- datetime.strptime('1994-08-14T11:32:14', datetime_format),
+ "name": ["Philadelphia", None, "north"],
+ "num": [1.001, None, 0.0],
+ "integer": [5, None, 8],
+ "boolean": [True, None, False],
+ "datetime": [
+ datetime.strptime("1994-08-14T11:32:14", datetime_format),
None,
- datetime.strptime('2018-11-29T03:02:52', datetime_format),
- ]
+ datetime.strptime("2018-11-29T03:02:52", datetime_format),
+ ],
},
fids=range(3),
),
)
-bad_ds = (TestDS('foo'),)
+bad_ds = (TestDS("foo"),)
class DataSourceTest(SimpleTestCase):
-
def test01_valid_shp(self):
"Testing valid SHP Data Source files."
@@ -115,15 +129,17 @@ class DataSourceTest(SimpleTestCase):
self.assertEqual(source.driver, str(ds.driver))
# Making sure indexing works
- msg = 'Index out of range when accessing layers in a datasource: %s.'
+ msg = "Index out of range when accessing layers in a datasource: %s."
with self.assertRaisesMessage(IndexError, msg % len(ds)):
ds.__getitem__(len(ds))
- with self.assertRaisesMessage(IndexError, 'Invalid OGR layer name given: invalid.'):
- ds.__getitem__('invalid')
+ with self.assertRaisesMessage(
+ IndexError, "Invalid OGR layer name given: invalid."
+ ):
+ ds.__getitem__("invalid")
def test_ds_input_pathlib(self):
- test_shp = Path(get_ds_file('test_point', 'shp'))
+ test_shp = Path(get_ds_file("test_point", "shp"))
ds = DataSource(test_shp)
self.assertEqual(len(ds), 1)
@@ -162,12 +178,14 @@ class DataSourceTest(SimpleTestCase):
self.assertIn(f, source.fields)
# Negative FIDs are not allowed.
- with self.assertRaisesMessage(IndexError, 'Negative indices are not allowed on OGR Layers.'):
+ with self.assertRaisesMessage(
+ IndexError, "Negative indices are not allowed on OGR Layers."
+ ):
layer.__getitem__(-1)
- with self.assertRaisesMessage(IndexError, 'Invalid feature id: 50000.'):
+ with self.assertRaisesMessage(IndexError, "Invalid feature id: 50000."):
layer.__getitem__(50000)
- if hasattr(source, 'field_values'):
+ if hasattr(source, "field_values"):
# Testing `Layer.get_fields` (which uses Layer.__iter__)
for fld_name, fld_value in source.field_values.items():
self.assertEqual(fld_value, layer.get_fields(fld_name))
@@ -181,12 +199,16 @@ class DataSourceTest(SimpleTestCase):
for fld_name, fld_value in source.field_values.items():
self.assertEqual(fld_value[i], feat.get(fld_name))
- msg = 'Index out of range when accessing field in a feature: %s.'
+ msg = (
+ "Index out of range when accessing field in a feature: %s."
+ )
with self.assertRaisesMessage(IndexError, msg % len(feat)):
feat.__getitem__(len(feat))
- with self.assertRaisesMessage(IndexError, 'Invalid OFT field name given: invalid.'):
- feat.__getitem__('invalid')
+ with self.assertRaisesMessage(
+ IndexError, "Invalid OFT field name given: invalid."
+ ):
+ feat.__getitem__("invalid")
def test03b_layer_slice(self):
"Test indexing and slicing on Layers."
@@ -223,7 +245,7 @@ class DataSourceTest(SimpleTestCase):
self.assertEqual(source.gtype, lyr.geom_type.num)
# Same issue for Feature/Field objects, see #18640
- self.assertEqual(str(lyr[0]['str']), "1")
+ self.assertEqual(str(lyr[0]["str"]), "1")
def test04_features(self):
"Testing Data Source Features."
@@ -271,12 +293,12 @@ class DataSourceTest(SimpleTestCase):
self.assertEqual(source.gtype, g.geom_type)
# Making sure the SpatialReference is as expected.
- if hasattr(source, 'srs_wkt'):
+ if hasattr(source, "srs_wkt"):
self.assertIsNotNone(re.match(wgs_84_wkt_regex, g.srs.wkt))
def test06_spatial_filter(self):
"Testing the Layer.spatial_filter property."
- ds = DataSource(get_ds_file('cities', 'shp'))
+ ds = DataSource(get_ds_file("cities", "shp"))
lyr = ds[0]
# When not set, it should be None.
@@ -284,7 +306,7 @@ class DataSourceTest(SimpleTestCase):
# Must be set a/an OGRGeometry or 4-tuple.
with self.assertRaises(TypeError):
- lyr._set_spatial_filter('foo')
+ lyr._set_spatial_filter("foo")
# Setting the spatial filter with a tuple/list with the extent of
# a buffer centering around Pueblo.
@@ -295,19 +317,19 @@ class DataSourceTest(SimpleTestCase):
self.assertEqual(OGRGeometry.from_bbox(filter_extent), lyr.spatial_filter)
feats = [feat for feat in lyr]
self.assertEqual(1, len(feats))
- self.assertEqual('Pueblo', feats[0].get('Name'))
+ self.assertEqual("Pueblo", feats[0].get("Name"))
# Setting the spatial filter with an OGRGeometry for buffer centering
# around Houston.
filter_geom = OGRGeometry(
- 'POLYGON((-96.363151 28.763374,-94.363151 28.763374,'
- '-94.363151 30.763374,-96.363151 30.763374,-96.363151 28.763374))'
+ "POLYGON((-96.363151 28.763374,-94.363151 28.763374,"
+ "-94.363151 30.763374,-96.363151 30.763374,-96.363151 28.763374))"
)
lyr.spatial_filter = filter_geom
self.assertEqual(filter_geom, lyr.spatial_filter)
feats = [feat for feat in lyr]
self.assertEqual(1, len(feats))
- self.assertEqual('Houston', feats[0].get('Name'))
+ self.assertEqual("Houston", feats[0].get("Name"))
# Clearing the spatial filter by setting it to None. Now
# should indicate that there are 3 features in the Layer.
@@ -319,14 +341,14 @@ class DataSourceTest(SimpleTestCase):
# Using *.dbf from Census 2010 TIGER Shapefile for Texas,
# which has land area ('ALAND10') stored in a Real field
# with no precision.
- ds = DataSource(os.path.join(TEST_DATA, 'texas.dbf'))
+ ds = DataSource(os.path.join(TEST_DATA, "texas.dbf"))
feat = ds[0][0]
# Reference value obtained using `ogrinfo`.
- self.assertEqual(676586997978, feat.get('ALAND10'))
+ self.assertEqual(676586997978, feat.get("ALAND10"))
def test_nonexistent_field(self):
source = ds_list[0]
ds = DataSource(source.ds)
- msg = 'invalid field name: nonexistent'
+ msg = "invalid field name: nonexistent"
with self.assertRaisesMessage(GDALException, msg):
- ds[0].get_fields('nonexistent')
+ ds[0].get_fields("nonexistent")
diff --git a/tests/gis_tests/gdal_tests/test_envelope.py b/tests/gis_tests/gdal_tests/test_envelope.py
index c414bea533..d55aae168b 100644
--- a/tests/gis_tests/gdal_tests/test_envelope.py
+++ b/tests/gis_tests/gdal_tests/test_envelope.py
@@ -10,7 +10,6 @@ class TestPoint:
class EnvelopeTest(unittest.TestCase):
-
def setUp(self):
self.e = Envelope(0, 0, 5, 5)
@@ -18,7 +17,7 @@ class EnvelopeTest(unittest.TestCase):
"Testing Envelope initialization."
e1 = Envelope((0, 0, 5, 5))
Envelope(0, 0, 5, 5)
- Envelope(0, '0', '5', 5) # Thanks to ww for this
+ Envelope(0, "0", "5", 5) # Thanks to ww for this
Envelope(e1._envelope)
with self.assertRaises(GDALException):
Envelope((5, 5, 0, 0))
@@ -29,9 +28,9 @@ class EnvelopeTest(unittest.TestCase):
with self.assertRaises(GDALException):
Envelope(())
with self.assertRaises(ValueError):
- Envelope(0, 'a', 5, 5)
+ Envelope(0, "a", 5, 5)
with self.assertRaises(TypeError):
- Envelope('foo')
+ Envelope("foo")
with self.assertRaises(GDALException):
Envelope((1, 1, 0, 0))
# Shouldn't raise an exception for min_x == max_x or min_y == max_y
@@ -47,8 +46,8 @@ class EnvelopeTest(unittest.TestCase):
self.assertEqual((0, 0), e.ll)
self.assertEqual((2, 3), e.ur)
self.assertEqual((0, 0, 2, 3), e.tuple)
- self.assertEqual('POLYGON((0.0 0.0,0.0 3.0,2.0 3.0,2.0 0.0,0.0 0.0))', e.wkt)
- self.assertEqual('(0.0, 0.0, 2.0, 3.0)', str(e))
+ self.assertEqual("POLYGON((0.0 0.0,0.0 3.0,2.0 3.0,2.0 0.0,0.0 0.0))", e.wkt)
+ self.assertEqual("(0.0, 0.0, 2.0, 3.0)", str(e))
def test03_equivalence(self):
"Testing Envelope equivalence."
diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py
index 68f43e2404..cb4588450c 100644
--- a/tests/gis_tests/gdal_tests/test_geom.py
+++ b/tests/gis_tests/gdal_tests/test_geom.py
@@ -2,7 +2,11 @@ import json
import pickle
from django.contrib.gis.gdal import (
- CoordTransform, GDALException, OGRGeometry, OGRGeomType, SpatialReference,
+ CoordTransform,
+ GDALException,
+ OGRGeometry,
+ OGRGeomType,
+ SpatialReference,
)
from django.template import Context
from django.template.engine import Engine
@@ -20,46 +24,48 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
# OGRGeomType should initialize on all these inputs.
OGRGeomType(1)
OGRGeomType(7)
- OGRGeomType('point')
- OGRGeomType('GeometrycollectioN')
- OGRGeomType('LINearrING')
- OGRGeomType('Unknown')
+ OGRGeomType("point")
+ OGRGeomType("GeometrycollectioN")
+ OGRGeomType("LINearrING")
+ OGRGeomType("Unknown")
# Should throw TypeError on this input
with self.assertRaises(GDALException):
OGRGeomType(23)
with self.assertRaises(GDALException):
- OGRGeomType('fooD')
+ OGRGeomType("fooD")
with self.assertRaises(GDALException):
OGRGeomType(9)
# Equivalence can take strings, ints, and other OGRGeomTypes
self.assertEqual(OGRGeomType(1), OGRGeomType(1))
- self.assertEqual(OGRGeomType(7), 'GeometryCollection')
- self.assertEqual(OGRGeomType('point'), 'POINT')
- self.assertNotEqual(OGRGeomType('point'), 2)
- self.assertEqual(OGRGeomType('unknown'), 0)
- self.assertEqual(OGRGeomType(6), 'MULtiPolyGON')
- self.assertEqual(OGRGeomType(1), OGRGeomType('point'))
- self.assertNotEqual(OGRGeomType('POINT'), OGRGeomType(6))
+ self.assertEqual(OGRGeomType(7), "GeometryCollection")
+ self.assertEqual(OGRGeomType("point"), "POINT")
+ self.assertNotEqual(OGRGeomType("point"), 2)
+ self.assertEqual(OGRGeomType("unknown"), 0)
+ self.assertEqual(OGRGeomType(6), "MULtiPolyGON")
+ self.assertEqual(OGRGeomType(1), OGRGeomType("point"))
+ self.assertNotEqual(OGRGeomType("POINT"), OGRGeomType(6))
# Testing the Django field name equivalent property.
- self.assertEqual('PointField', OGRGeomType('Point').django)
- self.assertEqual('GeometryField', OGRGeomType('Geometry').django)
- self.assertEqual('GeometryField', OGRGeomType('Unknown').django)
- self.assertIsNone(OGRGeomType('none').django)
+ self.assertEqual("PointField", OGRGeomType("Point").django)
+ self.assertEqual("GeometryField", OGRGeomType("Geometry").django)
+ self.assertEqual("GeometryField", OGRGeomType("Unknown").django)
+ self.assertIsNone(OGRGeomType("none").django)
# 'Geometry' initialization implies an unknown geometry type.
- gt = OGRGeomType('Geometry')
+ gt = OGRGeomType("Geometry")
self.assertEqual(0, gt.num)
- self.assertEqual('Unknown', gt.name)
+ self.assertEqual("Unknown", gt.name)
def test_geomtype_25d(self):
"Testing OGRGeomType object with 25D types."
wkb25bit = OGRGeomType.wkb25bit
- self.assertEqual(OGRGeomType(wkb25bit + 1), 'Point25D')
- self.assertEqual(OGRGeomType('MultiLineString25D'), (5 + wkb25bit))
- self.assertEqual('GeometryCollectionField', OGRGeomType('GeometryCollection25D').django)
+ self.assertEqual(OGRGeomType(wkb25bit + 1), "Point25D")
+ self.assertEqual(OGRGeomType("MultiLineString25D"), (5 + wkb25bit))
+ self.assertEqual(
+ "GeometryCollectionField", OGRGeomType("GeometryCollection25D").django
+ )
def test_wkt(self):
"Testing WKT output."
@@ -69,11 +75,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_ewkt(self):
"Testing EWKT input/output."
- for ewkt_val in ('POINT (1 2 3)', 'LINEARRING (0 0,1 1,2 1,0 0)'):
+ for ewkt_val in ("POINT (1 2 3)", "LINEARRING (0 0,1 1,2 1,0 0)"):
# First with ewkt output when no SRID in EWKT
self.assertEqual(ewkt_val, OGRGeometry(ewkt_val).ewkt)
# No test consumption with an SRID specified.
- ewkt_val = 'SRID=4326;%s' % ewkt_val
+ ewkt_val = "SRID=4326;%s" % ewkt_val
geom = OGRGeometry(ewkt_val)
self.assertEqual(ewkt_val, geom.ewkt)
self.assertEqual(4326, geom.srs.srid)
@@ -108,24 +114,26 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
"Testing GeoJSON input/output."
for g in self.geometries.json_geoms:
geom = OGRGeometry(g.wkt)
- if not hasattr(g, 'not_equal'):
+ if not hasattr(g, "not_equal"):
# Loading jsons to prevent decimal differences
self.assertEqual(json.loads(g.json), json.loads(geom.json))
self.assertEqual(json.loads(g.json), json.loads(geom.geojson))
self.assertEqual(OGRGeometry(g.wkt), OGRGeometry(geom.json))
# Test input with some garbage content (but valid json) (#15529)
- geom = OGRGeometry('{"type": "Point", "coordinates": [ 100.0, 0.0 ], "other": "<test>"}')
+ geom = OGRGeometry(
+ '{"type": "Point", "coordinates": [ 100.0, 0.0 ], "other": "<test>"}'
+ )
self.assertIsInstance(geom, OGRGeometry)
def test_points(self):
"Testing Point objects."
- OGRGeometry('POINT(0 0)')
+ OGRGeometry("POINT(0 0)")
for p in self.geometries.points:
- if not hasattr(p, 'z'): # No 3D
+ if not hasattr(p, "z"): # No 3D
pnt = OGRGeometry(p.wkt)
self.assertEqual(1, pnt.geom_type)
- self.assertEqual('POINT', pnt.geom_name)
+ self.assertEqual("POINT", pnt.geom_name)
self.assertEqual(p.x, pnt.x)
self.assertEqual(p.y, pnt.y)
self.assertEqual((p.x, p.y), pnt.tuple)
@@ -135,9 +143,9 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
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)
- mgeom2 = OGRGeometry('MULTIPOINT') # Creating empty multipoint
- mgeom3 = OGRGeometry('MULTIPOINT')
+ self.assertEqual("MULTIPOINT", mgeom1.geom_name)
+ mgeom2 = OGRGeometry("MULTIPOINT") # Creating empty multipoint
+ mgeom3 = OGRGeometry("MULTIPOINT")
for g in mgeom1:
mgeom2.add(g) # adding each point from the multipoints
mgeom3.add(g.wkt) # should take WKT as well
@@ -148,16 +156,16 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_linestring(self):
"Testing LineString objects."
- prev = OGRGeometry('POINT(0 0)')
+ prev = OGRGeometry("POINT(0 0)")
for ls in self.geometries.linestrings:
linestr = OGRGeometry(ls.wkt)
self.assertEqual(2, linestr.geom_type)
- self.assertEqual('LINESTRING', linestr.geom_name)
+ self.assertEqual("LINESTRING", linestr.geom_name)
self.assertEqual(ls.n_p, linestr.point_count)
self.assertEqual(ls.coords, linestr.tuple)
self.assertEqual(linestr, OGRGeometry(ls.wkt))
self.assertNotEqual(linestr, prev)
- msg = 'Index out of range when accessing points of a line string: %s.'
+ msg = "Index out of range when accessing points of a line string: %s."
with self.assertRaisesMessage(IndexError, msg % len(linestr)):
linestr.__getitem__(len(linestr))
prev = linestr
@@ -170,11 +178,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_multilinestring(self):
"Testing MultiLineString objects."
- prev = OGRGeometry('POINT(0 0)')
+ prev = OGRGeometry("POINT(0 0)")
for mls in self.geometries.multilinestrings:
mlinestr = OGRGeometry(mls.wkt)
self.assertEqual(5, mlinestr.geom_type)
- self.assertEqual('MULTILINESTRING', mlinestr.geom_name)
+ self.assertEqual("MULTILINESTRING", mlinestr.geom_name)
self.assertEqual(mls.n_p, mlinestr.point_count)
self.assertEqual(mls.coords, mlinestr.tuple)
self.assertEqual(mlinestr, OGRGeometry(mls.wkt))
@@ -182,18 +190,18 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
prev = mlinestr
for ls in mlinestr:
self.assertEqual(2, ls.geom_type)
- self.assertEqual('LINESTRING', ls.geom_name)
- msg = 'Index out of range when accessing geometry in a collection: %s.'
+ self.assertEqual("LINESTRING", ls.geom_name)
+ msg = "Index out of range when accessing geometry in a collection: %s."
with self.assertRaisesMessage(IndexError, msg % len(mlinestr)):
mlinestr.__getitem__(len(mlinestr))
def test_linearring(self):
"Testing LinearRing objects."
- prev = OGRGeometry('POINT(0 0)')
+ prev = OGRGeometry("POINT(0 0)")
for rr in self.geometries.linearrings:
lr = OGRGeometry(rr.wkt)
# self.assertEqual(101, lr.geom_type.num)
- self.assertEqual('LINEARRING', lr.geom_name)
+ self.assertEqual("LINEARRING", lr.geom_name)
self.assertEqual(rr.n_p, len(lr))
self.assertEqual(lr, OGRGeometry(rr.wkt))
self.assertNotEqual(lr, prev)
@@ -207,14 +215,14 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
p = OGRGeometry.from_bbox(bbox)
self.assertEqual(bbox, p.extent)
- prev = OGRGeometry('POINT(0 0)')
+ prev = OGRGeometry("POINT(0 0)")
for p in self.geometries.polygons:
poly = OGRGeometry(p.wkt)
self.assertEqual(3, poly.geom_type)
- self.assertEqual('POLYGON', poly.geom_name)
+ self.assertEqual("POLYGON", poly.geom_name)
self.assertEqual(p.n_p, poly.point_count)
self.assertEqual(p.n_i + 1, len(poly))
- msg = 'Index out of range when accessing rings of a polygon: %s.'
+ msg = "Index out of range when accessing rings of a polygon: %s."
with self.assertRaisesMessage(IndexError, msg % len(poly)):
poly.__getitem__(len(poly))
@@ -235,43 +243,45 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
self.assertEqual(len(p.ext_ring_cs), ring.point_count)
for r in poly:
- self.assertEqual('LINEARRING', r.geom_name)
+ self.assertEqual("LINEARRING", r.geom_name)
def test_polygons_templates(self):
# Accessing Polygon attributes in templates should work.
engine = Engine()
- template = engine.from_string('{{ polygons.0.wkt }}')
+ template = engine.from_string("{{ polygons.0.wkt }}")
polygons = [OGRGeometry(p.wkt) for p in self.geometries.multipolygons[:2]]
- content = template.render(Context({'polygons': polygons}))
- self.assertIn('MULTIPOLYGON (((100', content)
+ content = template.render(Context({"polygons": polygons}))
+ self.assertIn("MULTIPOLYGON (((100", content)
def test_closepolygons(self):
"Testing closing Polygon objects."
# Both rings in this geometry are not closed.
- poly = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5), (1 1, 2 1, 2 2, 2 1))')
+ poly = OGRGeometry("POLYGON((0 0, 5 0, 5 5, 0 5), (1 1, 2 1, 2 2, 2 1))")
self.assertEqual(8, poly.point_count)
with self.assertRaises(GDALException):
poly.centroid
poly.close_rings()
- self.assertEqual(10, poly.point_count) # Two closing points should've been added
- self.assertEqual(OGRGeometry('POINT(2.5 2.5)'), poly.centroid)
+ self.assertEqual(
+ 10, poly.point_count
+ ) # Two closing points should've been added
+ self.assertEqual(OGRGeometry("POINT(2.5 2.5)"), poly.centroid)
def test_multipolygons(self):
"Testing MultiPolygon objects."
- OGRGeometry('POINT(0 0)')
+ OGRGeometry("POINT(0 0)")
for mp in self.geometries.multipolygons:
mpoly = OGRGeometry(mp.wkt)
self.assertEqual(6, mpoly.geom_type)
- self.assertEqual('MULTIPOLYGON', mpoly.geom_name)
+ self.assertEqual("MULTIPOLYGON", mpoly.geom_name)
if mp.valid:
self.assertEqual(mp.n_p, mpoly.point_count)
self.assertEqual(mp.num_geom, len(mpoly))
- msg = 'Index out of range when accessing geometry in a collection: %s.'
+ msg = "Index out of range when accessing geometry in a collection: %s."
with self.assertRaisesMessage(IndexError, msg % len(mpoly)):
mpoly.__getitem__(len(mpoly))
for p in mpoly:
- self.assertEqual('POLYGON', p.geom_name)
+ self.assertEqual("POLYGON", p.geom_name)
self.assertEqual(3, p.geom_type)
self.assertEqual(mpoly.wkt, OGRGeometry(mp.wkt).wkt)
@@ -279,7 +289,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
"Testing OGR Geometries with Spatial Reference objects."
for mp in self.geometries.multipolygons:
# Creating a geometry w/spatial reference
- sr = SpatialReference('WGS84')
+ sr = SpatialReference("WGS84")
mpoly = OGRGeometry(mp.wkt, sr)
self.assertEqual(sr.wkt, mpoly.srs.wkt)
@@ -307,7 +317,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
self.assertEqual(4326, mpoly.srid)
mpoly.srs = SpatialReference(4269)
self.assertEqual(4269, mpoly.srid)
- self.assertEqual('NAD83', mpoly.srs.name)
+ self.assertEqual("NAD83", mpoly.srs.name)
# Incrementing through the multipolygon after the spatial reference
# has been re-assigned.
@@ -317,13 +327,13 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
for ring in poly:
# Changing each ring in the polygon
self.assertEqual(32140, ring.srs.srid)
- self.assertEqual('NAD83 / Texas South Central', ring.srs.name)
+ self.assertEqual("NAD83 / Texas South Central", ring.srs.name)
ring.srs = str(SpatialReference(4326)) # back to WGS84
self.assertEqual(4326, ring.srs.srid)
# Using the `srid` property.
ring.srid = 4322
- self.assertEqual('WGS 72', ring.srs.name)
+ self.assertEqual("WGS 72", ring.srs.name)
self.assertEqual(4322, ring.srid)
# srs/srid may be assigned their own values, even when srs is None.
@@ -333,15 +343,15 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_srs_transform(self):
"Testing transform()."
- orig = OGRGeometry('POINT (-104.609 38.255)', 4326)
- trans = OGRGeometry('POINT (992385.4472045 481455.4944650)', 2774)
+ orig = OGRGeometry("POINT (-104.609 38.255)", 4326)
+ trans = OGRGeometry("POINT (992385.4472045 481455.4944650)", 2774)
# Using an srid, a SpatialReference object, and a CoordTransform object
# or transformations.
t1, t2, t3 = orig.clone(), orig.clone(), orig.clone()
t1.transform(trans.srid)
- t2.transform(SpatialReference('EPSG:2774'))
- ct = CoordTransform(SpatialReference('WGS84'), SpatialReference(2774))
+ t2.transform(SpatialReference("EPSG:2774"))
+ ct = CoordTransform(SpatialReference("WGS84"), SpatialReference(2774))
t3.transform(ct)
# Testing use of the `clone` keyword.
@@ -359,8 +369,8 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_transform_dim(self):
"Testing coordinate dimension is the same on transformed geometries."
- ls_orig = OGRGeometry('LINESTRING(-104.609 38.255)', 4326)
- ls_trans = OGRGeometry('LINESTRING(992385.4472045 481455.4944650)', 2774)
+ ls_orig = OGRGeometry("LINESTRING(-104.609 38.255)", 4326)
+ ls_trans = OGRGeometry("LINESTRING(992385.4472045 481455.4944650)", 2774)
# Different PROJ versions use different transformations, all are
# correct as having a 1 meter accuracy.
@@ -379,7 +389,9 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
d1 = OGRGeometry(self.geometries.diff_geoms[i].wkt)
d2 = a.difference(b)
self.assertTrue(d1.geos.equals(d2.geos))
- self.assertTrue(d1.geos.equals((a - b).geos)) # __sub__ is difference operator
+ self.assertTrue(
+ d1.geos.equals((a - b).geos)
+ ) # __sub__ is difference operator
a -= b # testing __isub__
self.assertTrue(d1.geos.equals(a.geos))
@@ -392,7 +404,9 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
self.assertTrue(a.intersects(b))
i2 = a.intersection(b)
self.assertTrue(i1.geos.equals(i2.geos))
- self.assertTrue(i1.geos.equals((a & b).geos)) # __and__ is intersection operator
+ self.assertTrue(
+ i1.geos.equals((a & b).geos)
+ ) # __and__ is intersection operator
a &= b # testing __iand__
self.assertTrue(i1.geos.equals(a.geos))
@@ -404,7 +418,9 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
d1 = OGRGeometry(self.geometries.sdiff_geoms[i].wkt)
d2 = a.sym_difference(b)
self.assertTrue(d1.geos.equals(d2.geos))
- self.assertTrue(d1.geos.equals((a ^ b).geos)) # __xor__ is symmetric difference operator
+ self.assertTrue(
+ d1.geos.equals((a ^ b).geos)
+ ) # __xor__ is symmetric difference operator
a ^= b # testing __ixor__
self.assertTrue(d1.geos.equals(a.geos))
@@ -423,8 +439,8 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_add(self):
"Testing GeometryCollection.add()."
# Can't insert a Point into a MultiPolygon.
- mp = OGRGeometry('MultiPolygon')
- pnt = OGRGeometry('POINT(5 23)')
+ mp = OGRGeometry("MultiPolygon")
+ pnt = OGRGeometry("POINT(5 23)")
with self.assertRaises(GDALException):
mp.add(pnt)
@@ -432,9 +448,9 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
# of the same type all child geoms will be added individually) or WKT.
for mp in self.geometries.multipolygons:
mpoly = OGRGeometry(mp.wkt)
- mp1 = OGRGeometry('MultiPolygon')
- mp2 = OGRGeometry('MultiPolygon')
- mp3 = OGRGeometry('MultiPolygon')
+ mp1 = OGRGeometry("MultiPolygon")
+ mp2 = OGRGeometry("MultiPolygon")
+ mp3 = OGRGeometry("MultiPolygon")
for poly in mpoly:
mp1.add(poly) # Adding a geometry at a time
@@ -446,7 +462,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_extent(self):
"Testing `extent` property."
# The xmin, ymin, xmax, ymax of the MultiPoint should be returned.
- mp = OGRGeometry('MULTIPOINT(5 23, 0 0, 10 50)')
+ 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(self.geometries.polygons[3].wkt)
@@ -458,18 +474,18 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_25D(self):
"Testing 2.5D geometries."
- pnt_25d = OGRGeometry('POINT(1 2 3)')
- self.assertEqual('Point25D', pnt_25d.geom_type.name)
+ pnt_25d = OGRGeometry("POINT(1 2 3)")
+ self.assertEqual("Point25D", pnt_25d.geom_type.name)
self.assertEqual(3.0, pnt_25d.z)
self.assertEqual(3, pnt_25d.coord_dim)
- ls_25d = OGRGeometry('LINESTRING(1 1 1,2 2 2,3 3 3)')
- self.assertEqual('LineString25D', ls_25d.geom_type.name)
+ ls_25d = OGRGeometry("LINESTRING(1 1 1,2 2 2,3 3 3)")
+ self.assertEqual("LineString25D", ls_25d.geom_type.name)
self.assertEqual([1.0, 2.0, 3.0], ls_25d.z)
self.assertEqual(3, ls_25d.coord_dim)
def test_pickle(self):
"Testing pickle support."
- g1 = OGRGeometry('LINESTRING(1 1 1,2 2 2,3 3 3)', 'WGS84')
+ g1 = OGRGeometry("LINESTRING(1 1 1,2 2 2,3 3 3)", "WGS84")
g2 = pickle.loads(pickle.dumps(g1))
self.assertEqual(g1, g2)
self.assertEqual(4326, g2.srs.srid)
@@ -504,63 +520,114 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_equivalence_regression(self):
"Testing equivalence methods with non-OGRGeometry instances."
- self.assertIsNotNone(OGRGeometry('POINT(0 0)'))
- self.assertNotEqual(OGRGeometry('LINESTRING(0 0, 1 1)'), 3)
+ self.assertIsNotNone(OGRGeometry("POINT(0 0)"))
+ self.assertNotEqual(OGRGeometry("LINESTRING(0 0, 1 1)"), 3)
def test_contains(self):
- self.assertIs(OGRGeometry('POINT(0 0)').contains(OGRGeometry('POINT(0 0)')), True)
- self.assertIs(OGRGeometry('POINT(0 0)').contains(OGRGeometry('POINT(0 1)')), False)
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 0)")), True
+ )
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 1)")), False
+ )
def test_crosses(self):
- self.assertIs(OGRGeometry('LINESTRING(0 0, 1 1)').crosses(OGRGeometry('LINESTRING(0 1, 1 0)')), True)
- self.assertIs(OGRGeometry('LINESTRING(0 0, 0 1)').crosses(OGRGeometry('LINESTRING(1 0, 1 1)')), False)
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 1 1)").crosses(
+ OGRGeometry("LINESTRING(0 1, 1 0)")
+ ),
+ True,
+ )
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 0 1)").crosses(
+ OGRGeometry("LINESTRING(1 0, 1 1)")
+ ),
+ False,
+ )
def test_disjoint(self):
- self.assertIs(OGRGeometry('LINESTRING(0 0, 1 1)').disjoint(OGRGeometry('LINESTRING(0 1, 1 0)')), False)
- self.assertIs(OGRGeometry('LINESTRING(0 0, 0 1)').disjoint(OGRGeometry('LINESTRING(1 0, 1 1)')), True)
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 1 1)").disjoint(
+ OGRGeometry("LINESTRING(0 1, 1 0)")
+ ),
+ False,
+ )
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 0 1)").disjoint(
+ OGRGeometry("LINESTRING(1 0, 1 1)")
+ ),
+ True,
+ )
def test_equals(self):
- self.assertIs(OGRGeometry('POINT(0 0)').contains(OGRGeometry('POINT(0 0)')), True)
- self.assertIs(OGRGeometry('POINT(0 0)').contains(OGRGeometry('POINT(0 1)')), False)
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 0)")), True
+ )
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 1)")), False
+ )
def test_intersects(self):
- self.assertIs(OGRGeometry('LINESTRING(0 0, 1 1)').intersects(OGRGeometry('LINESTRING(0 1, 1 0)')), True)
- self.assertIs(OGRGeometry('LINESTRING(0 0, 0 1)').intersects(OGRGeometry('LINESTRING(1 0, 1 1)')), False)
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 1 1)").intersects(
+ OGRGeometry("LINESTRING(0 1, 1 0)")
+ ),
+ True,
+ )
+ self.assertIs(
+ OGRGeometry("LINESTRING(0 0, 0 1)").intersects(
+ OGRGeometry("LINESTRING(1 0, 1 1)")
+ ),
+ False,
+ )
def test_overlaps(self):
self.assertIs(
- OGRGeometry('POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0))').overlaps(
- OGRGeometry('POLYGON ((1 1, 1 5, 5 5, 5 1, 1 1))')
- ), True
+ OGRGeometry("POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0))").overlaps(
+ OGRGeometry("POLYGON ((1 1, 1 5, 5 5, 5 1, 1 1))")
+ ),
+ True,
+ )
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").overlaps(OGRGeometry("POINT(0 1)")), False
)
- self.assertIs(OGRGeometry('POINT(0 0)').overlaps(OGRGeometry('POINT(0 1)')), False)
def test_touches(self):
self.assertIs(
- OGRGeometry('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))').touches(OGRGeometry('LINESTRING(0 2, 2 0)')), True
+ OGRGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))").touches(
+ OGRGeometry("LINESTRING(0 2, 2 0)")
+ ),
+ True,
+ )
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").touches(OGRGeometry("POINT(0 1)")), False
)
- self.assertIs(OGRGeometry('POINT(0 0)').touches(OGRGeometry('POINT(0 1)')), False)
def test_within(self):
self.assertIs(
- OGRGeometry('POINT(0.5 0.5)').within(OGRGeometry('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')), True
+ OGRGeometry("POINT(0.5 0.5)").within(
+ OGRGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))")
+ ),
+ True,
+ )
+ self.assertIs(
+ OGRGeometry("POINT(0 0)").within(OGRGeometry("POINT(0 1)")), False
)
- self.assertIs(OGRGeometry('POINT(0 0)').within(OGRGeometry('POINT(0 1)')), False)
def test_from_gml(self):
self.assertEqual(
- OGRGeometry('POINT(0 0)'),
+ OGRGeometry("POINT(0 0)"),
OGRGeometry.from_gml(
'<gml:Point gml:id="p21" srsName="http://www.opengis.net/def/crs/EPSG/0/4326">'
' <gml:pos srsDimension="2">0 0</gml:pos>'
- '</gml:Point>'
+ "</gml:Point>"
),
)
def test_empty(self):
- self.assertIs(OGRGeometry('POINT (0 0)').empty, False)
- self.assertIs(OGRGeometry('POINT EMPTY').empty, True)
+ self.assertIs(OGRGeometry("POINT (0 0)").empty, False)
+ self.assertIs(OGRGeometry("POINT EMPTY").empty, True)
def test_empty_point_to_geos(self):
- p = OGRGeometry('POINT EMPTY', srs=4326)
+ p = OGRGeometry("POINT EMPTY", srs=4326)
self.assertEqual(p.geos.ewkt, p.ewkt)
diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py
index 229f09eaf4..795fdd079f 100644
--- a/tests/gis_tests/gdal_tests/test_raster.py
+++ b/tests/gis_tests/gdal_tests/test_raster.py
@@ -18,8 +18,11 @@ class GDALRasterTests(SimpleTestCase):
"""
Test a GDALRaster instance created from a file (GeoTiff).
"""
+
def setUp(self):
- self.rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
+ self.rs_path = os.path.join(
+ os.path.dirname(__file__), "../data/rasters/raster.tif"
+ )
self.rs = GDALRaster(self.rs_path)
def test_rs_name_repr(self):
@@ -27,7 +30,7 @@ class GDALRasterTests(SimpleTestCase):
self.assertRegex(repr(self.rs), r"<Raster object at 0x\w+>")
def test_rs_driver(self):
- self.assertEqual(self.rs.driver.name, 'GTiff')
+ self.assertEqual(self.rs.driver.name, "GTiff")
def test_rs_size(self):
self.assertEqual(self.rs.width, 163)
@@ -35,14 +38,16 @@ class GDALRasterTests(SimpleTestCase):
def test_rs_srs(self):
self.assertEqual(self.rs.srs.srid, 3086)
- self.assertEqual(self.rs.srs.units, (1.0, 'metre'))
+ self.assertEqual(self.rs.srs.units, (1.0, "metre"))
def test_rs_srid(self):
- rast = GDALRaster({
- 'width': 16,
- 'height': 16,
- 'srid': 4326,
- })
+ rast = GDALRaster(
+ {
+ "width": 16,
+ "height": 16,
+ "srid": 4326,
+ }
+ )
self.assertEqual(rast.srid, 4326)
rast.srid = 3086
self.assertEqual(rast.srid, 3086)
@@ -51,7 +56,7 @@ class GDALRasterTests(SimpleTestCase):
# Assert correct values for file based raster
self.assertEqual(
self.rs.geotransform,
- [511700.4680706557, 100.0, 0.0, 435103.3771231986, 0.0, -100.0]
+ [511700.4680706557, 100.0, 0.0, 435103.3771231986, 0.0, -100.0],
)
self.assertEqual(self.rs.origin, [511700.4680706557, 435103.3771231986])
self.assertEqual(self.rs.origin.x, 511700.4680706557)
@@ -85,18 +90,25 @@ class GDALRasterTests(SimpleTestCase):
rsmem = GDALRaster(JSON_RASTER)
error_geotransforms = [
[1, 2],
- [1, 2, 3, 4, 5, 'foo'],
- [1, 2, 3, 4, 5, 6, 'foo'],
+ [1, 2, 3, 4, 5, "foo"],
+ [1, 2, 3, 4, 5, 6, "foo"],
]
- msg = 'Geotransform must consist of 6 numeric values.'
+ msg = "Geotransform must consist of 6 numeric values."
for geotransform in error_geotransforms:
- with self.subTest(i=geotransform), self.assertRaisesMessage(ValueError, msg):
+ with self.subTest(i=geotransform), self.assertRaisesMessage(
+ ValueError, msg
+ ):
rsmem.geotransform = geotransform
def test_rs_extent(self):
self.assertEqual(
self.rs.extent,
- (511700.4680706557, 417703.3771231986, 528000.4680706557, 435103.3771231986)
+ (
+ 511700.4680706557,
+ 417703.3771231986,
+ 528000.4680706557,
+ 435103.3771231986,
+ ),
)
def test_rs_bands(self):
@@ -105,16 +117,20 @@ class GDALRasterTests(SimpleTestCase):
def test_memory_based_raster_creation(self):
# Create uint8 raster with full pixel data range (0-255)
- rast = GDALRaster({
- 'datatype': 1,
- 'width': 16,
- 'height': 16,
- 'srid': 4326,
- 'bands': [{
- 'data': range(256),
- 'nodata_value': 255,
- }],
- })
+ rast = GDALRaster(
+ {
+ "datatype": 1,
+ "width": 16,
+ "height": 16,
+ "srid": 4326,
+ "bands": [
+ {
+ "data": range(256),
+ "nodata_value": 255,
+ }
+ ],
+ }
+ )
# Get array from raster
result = rast.bands[0].data()
@@ -126,38 +142,41 @@ class GDALRasterTests(SimpleTestCase):
def test_file_based_raster_creation(self):
# Prepare tempfile
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
# Create file-based raster from scratch
- GDALRaster({
- 'datatype': self.rs.bands[0].datatype(),
- 'driver': 'tif',
- 'name': rstfile.name,
- 'width': 163,
- 'height': 174,
- 'nr_of_bands': 1,
- 'srid': self.rs.srs.wkt,
- 'origin': (self.rs.origin.x, self.rs.origin.y),
- 'scale': (self.rs.scale.x, self.rs.scale.y),
- 'skew': (self.rs.skew.x, self.rs.skew.y),
- 'bands': [{
- 'data': self.rs.bands[0].data(),
- 'nodata_value': self.rs.bands[0].nodata_value,
- }],
- })
+ GDALRaster(
+ {
+ "datatype": self.rs.bands[0].datatype(),
+ "driver": "tif",
+ "name": rstfile.name,
+ "width": 163,
+ "height": 174,
+ "nr_of_bands": 1,
+ "srid": self.rs.srs.wkt,
+ "origin": (self.rs.origin.x, self.rs.origin.y),
+ "scale": (self.rs.scale.x, self.rs.scale.y),
+ "skew": (self.rs.skew.x, self.rs.skew.y),
+ "bands": [
+ {
+ "data": self.rs.bands[0].data(),
+ "nodata_value": self.rs.bands[0].nodata_value,
+ }
+ ],
+ }
+ )
# Reload newly created raster from file
restored_raster = GDALRaster(rstfile.name)
# Presence of TOWGS84 depend on GDAL/Proj versions.
self.assertEqual(
- restored_raster.srs.wkt.replace('TOWGS84[0,0,0,0,0,0,0],', ''),
- self.rs.srs.wkt.replace('TOWGS84[0,0,0,0,0,0,0],', '')
+ restored_raster.srs.wkt.replace("TOWGS84[0,0,0,0,0,0,0],", ""),
+ self.rs.srs.wkt.replace("TOWGS84[0,0,0,0,0,0,0],", ""),
)
self.assertEqual(restored_raster.geotransform, self.rs.geotransform)
if numpy:
numpy.testing.assert_equal(
- restored_raster.bands[0].data(),
- self.rs.bands[0].data()
+ restored_raster.bands[0].data(), self.rs.bands[0].data()
)
else:
self.assertEqual(restored_raster.bands[0].data(), self.rs.bands[0].data())
@@ -165,11 +184,11 @@ class GDALRasterTests(SimpleTestCase):
def test_nonexistent_file(self):
msg = 'Unable to read raster source input "nonexistent.tif".'
with self.assertRaisesMessage(GDALException, msg):
- GDALRaster('nonexistent.tif')
+ GDALRaster("nonexistent.tif")
def test_vsi_raster_creation(self):
# Open a raster as a file object.
- with open(self.rs_path, 'rb') as dat:
+ with open(self.rs_path, "rb") as dat:
# Instantiate a raster from the file binary buffer.
vsimem = GDALRaster(dat.read())
# The data of the in-memory file is equal to the source file.
@@ -181,18 +200,22 @@ class GDALRasterTests(SimpleTestCase):
self.assertEqual(result, target)
def test_vsi_raster_deletion(self):
- path = '/vsimem/raster.tif'
+ path = "/vsimem/raster.tif"
# Create a vsi-based raster from scratch.
- vsimem = GDALRaster({
- 'name': path,
- 'driver': 'tif',
- 'width': 4,
- 'height': 4,
- 'srid': 4326,
- 'bands': [{
- 'data': range(16),
- }],
- })
+ vsimem = GDALRaster(
+ {
+ "name": path,
+ "driver": "tif",
+ "width": 4,
+ "height": 4,
+ "srid": 4326,
+ "bands": [
+ {
+ "data": range(16),
+ }
+ ],
+ }
+ )
# The virtual file exists.
rst = GDALRaster(path)
self.assertEqual(rst.width, 4)
@@ -205,22 +228,26 @@ class GDALRasterTests(SimpleTestCase):
GDALRaster(path)
def test_vsi_invalid_buffer_error(self):
- msg = 'Failed creating VSI raster from the input buffer.'
+ msg = "Failed creating VSI raster from the input buffer."
with self.assertRaisesMessage(GDALException, msg):
- GDALRaster(b'not-a-raster-buffer')
+ GDALRaster(b"not-a-raster-buffer")
def test_vsi_buffer_property(self):
# Create a vsi-based raster from scratch.
- rast = GDALRaster({
- 'name': '/vsimem/raster.tif',
- 'driver': 'tif',
- 'width': 4,
- 'height': 4,
- 'srid': 4326,
- 'bands': [{
- 'data': range(16),
- }],
- })
+ rast = GDALRaster(
+ {
+ "name": "/vsimem/raster.tif",
+ "driver": "tif",
+ "width": 4,
+ "height": 4,
+ "srid": 4326,
+ "bands": [
+ {
+ "data": range(16),
+ }
+ ],
+ }
+ )
# Do a round trip from raster to buffer to raster.
result = GDALRaster(rast.vsi_buffer).bands[0].data()
if numpy:
@@ -231,10 +258,10 @@ class GDALRasterTests(SimpleTestCase):
self.assertIsNone(self.rs.vsi_buffer)
def test_vsi_vsizip_filesystem(self):
- rst_zipfile = tempfile.NamedTemporaryFile(suffix='.zip')
- with zipfile.ZipFile(rst_zipfile, mode='w') as zf:
- zf.write(self.rs_path, 'raster.tif')
- rst_path = '/vsizip/' + os.path.join(rst_zipfile.name, 'raster.tif')
+ rst_zipfile = tempfile.NamedTemporaryFile(suffix=".zip")
+ with zipfile.ZipFile(rst_zipfile, mode="w") as zf:
+ zf.write(self.rs_path, "raster.tif")
+ rst_path = "/vsizip/" + os.path.join(rst_zipfile.name, "raster.tif")
rst = GDALRaster(rst_path)
self.assertEqual(rst.driver.name, self.rs.driver.name)
self.assertEqual(rst.name, rst_path)
@@ -242,38 +269,41 @@ class GDALRasterTests(SimpleTestCase):
self.assertIsNone(rst.vsi_buffer)
def test_offset_size_and_shape_on_raster_creation(self):
- rast = GDALRaster({
- 'datatype': 1,
- 'width': 4,
- 'height': 4,
- 'srid': 4326,
- 'bands': [{
- 'data': (1,),
- 'offset': (1, 1),
- 'size': (2, 2),
- 'shape': (1, 1),
- 'nodata_value': 2,
- }],
- })
+ rast = GDALRaster(
+ {
+ "datatype": 1,
+ "width": 4,
+ "height": 4,
+ "srid": 4326,
+ "bands": [
+ {
+ "data": (1,),
+ "offset": (1, 1),
+ "size": (2, 2),
+ "shape": (1, 1),
+ "nodata_value": 2,
+ }
+ ],
+ }
+ )
# Get array from raster.
result = rast.bands[0].data()
if numpy:
result = result.flatten().tolist()
# Band data is equal to nodata value except on input block of ones.
- self.assertEqual(
- result,
- [2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2]
- )
+ self.assertEqual(result, [2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2])
def test_set_nodata_value_on_raster_creation(self):
# Create raster filled with nodata values.
- rast = GDALRaster({
- 'datatype': 1,
- 'width': 2,
- 'height': 2,
- 'srid': 4326,
- 'bands': [{'nodata_value': 23}],
- })
+ rast = GDALRaster(
+ {
+ "datatype": 1,
+ "width": 2,
+ "height": 2,
+ "srid": 4326,
+ "bands": [{"nodata_value": 23}],
+ }
+ )
# Get array from raster.
result = rast.bands[0].data()
if numpy:
@@ -283,13 +313,15 @@ class GDALRasterTests(SimpleTestCase):
def test_set_nodata_none_on_raster_creation(self):
# Create raster without data and without nodata value.
- rast = GDALRaster({
- 'datatype': 1,
- 'width': 2,
- 'height': 2,
- 'srid': 4326,
- 'bands': [{'nodata_value': None}],
- })
+ rast = GDALRaster(
+ {
+ "datatype": 1,
+ "width": 2,
+ "height": 2,
+ "srid": 4326,
+ "bands": [{"nodata_value": None}],
+ }
+ )
# Get array from raster.
result = rast.bands[0].data()
if numpy:
@@ -299,54 +331,56 @@ class GDALRasterTests(SimpleTestCase):
def test_raster_metadata_property(self):
data = self.rs.metadata
- self.assertEqual(data['DEFAULT'], {'AREA_OR_POINT': 'Area'})
- self.assertEqual(data['IMAGE_STRUCTURE'], {'INTERLEAVE': 'BAND'})
+ self.assertEqual(data["DEFAULT"], {"AREA_OR_POINT": "Area"})
+ self.assertEqual(data["IMAGE_STRUCTURE"], {"INTERLEAVE": "BAND"})
# Create file-based raster from scratch
- source = GDALRaster({
- 'datatype': 1,
- 'width': 2,
- 'height': 2,
- 'srid': 4326,
- 'bands': [{'data': range(4), 'nodata_value': 99}],
- })
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "width": 2,
+ "height": 2,
+ "srid": 4326,
+ "bands": [{"data": range(4), "nodata_value": 99}],
+ }
+ )
# Set metadata on raster and on a band.
metadata = {
- 'DEFAULT': {'OWNER': 'Django', 'VERSION': '1.0', 'AREA_OR_POINT': 'Point'},
+ "DEFAULT": {"OWNER": "Django", "VERSION": "1.0", "AREA_OR_POINT": "Point"},
}
source.metadata = metadata
source.bands[0].metadata = metadata
- self.assertEqual(source.metadata['DEFAULT'], metadata['DEFAULT'])
- self.assertEqual(source.bands[0].metadata['DEFAULT'], metadata['DEFAULT'])
+ self.assertEqual(source.metadata["DEFAULT"], metadata["DEFAULT"])
+ self.assertEqual(source.bands[0].metadata["DEFAULT"], metadata["DEFAULT"])
# Update metadata on raster.
metadata = {
- 'DEFAULT': {'VERSION': '2.0'},
+ "DEFAULT": {"VERSION": "2.0"},
}
source.metadata = metadata
- self.assertEqual(source.metadata['DEFAULT']['VERSION'], '2.0')
+ self.assertEqual(source.metadata["DEFAULT"]["VERSION"], "2.0")
# Remove metadata on raster.
metadata = {
- 'DEFAULT': {'OWNER': None},
+ "DEFAULT": {"OWNER": None},
}
source.metadata = metadata
- self.assertNotIn('OWNER', source.metadata['DEFAULT'])
+ self.assertNotIn("OWNER", source.metadata["DEFAULT"])
def test_raster_info_accessor(self):
infos = self.rs.info
# Data
- info_lines = [line.strip() for line in infos.split('\n') if line.strip() != '']
+ info_lines = [line.strip() for line in infos.split("\n") if line.strip() != ""]
for line in [
- 'Driver: GTiff/GeoTIFF',
- 'Files: {}'.format(self.rs_path),
- 'Size is 163, 174',
- 'Origin = (511700.468070655711927,435103.377123198588379)',
- 'Pixel Size = (100.000000000000000,-100.000000000000000)',
- 'Metadata:',
- 'AREA_OR_POINT=Area',
- 'Image Structure Metadata:',
- 'INTERLEAVE=BAND',
- 'Band 1 Block=163x50 Type=Byte, ColorInterp=Gray',
- 'NoData Value=15'
+ "Driver: GTiff/GeoTIFF",
+ "Files: {}".format(self.rs_path),
+ "Size is 163, 174",
+ "Origin = (511700.468070655711927,435103.377123198588379)",
+ "Pixel Size = (100.000000000000000,-100.000000000000000)",
+ "Metadata:",
+ "AREA_OR_POINT=Area",
+ "Image Structure Metadata:",
+ "INTERLEAVE=BAND",
+ "Band 1 Block=163x50 Type=Byte, ColorInterp=Gray",
+ "NoData Value=15",
]:
self.assertIn(line, info_lines)
for line in [
@@ -361,72 +395,87 @@ class GDALRasterTests(SimpleTestCase):
self.assertIn("NAD83 / Florida GDL Albers", infos)
def test_compressed_file_based_raster_creation(self):
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
# Make a compressed copy of an existing raster.
- compressed = self.rs.warp({'papsz_options': {'compress': 'packbits'}, 'name': rstfile.name})
+ compressed = self.rs.warp(
+ {"papsz_options": {"compress": "packbits"}, "name": rstfile.name}
+ )
# Check physically if compression worked.
self.assertLess(os.path.getsize(compressed.name), os.path.getsize(self.rs.name))
# Create file-based raster with options from scratch.
- compressed = GDALRaster({
- 'datatype': 1,
- 'driver': 'tif',
- 'name': rstfile.name,
- 'width': 40,
- 'height': 40,
- 'srid': 3086,
- 'origin': (500000, 400000),
- 'scale': (100, -100),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(40 ^ 2),
- 'nodata_value': 255,
- }],
- 'papsz_options': {
- 'compress': 'packbits',
- 'pixeltype': 'signedbyte',
- 'blockxsize': 23,
- 'blockysize': 23,
+ compressed = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "tif",
+ "name": rstfile.name,
+ "width": 40,
+ "height": 40,
+ "srid": 3086,
+ "origin": (500000, 400000),
+ "scale": (100, -100),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(40 ^ 2),
+ "nodata_value": 255,
+ }
+ ],
+ "papsz_options": {
+ "compress": "packbits",
+ "pixeltype": "signedbyte",
+ "blockxsize": 23,
+ "blockysize": 23,
+ },
}
- })
+ )
# Check if options used on creation are stored in metadata.
# Reopening the raster ensures that all metadata has been written
# to the file.
compressed = GDALRaster(compressed.name)
- self.assertEqual(compressed.metadata['IMAGE_STRUCTURE']['COMPRESSION'], 'PACKBITS',)
- self.assertEqual(compressed.bands[0].metadata['IMAGE_STRUCTURE']['PIXELTYPE'], 'SIGNEDBYTE')
- self.assertIn('Block=40x23', compressed.info)
+ self.assertEqual(
+ compressed.metadata["IMAGE_STRUCTURE"]["COMPRESSION"],
+ "PACKBITS",
+ )
+ self.assertEqual(
+ compressed.bands[0].metadata["IMAGE_STRUCTURE"]["PIXELTYPE"], "SIGNEDBYTE"
+ )
+ self.assertIn("Block=40x23", compressed.info)
def test_raster_warp(self):
# Create in memory raster
- source = GDALRaster({
- 'datatype': 1,
- 'driver': 'MEM',
- 'name': 'sourceraster',
- 'width': 4,
- 'height': 4,
- 'nr_of_bands': 1,
- 'srid': 3086,
- 'origin': (500000, 400000),
- 'scale': (100, -100),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(16),
- 'nodata_value': 255,
- }],
- })
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "MEM",
+ "name": "sourceraster",
+ "width": 4,
+ "height": 4,
+ "nr_of_bands": 1,
+ "srid": 3086,
+ "origin": (500000, 400000),
+ "scale": (100, -100),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(16),
+ "nodata_value": 255,
+ }
+ ],
+ }
+ )
# Test altering the scale, width, and height of a raster
data = {
- 'scale': [200, -200],
- 'width': 2,
- 'height': 2,
+ "scale": [200, -200],
+ "width": 2,
+ "height": 2,
}
target = source.warp(data)
- self.assertEqual(target.width, data['width'])
- self.assertEqual(target.height, data['height'])
- self.assertEqual(target.scale, data['scale'])
+ self.assertEqual(target.width, data["width"])
+ self.assertEqual(target.height, data["height"])
+ self.assertEqual(target.scale, data["scale"])
self.assertEqual(target.bands[0].datatype(), source.bands[0].datatype())
- self.assertEqual(target.name, 'sourceraster_copy.MEM')
+ self.assertEqual(target.name, "sourceraster_copy.MEM")
result = target.bands[0].data()
if numpy:
result = result.flatten().tolist()
@@ -434,70 +483,92 @@ class GDALRasterTests(SimpleTestCase):
# Test altering the name and datatype (to float)
data = {
- 'name': '/path/to/targetraster.tif',
- 'datatype': 6,
+ "name": "/path/to/targetraster.tif",
+ "datatype": 6,
}
target = source.warp(data)
self.assertEqual(target.bands[0].datatype(), 6)
- self.assertEqual(target.name, '/path/to/targetraster.tif')
- self.assertEqual(target.driver.name, 'MEM')
+ self.assertEqual(target.name, "/path/to/targetraster.tif")
+ self.assertEqual(target.driver.name, "MEM")
result = target.bands[0].data()
if numpy:
result = result.flatten().tolist()
self.assertEqual(
result,
- [0.0, 1.0, 2.0, 3.0,
- 4.0, 5.0, 6.0, 7.0,
- 8.0, 9.0, 10.0, 11.0,
- 12.0, 13.0, 14.0, 15.0]
+ [
+ 0.0,
+ 1.0,
+ 2.0,
+ 3.0,
+ 4.0,
+ 5.0,
+ 6.0,
+ 7.0,
+ 8.0,
+ 9.0,
+ 10.0,
+ 11.0,
+ 12.0,
+ 13.0,
+ 14.0,
+ 15.0,
+ ],
)
def test_raster_warp_nodata_zone(self):
# Create in memory raster.
- source = GDALRaster({
- 'datatype': 1,
- 'driver': 'MEM',
- 'width': 4,
- 'height': 4,
- 'srid': 3086,
- 'origin': (500000, 400000),
- 'scale': (100, -100),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(16),
- 'nodata_value': 23,
- }],
- })
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "MEM",
+ "width": 4,
+ "height": 4,
+ "srid": 3086,
+ "origin": (500000, 400000),
+ "scale": (100, -100),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(16),
+ "nodata_value": 23,
+ }
+ ],
+ }
+ )
# Warp raster onto a location that does not cover any pixels of the original.
- result = source.warp({'origin': (200000, 200000)}).bands[0].data()
+ result = source.warp({"origin": (200000, 200000)}).bands[0].data()
if numpy:
result = result.flatten().tolist()
# The result is an empty raster filled with the correct nodata value.
self.assertEqual(result, [23] * 16)
def test_raster_clone(self):
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
tests = [
- ('MEM', '', 23), # In memory raster.
- ('tif', rstfile.name, 99), # In file based raster.
+ ("MEM", "", 23), # In memory raster.
+ ("tif", rstfile.name, 99), # In file based raster.
]
for driver, name, nodata_value in tests:
with self.subTest(driver=driver):
- source = GDALRaster({
- 'datatype': 1,
- 'driver': driver,
- 'name': name,
- 'width': 4,
- 'height': 4,
- 'srid': 3086,
- 'origin': (500000, 400000),
- 'scale': (100, -100),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(16),
- 'nodata_value': nodata_value,
- }],
- })
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": driver,
+ "name": name,
+ "width": 4,
+ "height": 4,
+ "srid": 3086,
+ "origin": (500000, 400000),
+ "scale": (100, -100),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(16),
+ "nodata_value": nodata_value,
+ }
+ ],
+ }
+ )
clone = source.clone()
self.assertNotEqual(clone.name, source.name)
self.assertEqual(clone._write, source._write)
@@ -512,31 +583,35 @@ class GDALRasterTests(SimpleTestCase):
def test_raster_transform(self):
tests = [
3086,
- '3086',
+ "3086",
SpatialReference(3086),
]
for srs in tests:
with self.subTest(srs=srs):
# Prepare tempfile and nodata value.
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
ndv = 99
# Create in file based raster.
- source = GDALRaster({
- 'datatype': 1,
- 'driver': 'tif',
- 'name': rstfile.name,
- 'width': 5,
- 'height': 5,
- 'nr_of_bands': 1,
- 'srid': 4326,
- 'origin': (-5, 5),
- 'scale': (2, -2),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(25),
- 'nodata_value': ndv,
- }],
- })
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "tif",
+ "name": rstfile.name,
+ "width": 5,
+ "height": 5,
+ "nr_of_bands": 1,
+ "srid": 4326,
+ "origin": (-5, 5),
+ "scale": (2, -2),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(25),
+ "nodata_value": ndv,
+ }
+ ],
+ }
+ )
target = source.transform(srs)
@@ -560,36 +635,82 @@ class GDALRasterTests(SimpleTestCase):
self.assertEqual(
result,
[
- ndv, ndv, ndv, ndv, 4, ndv, ndv,
- ndv, ndv, 2, 3, 9, ndv, ndv,
- ndv, 1, 2, 8, 13, 19, ndv,
- 0, 6, 6, 12, 18, 18, 24,
- ndv, 10, 11, 16, 22, 23, ndv,
- ndv, ndv, 15, 21, 22, ndv, ndv,
- ndv, ndv, 20, ndv, ndv, ndv, ndv,
+ ndv,
+ ndv,
+ ndv,
+ ndv,
+ 4,
+ ndv,
+ ndv,
+ ndv,
+ ndv,
+ 2,
+ 3,
+ 9,
+ ndv,
+ ndv,
+ ndv,
+ 1,
+ 2,
+ 8,
+ 13,
+ 19,
+ ndv,
+ 0,
+ 6,
+ 6,
+ 12,
+ 18,
+ 18,
+ 24,
+ ndv,
+ 10,
+ 11,
+ 16,
+ 22,
+ 23,
+ ndv,
+ ndv,
+ ndv,
+ 15,
+ 21,
+ 22,
+ ndv,
+ ndv,
+ ndv,
+ ndv,
+ 20,
+ ndv,
+ ndv,
+ ndv,
+ ndv,
],
)
def test_raster_transform_clone(self):
- with mock.patch.object(GDALRaster, 'clone') as mocked_clone:
+ with mock.patch.object(GDALRaster, "clone") as mocked_clone:
# Create in file based raster.
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
- source = GDALRaster({
- 'datatype': 1,
- 'driver': 'tif',
- 'name': rstfile.name,
- 'width': 5,
- 'height': 5,
- 'nr_of_bands': 1,
- 'srid': 4326,
- 'origin': (-5, 5),
- 'scale': (2, -2),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(25),
- 'nodata_value': 99,
- }],
- })
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "tif",
+ "name": rstfile.name,
+ "width": 5,
+ "height": 5,
+ "nr_of_bands": 1,
+ "srid": 4326,
+ "origin": (-5, 5),
+ "scale": (2, -2),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(25),
+ "nodata_value": 99,
+ }
+ ],
+ }
+ )
# transform() returns a clone because it is the same SRID and
# driver.
source.transform(4326)
@@ -597,57 +718,63 @@ class GDALRasterTests(SimpleTestCase):
def test_raster_transform_clone_name(self):
# Create in file based raster.
- rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
- source = GDALRaster({
- 'datatype': 1,
- 'driver': 'tif',
- 'name': rstfile.name,
- 'width': 5,
- 'height': 5,
- 'nr_of_bands': 1,
- 'srid': 4326,
- 'origin': (-5, 5),
- 'scale': (2, -2),
- 'skew': (0, 0),
- 'bands': [{
- 'data': range(25),
- 'nodata_value': 99,
- }],
- })
- clone_name = rstfile.name + '_respect_name.GTiff'
+ rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
+ source = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "tif",
+ "name": rstfile.name,
+ "width": 5,
+ "height": 5,
+ "nr_of_bands": 1,
+ "srid": 4326,
+ "origin": (-5, 5),
+ "scale": (2, -2),
+ "skew": (0, 0),
+ "bands": [
+ {
+ "data": range(25),
+ "nodata_value": 99,
+ }
+ ],
+ }
+ )
+ clone_name = rstfile.name + "_respect_name.GTiff"
target = source.transform(4326, name=clone_name)
self.assertEqual(target.name, clone_name)
class GDALBandTests(SimpleTestCase):
- rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
+ rs_path = os.path.join(os.path.dirname(__file__), "../data/rasters/raster.tif")
def test_band_data(self):
rs = GDALRaster(self.rs_path)
band = rs.bands[0]
self.assertEqual(band.width, 163)
self.assertEqual(band.height, 174)
- self.assertEqual(band.description, '')
+ self.assertEqual(band.description, "")
self.assertEqual(band.datatype(), 1)
- self.assertEqual(band.datatype(as_string=True), 'GDT_Byte')
+ self.assertEqual(band.datatype(as_string=True), "GDT_Byte")
self.assertEqual(band.color_interp(), 1)
- self.assertEqual(band.color_interp(as_string=True), 'GCI_GrayIndex')
+ self.assertEqual(band.color_interp(as_string=True), "GCI_GrayIndex")
self.assertEqual(band.nodata_value, 15)
if numpy:
data = band.data()
assert_array = numpy.loadtxt(
- os.path.join(os.path.dirname(__file__), '../data/rasters/raster.numpy.txt')
+ os.path.join(
+ os.path.dirname(__file__), "../data/rasters/raster.numpy.txt"
+ )
)
numpy.testing.assert_equal(data, assert_array)
self.assertEqual(data.shape, (band.height, band.width))
def test_band_statistics(self):
with tempfile.TemporaryDirectory() as tmp_dir:
- rs_path = os.path.join(tmp_dir, 'raster.tif')
+ rs_path = os.path.join(tmp_dir, "raster.tif")
shutil.copyfile(self.rs_path, rs_path)
rs = GDALRaster(rs_path)
band = rs.bands[0]
- pam_file = rs_path + '.aux.xml'
+ pam_file = rs_path + ".aux.xml"
smin, smax, smean, sstd = band.statistics(approximate=True)
self.assertEqual(smin, 0)
self.assertEqual(smax, 9)
@@ -676,19 +803,21 @@ class GDALBandTests(SimpleTestCase):
# Setting attributes in write mode raises exception in the _flush method
with self.assertRaises(GDALException):
- setattr(band, 'nodata_value', 10)
+ setattr(band, "nodata_value", 10)
def test_band_data_setters(self):
# Create in-memory raster and get band
- rsmem = GDALRaster({
- 'datatype': 1,
- 'driver': 'MEM',
- 'name': 'mem_rst',
- 'width': 10,
- 'height': 10,
- 'nr_of_bands': 1,
- 'srid': 4326,
- })
+ rsmem = GDALRaster(
+ {
+ "datatype": 1,
+ "driver": "MEM",
+ "name": "mem_rst",
+ "width": 10,
+ "height": 10,
+ "nr_of_bands": 1,
+ "srid": 4326,
+ }
+ )
bandmem = rsmem.bands[0]
# Set nodata value
@@ -698,13 +827,15 @@ class GDALBandTests(SimpleTestCase):
# Set data for entire dataset
bandmem.data(range(100))
if numpy:
- numpy.testing.assert_equal(bandmem.data(), numpy.arange(100).reshape(10, 10))
+ numpy.testing.assert_equal(
+ bandmem.data(), numpy.arange(100).reshape(10, 10)
+ )
else:
self.assertEqual(bandmem.data(), list(range(100)))
# Prepare data for setting values in subsequent tests
block = list(range(100, 104))
- packed_block = struct.pack('<' + 'B B B B', *block)
+ packed_block = struct.pack("<" + "B B B B", *block)
# Set data from list
bandmem.data(block, (1, 1), (2, 2))
@@ -748,10 +879,10 @@ class GDALBandTests(SimpleTestCase):
# Set data from numpy array
if numpy:
- bandmem.data(numpy.array(block, dtype='int8').reshape(2, 2), (1, 1), (2, 2))
+ bandmem.data(numpy.array(block, dtype="int8").reshape(2, 2), (1, 1), (2, 2))
numpy.testing.assert_equal(
bandmem.data(offset=(1, 1), size=(2, 2)),
- numpy.array(block).reshape(2, 2)
+ numpy.array(block).reshape(2, 2),
)
# Test json input data
@@ -759,19 +890,20 @@ class GDALBandTests(SimpleTestCase):
bandmemjson = rsmemjson.bands[0]
if numpy:
numpy.testing.assert_equal(
- bandmemjson.data(),
- numpy.array(range(25)).reshape(5, 5)
+ bandmemjson.data(), numpy.array(range(25)).reshape(5, 5)
)
else:
self.assertEqual(bandmemjson.data(), list(range(25)))
def test_band_statistics_automatic_refresh(self):
- rsmem = GDALRaster({
- 'srid': 4326,
- 'width': 2,
- 'height': 2,
- 'bands': [{'data': [0] * 4, 'nodata_value': 99}],
- })
+ rsmem = GDALRaster(
+ {
+ "srid": 4326,
+ "width": 2,
+ "height": 2,
+ "bands": [{"data": [0] * 4, "nodata_value": 99}],
+ }
+ )
band = rsmem.bands[0]
# Populate statistics cache
self.assertEqual(band.statistics(), (0, 0, 0, 0))
@@ -785,31 +917,37 @@ class GDALBandTests(SimpleTestCase):
self.assertEqual(band.statistics(), (1.0, 1.0, 1.0, 0.0))
def test_band_statistics_empty_band(self):
- rsmem = GDALRaster({
- 'srid': 4326,
- 'width': 1,
- 'height': 1,
- 'bands': [{'data': [0], 'nodata_value': 0}],
- })
+ rsmem = GDALRaster(
+ {
+ "srid": 4326,
+ "width": 1,
+ "height": 1,
+ "bands": [{"data": [0], "nodata_value": 0}],
+ }
+ )
self.assertEqual(rsmem.bands[0].statistics(), (None, None, None, None))
def test_band_delete_nodata(self):
- rsmem = GDALRaster({
- 'srid': 4326,
- 'width': 1,
- 'height': 1,
- 'bands': [{'data': [0], 'nodata_value': 1}],
- })
+ rsmem = GDALRaster(
+ {
+ "srid": 4326,
+ "width": 1,
+ "height": 1,
+ "bands": [{"data": [0], "nodata_value": 1}],
+ }
+ )
rsmem.bands[0].nodata_value = None
self.assertIsNone(rsmem.bands[0].nodata_value)
def test_band_data_replication(self):
- band = GDALRaster({
- 'srid': 4326,
- 'width': 3,
- 'height': 3,
- 'bands': [{'data': range(10, 19), 'nodata_value': 0}],
- }).bands[0]
+ band = GDALRaster(
+ {
+ "srid": 4326,
+ "width": 3,
+ "height": 3,
+ "bands": [{"data": range(10, 19), "nodata_value": 0}],
+ }
+ ).bands[0]
# Variations for input (data, shape, expected result).
combos = (
@@ -820,6 +958,8 @@ class GDALBandTests(SimpleTestCase):
for combo in combos:
band.data(combo[0], shape=combo[1])
if numpy:
- numpy.testing.assert_equal(band.data(), numpy.array(combo[2]).reshape(3, 3))
+ numpy.testing.assert_equal(
+ band.data(), numpy.array(combo[2]).reshape(3, 3)
+ )
else:
self.assertEqual(band.data(), list(combo[2]))
diff --git a/tests/gis_tests/gdal_tests/test_srs.py b/tests/gis_tests/gdal_tests/test_srs.py
index ddc2a65bde..320d215482 100644
--- a/tests/gis_tests/gdal_tests/test_srs.py
+++ b/tests/gis_tests/gdal_tests/test_srs.py
@@ -1,7 +1,11 @@
from unittest import skipIf
from django.contrib.gis.gdal import (
- GDAL_VERSION, AxisOrder, CoordTransform, GDALException, SpatialReference,
+ GDAL_VERSION,
+ AxisOrder,
+ CoordTransform,
+ GDALException,
+ SpatialReference,
SRSException,
)
from django.contrib.gis.geos import GEOSGeometry
@@ -15,7 +19,7 @@ class TestSRS:
setattr(self, key, value)
-WGS84_proj = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '
+WGS84_proj = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs "
# Some Spatial Reference examples
srlist = (
@@ -25,10 +29,20 @@ srlist = (
'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",'
'0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],'
'AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]',
- epsg=4326, projected=False, geographic=True, local=False,
- lin_name='unknown', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199,
- auth={'GEOGCS': ('EPSG', '4326'), 'spheroid': ('EPSG', '7030')},
- attr=(('DATUM', 'WGS_1984'), (('SPHEROID', 1), '6378137'), ('primem|authority', 'EPSG'),),
+ epsg=4326,
+ projected=False,
+ geographic=True,
+ local=False,
+ lin_name="unknown",
+ ang_name="degree",
+ lin_units=1.0,
+ ang_units=0.0174532925199,
+ auth={"GEOGCS": ("EPSG", "4326"), "spheroid": ("EPSG", "7030")},
+ attr=(
+ ("DATUM", "WGS_1984"),
+ (("SPHEROID", 1), "6378137"),
+ ("primem|authority", "EPSG"),
+ ),
),
TestSRS(
'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",'
@@ -42,13 +56,23 @@ srlist = (
'PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],'
'PARAMETER["false_northing",4000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],'
'AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32140"]]',
- epsg=32140, projected=True, geographic=False, local=False,
- lin_name='metre', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199,
- auth={'PROJCS': ('EPSG', '32140'), 'spheroid': ('EPSG', '7019'), 'unit': ('EPSG', '9001')},
+ epsg=32140,
+ projected=True,
+ geographic=False,
+ local=False,
+ lin_name="metre",
+ ang_name="degree",
+ lin_units=1.0,
+ ang_units=0.0174532925199,
+ auth={
+ "PROJCS": ("EPSG", "32140"),
+ "spheroid": ("EPSG", "7019"),
+ "unit": ("EPSG", "9001"),
+ },
attr=(
- ('DATUM', 'North_American_Datum_1983'),
- (('SPHEROID', 2), '298.257222101'),
- ('PROJECTION', 'Lambert_Conformal_Conic_2SP'),
+ ("DATUM", "North_American_Datum_1983"),
+ (("SPHEROID", 2), "298.257222101"),
+ ("PROJECTION", "Lambert_Conformal_Conic_2SP"),
),
),
TestSRS(
@@ -61,18 +85,35 @@ srlist = (
'PARAMETER["central_meridian",-99],PARAMETER["standard_parallel_1",28.3833333333333],'
'PARAMETER["standard_parallel_2",30.2833333333333],PARAMETER["latitude_of_origin",27.8333333333333],'
'UNIT["US survey foot",0.304800609601219],AXIS["Easting",EAST],AXIS["Northing",NORTH]]',
- epsg=None, projected=True, geographic=False, local=False,
- lin_name='US survey foot', ang_name='Degree', lin_units=0.3048006096012192, ang_units=0.0174532925199,
- auth={'PROJCS': (None, None)},
- attr=(('PROJCS|GeOgCs|spheroid', 'GRS 1980'), (('projcs', 9), 'UNIT'), (('projcs', 11), 'AXIS'),),
+ epsg=None,
+ projected=True,
+ geographic=False,
+ local=False,
+ lin_name="US survey foot",
+ ang_name="Degree",
+ lin_units=0.3048006096012192,
+ ang_units=0.0174532925199,
+ auth={"PROJCS": (None, None)},
+ attr=(
+ ("PROJCS|GeOgCs|spheroid", "GRS 1980"),
+ (("projcs", 9), "UNIT"),
+ (("projcs", 11), "AXIS"),
+ ),
),
# This is really ESRI format, not WKT -- but the import should work the same
TestSRS(
'LOCAL_CS["Non-Earth (Meter)",LOCAL_DATUM["Local Datum",32767],'
'UNIT["Meter",1],AXIS["X",EAST],AXIS["Y",NORTH]]',
- esri=True, epsg=None, projected=False, geographic=False, local=True,
- lin_name='Meter', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199,
- attr=(('LOCAL_DATUM', 'Local Datum'),),
+ esri=True,
+ epsg=None,
+ projected=False,
+ geographic=False,
+ local=True,
+ lin_name="Meter",
+ ang_name="degree",
+ lin_units=1.0,
+ ang_units=0.0174532925199,
+ attr=(("LOCAL_DATUM", "Local Datum"),),
),
)
@@ -83,8 +124,9 @@ well_known = (
'AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],'
'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,'
'AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]',
- wk='WGS84', name='WGS 84',
- attrs=(('GEOGCS|AUTHORITY', 1, '4326'), ('SPHEROID', 'WGS 84')),
+ wk="WGS84",
+ name="WGS 84",
+ attrs=(("GEOGCS|AUTHORITY", 1, "4326"), ("SPHEROID", "WGS 84")),
),
TestSRS(
'GEOGCS["WGS 72",DATUM["WGS_1972",SPHEROID["WGS 72",6378135,298.26,'
@@ -92,8 +134,9 @@ well_known = (
'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],'
'UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],'
'AUTHORITY["EPSG","4322"]]',
- wk='WGS72', name='WGS 72',
- attrs=(('GEOGCS|AUTHORITY', 1, '4322'), ('SPHEROID', 'WGS 72')),
+ wk="WGS72",
+ name="WGS 72",
+ attrs=(("GEOGCS|AUTHORITY", 1, "4322"), ("SPHEROID", "WGS 72")),
),
TestSRS(
'GEOGCS["NAD27",DATUM["North_American_Datum_1927",'
@@ -102,8 +145,9 @@ well_known = (
'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],'
'UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],'
'AUTHORITY["EPSG","4267"]]',
- wk='NAD27', name='NAD27',
- attrs=(('GEOGCS|AUTHORITY', 1, '4267'), ('SPHEROID', 'Clarke 1866'))
+ wk="NAD27",
+ name="NAD27",
+ attrs=(("GEOGCS|AUTHORITY", 1, "4267"), ("SPHEROID", "Clarke 1866")),
),
TestSRS(
'GEOGCS["NAD83",DATUM["North_American_Datum_1983",'
@@ -112,15 +156,16 @@ well_known = (
'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],'
'UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],'
'AUTHORITY["EPSG","4269"]]',
- wk='NAD83', name='NAD83',
- attrs=(('GEOGCS|AUTHORITY', 1, '4269'), ('SPHEROID', 'GRS 1980')),
+ wk="NAD83",
+ name="NAD83",
+ attrs=(("GEOGCS|AUTHORITY", 1, "4269"), ("SPHEROID", "GRS 1980")),
),
TestSRS(
'PROJCS["NZGD49 / Karamea Circuit",GEOGCS["NZGD49",'
'DATUM["New_Zealand_Geodetic_Datum_1949",'
'SPHEROID["International 1924",6378388,297,'
'AUTHORITY["EPSG","7022"]],'
- 'TOWGS84[59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993],'
+ "TOWGS84[59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993],"
'AUTHORITY["EPSG","6272"]],PRIMEM["Greenwich",0,'
'AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,'
'AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4272"]],'
@@ -130,13 +175,17 @@ well_known = (
'PARAMETER["scale_factor",1],PARAMETER["false_easting",300000],'
'PARAMETER["false_northing",700000],'
'UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","27216"]]',
- wk='EPSG:27216', name='NZGD49 / Karamea Circuit',
- attrs=(('PROJECTION', 'Transverse_Mercator'), ('SPHEROID', 'International 1924')),
+ wk="EPSG:27216",
+ name="NZGD49 / Karamea Circuit",
+ attrs=(
+ ("PROJECTION", "Transverse_Mercator"),
+ ("SPHEROID", "International 1924"),
+ ),
),
)
bad_srlist = (
- 'Foobar',
+ "Foobar",
'OOJCS["NAD83 / Texas South Central",GEOGCS["NAD83",'
'DATUM["North_American_Datum_1983",'
'SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],'
@@ -153,7 +202,6 @@ bad_srlist = (
class SpatialRefTest(SimpleTestCase):
-
def test01_wkt(self):
"Testing initialization on valid OGC WKT."
for s in srlist:
@@ -176,14 +224,18 @@ class SpatialRefTest(SimpleTestCase):
srs = SpatialReference(s.wkt)
# GDAL 3 strips UNIT part in the last occurrence.
self.assertEqual(
- s.wkt.replace(',UNIT["Meter",1]', ''),
- srs.wkt.replace(',UNIT["Meter",1]', ''),
+ s.wkt.replace(',UNIT["Meter",1]', ""),
+ srs.wkt.replace(',UNIT["Meter",1]', ""),
)
def test04_proj(self):
"""PROJ import and export."""
proj_parts = [
- '+proj=longlat', '+ellps=WGS84', '+towgs84=0,0,0,0,0,0,0', '+datum=WGS84', '+no_defs'
+ "+proj=longlat",
+ "+ellps=WGS84",
+ "+towgs84=0,0,0,0,0,0,0",
+ "+datum=WGS84",
+ "+no_defs",
]
srs1 = SpatialReference(srlist[0].wkt)
srs2 = SpatialReference(WGS84_proj)
@@ -197,7 +249,7 @@ class SpatialRefTest(SimpleTestCase):
srs1 = SpatialReference(s.wkt)
srs2 = SpatialReference(s.epsg)
srs3 = SpatialReference(str(s.epsg))
- srs4 = SpatialReference('EPSG:%d' % s.epsg)
+ srs4 = SpatialReference("EPSG:%d" % s.epsg)
for srs in (srs1, srs2, srs3, srs4):
for attr, expected in s.attr:
self.assertEqual(expected, srs[attr])
@@ -221,7 +273,7 @@ class SpatialRefTest(SimpleTestCase):
def test09_authority(self):
"Testing the authority name & code routines."
for s in srlist:
- if hasattr(s, 'auth'):
+ if hasattr(s, "auth"):
srs = SpatialReference(s.wkt)
for target, tup in s.auth.items():
self.assertEqual(tup[0], srs.auth_name(target))
@@ -252,21 +304,21 @@ class SpatialRefTest(SimpleTestCase):
def test12_coordtransform(self):
"Testing initialization of a CoordTransform."
- target = SpatialReference('WGS84')
+ target = SpatialReference("WGS84")
CoordTransform(SpatialReference(srlist[0].wkt), target)
def test13_attr_value(self):
"Testing the attr_value() method."
- s1 = SpatialReference('WGS84')
+ s1 = SpatialReference("WGS84")
with self.assertRaises(TypeError):
s1.__getitem__(0)
with self.assertRaises(TypeError):
- s1.__getitem__(('GEOGCS', 'foo'))
- self.assertEqual('WGS 84', s1['GEOGCS'])
- self.assertEqual('WGS_1984', s1['DATUM'])
- self.assertEqual('EPSG', s1['AUTHORITY'])
- self.assertEqual(4326, int(s1['AUTHORITY', 1]))
- self.assertIsNone(s1['FOOBAR'])
+ s1.__getitem__(("GEOGCS", "foo"))
+ self.assertEqual("WGS 84", s1["GEOGCS"])
+ self.assertEqual("WGS_1984", s1["DATUM"])
+ self.assertEqual("EPSG", s1["AUTHORITY"])
+ self.assertEqual(4326, int(s1["AUTHORITY", 1]))
+ self.assertIsNone(s1["FOOBAR"])
def test_unicode(self):
wkt = (
@@ -285,17 +337,17 @@ class SpatialRefTest(SimpleTestCase):
srs.import_wkt(wkt)
for srs in srs_list:
- self.assertEqual(srs.name, 'DHDN / Soldner 39 Langschoß')
+ self.assertEqual(srs.name, "DHDN / Soldner 39 Langschoß")
self.assertEqual(srs.wkt, wkt)
- self.assertIn('Langschoß', srs.pretty_wkt)
- self.assertIn('Langschoß', srs.xml)
+ self.assertIn("Langschoß", srs.pretty_wkt)
+ self.assertIn("Langschoß", srs.xml)
- @skipIf(GDAL_VERSION < (3, 0), 'GDAL >= 3.0 is required')
+ @skipIf(GDAL_VERSION < (3, 0), "GDAL >= 3.0 is required")
def test_axis_order(self):
wgs84_trad = SpatialReference(4326, axis_order=AxisOrder.TRADITIONAL)
wgs84_auth = SpatialReference(4326, axis_order=AxisOrder.AUTHORITY)
# Coordinate interpretation may depend on the srs axis predicate.
- pt = GEOSGeometry('POINT (992385.4472045 481455.4944650)', 2774)
+ pt = GEOSGeometry("POINT (992385.4472045 481455.4944650)", 2774)
pt_trad = pt.transform(wgs84_trad, clone=True)
self.assertAlmostEqual(pt_trad.x, -104.609, 3)
self.assertAlmostEqual(pt_trad.y, 38.255, 3)
@@ -308,18 +360,18 @@ class SpatialRefTest(SimpleTestCase):
self.assertAlmostEqual(pt_auth.y, -104.609, 3)
def test_axis_order_invalid(self):
- msg = 'SpatialReference.axis_order must be an AxisOrder instance.'
+ msg = "SpatialReference.axis_order must be an AxisOrder instance."
with self.assertRaisesMessage(ValueError, msg):
- SpatialReference(4326, axis_order='other')
+ SpatialReference(4326, axis_order="other")
@skipIf(GDAL_VERSION > (3, 0), "GDAL < 3.0 doesn't support authority.")
def test_axis_order_non_traditional_invalid(self):
- msg = 'AxisOrder.AUTHORITY is not supported in GDAL < 3.0.'
+ msg = "AxisOrder.AUTHORITY is not supported in GDAL < 3.0."
with self.assertRaisesMessage(ValueError, msg):
SpatialReference(4326, axis_order=AxisOrder.AUTHORITY)
def test_esri(self):
- srs = SpatialReference('NAD83')
+ srs = SpatialReference("NAD83")
pre_esri_wkt = srs.wkt
srs.to_esri()
self.assertNotEqual(srs.wkt, pre_esri_wkt)
diff --git a/tests/gis_tests/gdal_tests/tests.py b/tests/gis_tests/gdal_tests/tests.py
index 607753271f..d4ef7dc7ef 100644
--- a/tests/gis_tests/gdal_tests/tests.py
+++ b/tests/gis_tests/gdal_tests/tests.py
@@ -1,18 +1,16 @@
import unittest
-from django.contrib.gis.gdal import (
- GDAL_VERSION, gdal_full_version, gdal_version,
-)
+from django.contrib.gis.gdal import GDAL_VERSION, gdal_full_version, gdal_version
class GDALTest(unittest.TestCase):
def test_gdal_version(self):
if GDAL_VERSION:
- self.assertEqual(gdal_version(), ('%s.%s.%s' % GDAL_VERSION).encode())
+ self.assertEqual(gdal_version(), ("%s.%s.%s" % GDAL_VERSION).encode())
else:
- self.assertIn(b'.', gdal_version())
+ self.assertIn(b".", gdal_version())
def test_gdal_full_version(self):
full_version = gdal_full_version()
self.assertIn(gdal_version(), full_version)
- self.assertTrue(full_version.startswith(b'GDAL'))
+ self.assertTrue(full_version.startswith(b"GDAL"))
diff --git a/tests/gis_tests/geo3d/models.py b/tests/gis_tests/geo3d/models.py
index cd33a1da39..456be077f0 100644
--- a/tests/gis_tests/geo3d/models.py
+++ b/tests/gis_tests/geo3d/models.py
@@ -16,7 +16,7 @@ class City3D(NamedModel):
pointg = models.PointField(dim=3, geography=True)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
class Interstate2D(NamedModel):
@@ -27,7 +27,7 @@ class Interstate3D(NamedModel):
line = models.LineStringField(dim=3, srid=4269)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
class InterstateProj2D(NamedModel):
@@ -38,7 +38,7 @@ class InterstateProj3D(NamedModel):
line = models.LineStringField(dim=3, srid=32140)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
class Polygon2D(NamedModel):
@@ -49,11 +49,10 @@ class Polygon3D(NamedModel):
poly = models.PolygonField(dim=3, srid=32140)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
class SimpleModel(models.Model):
-
class Meta:
abstract = True
@@ -66,11 +65,11 @@ class Point3D(SimpleModel):
point = models.PointField(dim=3)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
class MultiPoint3D(SimpleModel):
mpoint = models.MultiPointField(dim=3)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py
index ad34caf7e0..2e99d741ef 100644
--- a/tests/gis_tests/geo3d/tests.py
+++ b/tests/gis_tests/geo3d/tests.py
@@ -3,32 +3,45 @@ import re
from django.contrib.gis.db.models import Extent3D, Union
from django.contrib.gis.db.models.functions import (
- AsGeoJSON, AsKML, Length, Perimeter, Scale, Translate,
+ AsGeoJSON,
+ AsKML,
+ Length,
+ Perimeter,
+ Scale,
+ Translate,
)
from django.contrib.gis.geos import GEOSGeometry, LineString, Point, Polygon
from django.test import TestCase, skipUnlessDBFeature
from ..utils import FuncTestMixin
from .models import (
- City3D, Interstate2D, Interstate3D, InterstateProj2D, InterstateProj3D,
- MultiPoint3D, Point2D, Point3D, Polygon2D, Polygon3D,
+ City3D,
+ Interstate2D,
+ Interstate3D,
+ InterstateProj2D,
+ InterstateProj3D,
+ MultiPoint3D,
+ Point2D,
+ Point3D,
+ Polygon2D,
+ Polygon3D,
)
-data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data'))
-city_file = os.path.join(data_path, 'cities', 'cities.shp')
-vrt_file = os.path.join(data_path, 'test_vrt', 'test_vrt.vrt')
+data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "data"))
+city_file = os.path.join(data_path, "cities", "cities.shp")
+vrt_file = os.path.join(data_path, "test_vrt", "test_vrt.vrt")
# The coordinates of each city, with Z values corresponding to their
# altitude in meters.
city_data = (
- ('Houston', (-95.363151, 29.763374, 18)),
- ('Dallas', (-96.801611, 32.782057, 147)),
- ('Oklahoma City', (-97.521157, 34.464642, 380)),
- ('Wellington', (174.783117, -41.315268, 14)),
- ('Pueblo', (-104.609252, 38.255001, 1433)),
- ('Lawrence', (-95.235060, 38.971823, 251)),
- ('Chicago', (-87.650175, 41.850385, 181)),
- ('Victoria', (-123.305196, 48.462611, 15)),
+ ("Houston", (-95.363151, 29.763374, 18)),
+ ("Dallas", (-96.801611, 32.782057, 147)),
+ ("Oklahoma City", (-97.521157, 34.464642, 380)),
+ ("Wellington", (174.783117, -41.315268, 14)),
+ ("Pueblo", (-104.609252, 38.255001, 1433)),
+ ("Lawrence", (-95.235060, 38.971823, 251)),
+ ("Chicago", (-87.650175, 41.850385, 181)),
+ ("Victoria", (-123.305196, 48.462611, 15)),
)
# Reference mapping of city name to its altitude (Z value).
@@ -37,32 +50,53 @@ city_dict = {name: coords for name, coords in city_data}
# 3D freeway data derived from the National Elevation Dataset:
# http://seamless.usgs.gov/products/9arc.php
interstate_data = (
- ('I-45',
- 'LINESTRING(-95.3708481 29.7765870 11.339,-95.3694580 29.7787980 4.536,'
- '-95.3690305 29.7797359 9.762,-95.3691886 29.7812450 12.448,'
- '-95.3696447 29.7850144 10.457,-95.3702511 29.7868518 9.418,'
- '-95.3706724 29.7881286 14.858,-95.3711632 29.7896157 15.386,'
- '-95.3714525 29.7936267 13.168,-95.3717848 29.7955007 15.104,'
- '-95.3717719 29.7969804 16.516,-95.3717305 29.7982117 13.923,'
- '-95.3717254 29.8000778 14.385,-95.3719875 29.8013539 15.160,'
- '-95.3720575 29.8026785 15.544,-95.3721321 29.8040912 14.975,'
- '-95.3722074 29.8050998 15.688,-95.3722779 29.8060430 16.099,'
- '-95.3733818 29.8076750 15.197,-95.3741563 29.8103686 17.268,'
- '-95.3749458 29.8129927 19.857,-95.3763564 29.8144557 15.435)',
- (11.339, 4.536, 9.762, 12.448, 10.457, 9.418, 14.858,
- 15.386, 13.168, 15.104, 16.516, 13.923, 14.385, 15.16,
- 15.544, 14.975, 15.688, 16.099, 15.197, 17.268, 19.857,
- 15.435),
- ),
+ (
+ "I-45",
+ "LINESTRING(-95.3708481 29.7765870 11.339,-95.3694580 29.7787980 4.536,"
+ "-95.3690305 29.7797359 9.762,-95.3691886 29.7812450 12.448,"
+ "-95.3696447 29.7850144 10.457,-95.3702511 29.7868518 9.418,"
+ "-95.3706724 29.7881286 14.858,-95.3711632 29.7896157 15.386,"
+ "-95.3714525 29.7936267 13.168,-95.3717848 29.7955007 15.104,"
+ "-95.3717719 29.7969804 16.516,-95.3717305 29.7982117 13.923,"
+ "-95.3717254 29.8000778 14.385,-95.3719875 29.8013539 15.160,"
+ "-95.3720575 29.8026785 15.544,-95.3721321 29.8040912 14.975,"
+ "-95.3722074 29.8050998 15.688,-95.3722779 29.8060430 16.099,"
+ "-95.3733818 29.8076750 15.197,-95.3741563 29.8103686 17.268,"
+ "-95.3749458 29.8129927 19.857,-95.3763564 29.8144557 15.435)",
+ (
+ 11.339,
+ 4.536,
+ 9.762,
+ 12.448,
+ 10.457,
+ 9.418,
+ 14.858,
+ 15.386,
+ 13.168,
+ 15.104,
+ 16.516,
+ 13.923,
+ 14.385,
+ 15.16,
+ 15.544,
+ 14.975,
+ 15.688,
+ 16.099,
+ 15.197,
+ 17.268,
+ 19.857,
+ 15.435,
+ ),
+ ),
)
# Bounding box polygon for inner-loop of Houston (in projected coordinate
# system 32140), with elevation values from the National Elevation Dataset
# (see above).
bbox_data = (
- 'POLYGON((941527.97 4225693.20,962596.48 4226349.75,963152.57 4209023.95,'
- '942051.75 4208366.38,941527.97 4225693.20))',
- (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))",
+ (21.71, 13.21, 9.12, 16.40, 21.71),
)
@@ -83,15 +117,19 @@ class Geo3DLoadingHelper:
def _load_city_data(self):
for name, pnt_data in city_data:
City3D.objects.create(
- name=name, point=Point(*pnt_data, srid=4326), pointg=Point(*pnt_data, srid=4326),
+ name=name,
+ point=Point(*pnt_data, srid=4326),
+ pointg=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)
+ 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)
@skipUnlessDBFeature("supports_3d_storage")
@@ -132,7 +170,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
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.assertIsInstance(p3d.poly, Polygon)
self.assertEqual(p3d.poly.srid, 32140)
@@ -144,8 +182,8 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
# Import here as GDAL is required for those imports
from django.contrib.gis.utils import LayerMapError, LayerMapping
- point_mapping = {'point': 'POINT'}
- mpoint_mapping = {'mpoint': 'MULTIPOINT'}
+ point_mapping = {"point": "POINT"}
+ mpoint_mapping = {"mpoint": "MULTIPOINT"}
# The VRT is 3D, but should still be able to map sans the Z.
lm = LayerMapping(Point2D, vrt_file, point_mapping, transform=False)
@@ -177,12 +215,12 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
# `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)'
+ "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)
- union = City3D.objects.aggregate(Union('point'))['point__union']
+ union = City3D.objects.aggregate(Union("point"))["point__union"]
self.assertTrue(union.hasz)
# Ordering of points in the resulting geometry may vary between implementations
self.assertEqual({p.ewkt for p in ref_union}, {p.ewkt for p in union})
@@ -195,14 +233,16 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
self._load_city_data()
# `SELECT ST_Extent3D(point) FROM geo3d_city3d;`
ref_extent3d = (-123.305196, -41.315268, 14, 174.783117, 48.462611, 1433)
- extent = City3D.objects.aggregate(Extent3D('point'))['point__extent3d']
+ extent = City3D.objects.aggregate(Extent3D("point"))["point__extent3d"]
def check_extent3d(extent3d, tol=6):
for ref_val, ext_val in zip(ref_extent3d, extent3d):
self.assertAlmostEqual(ref_val, ext_val, tol)
check_extent3d(extent)
- self.assertIsNone(City3D.objects.none().aggregate(Extent3D('point'))['point__extent3d'])
+ self.assertIsNone(
+ City3D.objects.none().aggregate(Extent3D("point"))["point__extent3d"]
+ )
@skipUnlessDBFeature("supports_3d_functions")
@@ -212,10 +252,12 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
Test KML() function with Z values.
"""
self._load_city_data()
- h = City3D.objects.annotate(kml=AsKML('point', precision=6)).get(name='Houston')
+ h = City3D.objects.annotate(kml=AsKML("point", 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>$')
+ 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))
def test_geojson(self):
@@ -223,10 +265,14 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
Test GeoJSON() function with Z values.
"""
self._load_city_data()
- h = City3D.objects.annotate(geojson=AsGeoJSON('point', precision=6)).get(name='Houston')
+ h = City3D.objects.annotate(geojson=AsGeoJSON("point", 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+)?\]}$')
+ ref_json_regex = re.compile(
+ r'^{"type":"Point","coordinates":\[-95.363151,29.763374,18(\.0+)?\]}$'
+ )
self.assertTrue(ref_json_regex.match(h.geojson))
def test_perimeter(self):
@@ -239,9 +285,13 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
ref_perim_3d = 76859.2620451
ref_perim_2d = 76859.2577803
tol = 6
- poly2d = Polygon2D.objects.annotate(perimeter=Perimeter('poly')).get(name='2D BBox')
+ poly2d = Polygon2D.objects.annotate(perimeter=Perimeter("poly")).get(
+ name="2D BBox"
+ )
self.assertAlmostEqual(ref_perim_2d, poly2d.perimeter.m, tol)
- poly3d = Polygon3D.objects.annotate(perimeter=Perimeter('poly')).get(name='3D BBox')
+ poly3d = Polygon3D.objects.annotate(perimeter=Perimeter("poly")).get(
+ name="3D BBox"
+ )
self.assertAlmostEqual(ref_perim_3d, poly3d.perimeter.m, tol)
def test_length(self):
@@ -256,9 +306,9 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
tol = 3
ref_length_2d = 4368.1721949481
ref_length_3d = 4368.62547052088
- inter2d = Interstate2D.objects.annotate(length=Length('line')).get(name='I-45')
+ inter2d = Interstate2D.objects.annotate(length=Length("line")).get(name="I-45")
self.assertAlmostEqual(ref_length_2d, inter2d.length.m, tol)
- inter3d = Interstate3D.objects.annotate(length=Length('line')).get(name='I-45')
+ inter3d = Interstate3D.objects.annotate(length=Length("line")).get(name="I-45")
self.assertAlmostEqual(ref_length_3d, inter3d.length.m, tol)
# Making sure `ST_Length3D` is used on for a projected
@@ -267,9 +317,13 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
ref_length_2d = 4367.71564892392
# `SELECT ST_Length3D(line) FROM geo3d_interstateproj3d;`
ref_length_3d = 4368.16897234101
- inter2d = InterstateProj2D.objects.annotate(length=Length('line')).get(name='I-45')
+ inter2d = InterstateProj2D.objects.annotate(length=Length("line")).get(
+ name="I-45"
+ )
self.assertAlmostEqual(ref_length_2d, inter2d.length.m, tol)
- inter3d = InterstateProj3D.objects.annotate(length=Length('line')).get(name='I-45')
+ inter3d = InterstateProj3D.objects.annotate(length=Length("line")).get(
+ name="I-45"
+ )
self.assertAlmostEqual(ref_length_3d, inter3d.length.m, tol)
def test_scale(self):
@@ -280,7 +334,7 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
# Mapping of City name to reference Z values.
zscales = (-3, 4, 23)
for zscale in zscales:
- for city in City3D.objects.annotate(scale=Scale('point', 1.0, 1.0, zscale)):
+ for city in City3D.objects.annotate(scale=Scale("point", 1.0, 1.0, zscale)):
self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z)
def test_translate(self):
@@ -290,5 +344,7 @@ class Geo3DFunctionsTests(FuncTestMixin, Geo3DLoadingHelper, TestCase):
self._load_city_data()
ztranslations = (5.23, 23, -17)
for ztrans in ztranslations:
- for city in City3D.objects.annotate(translate=Translate('point', 0, 0, ztrans)):
+ for city in City3D.objects.annotate(
+ translate=Translate("point", 0, 0, ztrans)
+ ):
self.assertEqual(city_dict[city.name][2] + ztrans, city.translate.z)
diff --git a/tests/gis_tests/geoadmin/models.py b/tests/gis_tests/geoadmin/models.py
index 115ed0624e..ea726dd68f 100644
--- a/tests/gis_tests/geoadmin/models.py
+++ b/tests/gis_tests/geoadmin/models.py
@@ -8,7 +8,7 @@ class City(models.Model):
point = models.PointField()
class Meta:
- app_label = 'geoadmin'
+ app_label = "geoadmin"
def __str__(self):
return self.name
@@ -16,18 +16,18 @@ class City(models.Model):
class CityAdminCustomWidgetKwargs(admin.GISModelAdmin):
gis_widget_kwargs = {
- 'attrs': {
- 'default_lat': 55,
- 'default_lon': 37,
+ "attrs": {
+ "default_lat": 55,
+ "default_lon": 37,
},
}
-site = admin.AdminSite(name='gis_admin_modeladmin')
+site = admin.AdminSite(name="gis_admin_modeladmin")
site.register(City, admin.ModelAdmin)
-site_gis = admin.AdminSite(name='gis_admin_gismodeladmin')
+site_gis = admin.AdminSite(name="gis_admin_gismodeladmin")
site_gis.register(City, admin.GISModelAdmin)
-site_gis_custom = admin.AdminSite(name='gis_admin_gismodeladmin')
+site_gis_custom = admin.AdminSite(name="gis_admin_gismodeladmin")
site_gis_custom.register(City, CityAdminCustomWidgetKwargs)
diff --git a/tests/gis_tests/geoadmin/tests.py b/tests/gis_tests/geoadmin/tests.py
index 2e4e4903ec..54b7073d69 100644
--- a/tests/gis_tests/geoadmin/tests.py
+++ b/tests/gis_tests/geoadmin/tests.py
@@ -4,16 +4,16 @@ from django.test import SimpleTestCase, override_settings
from .models import City, site, site_gis, site_gis_custom
-@override_settings(ROOT_URLCONF='django.contrib.gis.tests.geoadmin.urls')
+@override_settings(ROOT_URLCONF="django.contrib.gis.tests.geoadmin.urls")
class GeoAdminTest(SimpleTestCase):
admin_site = site # ModelAdmin
def test_widget_empty_string(self):
geoadmin = self.admin_site._registry[City]
- form = geoadmin.get_changelist_form(None)({'point': ''})
- with self.assertRaisesMessage(AssertionError, 'no logs'):
- with self.assertLogs('django.contrib.gis', 'ERROR'):
- output = str(form['point'])
+ form = geoadmin.get_changelist_form(None)({"point": ""})
+ with self.assertRaisesMessage(AssertionError, "no logs"):
+ with self.assertLogs("django.contrib.gis", "ERROR"):
+ output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vSerializedField required" cols="150"'
' rows="10" name="point"></textarea>',
@@ -22,9 +22,9 @@ class GeoAdminTest(SimpleTestCase):
def test_widget_invalid_string(self):
geoadmin = self.admin_site._registry[City]
- form = geoadmin.get_changelist_form(None)({'point': 'INVALID()'})
- with self.assertLogs('django.contrib.gis', 'ERROR') as cm:
- output = str(form['point'])
+ form = geoadmin.get_changelist_form(None)({"point": "INVALID()"})
+ with self.assertLogs("django.contrib.gis", "ERROR") as cm:
+ output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vSerializedField required" cols="150"'
' rows="10" name="point"></textarea>',
@@ -40,16 +40,16 @@ class GeoAdminTest(SimpleTestCase):
def test_widget_has_changed(self):
geoadmin = self.admin_site._registry[City]
form = geoadmin.get_changelist_form(None)()
- has_changed = form.fields['point'].has_changed
+ has_changed = form.fields["point"].has_changed
initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326)
- data_same = 'SRID=3857;POINT(1493879.2754093995 6894592.019687599)'
- data_almost_same = 'SRID=3857;POINT(1493879.2754093990 6894592.019687590)'
- data_changed = 'SRID=3857;POINT(1493884.0527237 6894593.8111804)'
+ data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)"
+ data_almost_same = "SRID=3857;POINT(1493879.2754093990 6894592.019687590)"
+ data_changed = "SRID=3857;POINT(1493884.0527237 6894593.8111804)"
self.assertIs(has_changed(None, data_changed), True)
- self.assertIs(has_changed(initial, ''), True)
- self.assertIs(has_changed(None, ''), False)
+ self.assertIs(has_changed(initial, ""), True)
+ self.assertIs(has_changed(None, ""), False)
self.assertIs(has_changed(initial, data_same), False)
self.assertIs(has_changed(initial, data_almost_same), False)
self.assertIs(has_changed(initial, data_changed), True)
@@ -61,15 +61,15 @@ class GISAdminTests(GeoAdminTest):
def test_default_gis_widget_kwargs(self):
geoadmin = self.admin_site._registry[City]
form = geoadmin.get_changelist_form(None)()
- widget = form['point'].field.widget
- self.assertEqual(widget.attrs['default_lat'], 47)
- self.assertEqual(widget.attrs['default_lon'], 5)
- self.assertEqual(widget.attrs['default_zoom'], 12)
+ widget = form["point"].field.widget
+ self.assertEqual(widget.attrs["default_lat"], 47)
+ self.assertEqual(widget.attrs["default_lon"], 5)
+ self.assertEqual(widget.attrs["default_zoom"], 12)
def test_custom_gis_widget_kwargs(self):
geoadmin = site_gis_custom._registry[City]
form = geoadmin.get_changelist_form(None)()
- widget = form['point'].field.widget
- self.assertEqual(widget.attrs['default_lat'], 55)
- self.assertEqual(widget.attrs['default_lon'], 37)
- self.assertEqual(widget.attrs['default_zoom'], 12)
+ widget = form["point"].field.widget
+ self.assertEqual(widget.attrs["default_lat"], 55)
+ self.assertEqual(widget.attrs["default_lon"], 37)
+ self.assertEqual(widget.attrs["default_zoom"], 12)
diff --git a/tests/gis_tests/geoadmin/urls.py b/tests/gis_tests/geoadmin/urls.py
index c27b1d7cda..ce237dbfd1 100644
--- a/tests/gis_tests/geoadmin/urls.py
+++ b/tests/gis_tests/geoadmin/urls.py
@@ -2,5 +2,5 @@ from django.contrib import admin
from django.urls import include, path
urlpatterns = [
- path('admin/', include(admin.site.urls)),
+ path("admin/", include(admin.site.urls)),
]
diff --git a/tests/gis_tests/geoadmin_deprecated/models.py b/tests/gis_tests/geoadmin_deprecated/models.py
index efd9535977..5e84d0c9fa 100644
--- a/tests/gis_tests/geoadmin_deprecated/models.py
+++ b/tests/gis_tests/geoadmin_deprecated/models.py
@@ -10,12 +10,12 @@ class City(models.Model):
point = models.PointField()
class Meta:
- app_label = 'geoadmini_deprecated'
+ app_label = "geoadmini_deprecated"
def __str__(self):
return self.name
-site = admin.AdminSite(name='admin_gis')
+site = admin.AdminSite(name="admin_gis")
with ignore_warnings(category=RemovedInDjango50Warning):
site.register(City, admin.OSMGeoAdmin)
diff --git a/tests/gis_tests/geoadmin_deprecated/tests.py b/tests/gis_tests/geoadmin_deprecated/tests.py
index 4240de98b1..a2049827a1 100644
--- a/tests/gis_tests/geoadmin_deprecated/tests.py
+++ b/tests/gis_tests/geoadmin_deprecated/tests.py
@@ -8,9 +8,8 @@ from .models import City, site
@ignore_warnings(category=RemovedInDjango50Warning)
-@override_settings(ROOT_URLCONF='django.contrib.gis.tests.geoadmin.urls')
+@override_settings(ROOT_URLCONF="django.contrib.gis.tests.geoadmin.urls")
class GeoAdminTest(SimpleTestCase):
-
def test_ensure_geographic_media(self):
geoadmin = site._registry[City]
admin_js = geoadmin.media.render_js()
@@ -20,12 +19,14 @@ class GeoAdminTest(SimpleTestCase):
delete_all_btn = """<a href="javascript:geodjango_point.clearFeatures()">Delete all Features</a>"""
original_geoadmin = site._registry[City]
- params = original_geoadmin.get_map_widget(City._meta.get_field('point')).params
- result = original_geoadmin.get_map_widget(City._meta.get_field('point'))(
- ).render('point', Point(-79.460734, 40.18476), params)
+ params = original_geoadmin.get_map_widget(City._meta.get_field("point")).params
+ result = original_geoadmin.get_map_widget(
+ City._meta.get_field("point")
+ )().render("point", Point(-79.460734, 40.18476), params)
self.assertIn(
"""geodjango_point.layers.base = new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");""",
- result)
+ result,
+ )
self.assertIn(delete_all_btn, result)
@@ -33,9 +34,10 @@ class GeoAdminTest(SimpleTestCase):
site.register(City, UnmodifiableAdmin)
try:
geoadmin = site._registry[City]
- params = geoadmin.get_map_widget(City._meta.get_field('point')).params
- result = geoadmin.get_map_widget(City._meta.get_field('point'))(
- ).render('point', Point(-79.460734, 40.18476), params)
+ params = geoadmin.get_map_widget(City._meta.get_field("point")).params
+ result = geoadmin.get_map_widget(City._meta.get_field("point"))().render(
+ "point", Point(-79.460734, 40.18476), params
+ )
self.assertNotIn(delete_all_btn, result)
finally:
@@ -44,12 +46,14 @@ class GeoAdminTest(SimpleTestCase):
def test_olmap_WMS_rendering(self):
geoadmin = admin.GeoModelAdmin(City, site)
- result = geoadmin.get_map_widget(City._meta.get_field('point'))(
- ).render('point', Point(-79.460734, 40.18476))
+ result = geoadmin.get_map_widget(City._meta.get_field("point"))().render(
+ "point", Point(-79.460734, 40.18476)
+ )
self.assertIn(
"""geodjango_point.layers.base = new OpenLayers.Layer.WMS("OpenLayers WMS", """
""""http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic', format: 'image/jpeg'});""",
- result)
+ result,
+ )
def test_olwidget_has_changed(self):
"""
@@ -57,7 +61,7 @@ class GeoAdminTest(SimpleTestCase):
"""
geoadmin = site._registry[City]
form = geoadmin.get_changelist_form(None)()
- has_changed = form.fields['point'].has_changed
+ has_changed = form.fields["point"].has_changed
initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326)
data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)"
@@ -73,30 +77,30 @@ class GeoAdminTest(SimpleTestCase):
def test_olwidget_empty_string(self):
geoadmin = site._registry[City]
- form = geoadmin.get_changelist_form(None)({'point': ''})
- with self.assertNoLogs('django.contrib.gis', 'ERROR'):
- output = str(form['point'])
+ form = geoadmin.get_changelist_form(None)({"point": ""})
+ with self.assertNoLogs("django.contrib.gis", "ERROR"):
+ output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vWKTField required" cols="150"'
' rows="10" name="point"></textarea>',
- output
+ output,
)
def test_olwidget_invalid_string(self):
geoadmin = site._registry[City]
- form = geoadmin.get_changelist_form(None)({'point': 'INVALID()'})
- with self.assertLogs('django.contrib.gis', 'ERROR') as cm:
- output = str(form['point'])
+ form = geoadmin.get_changelist_form(None)({"point": "INVALID()"})
+ with self.assertLogs("django.contrib.gis", "ERROR") as cm:
+ output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vWKTField required" cols="150"'
' rows="10" name="point"></textarea>',
- output
+ output,
)
self.assertEqual(len(cm.records), 1)
self.assertEqual(
cm.records[0].getMessage(),
"Error creating geometry from value 'INVALID()' (String input "
- "unrecognized as WKT EWKT, and HEXEWKB.)"
+ "unrecognized as WKT EWKT, and HEXEWKB.)",
)
@@ -109,9 +113,9 @@ class DeprecationTests(SimpleTestCase):
pass
msg = (
- 'django.contrib.gis.admin.GeoModelAdmin and OSMGeoAdmin are '
- 'deprecated in favor of django.contrib.admin.ModelAdmin and '
- 'django.contrib.gis.admin.GISModelAdmin.'
+ "django.contrib.gis.admin.GeoModelAdmin and OSMGeoAdmin are "
+ "deprecated in favor of django.contrib.admin.ModelAdmin and "
+ "django.contrib.gis.admin.GISModelAdmin."
)
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
DeprecatedOSMGeoAdmin(City, site)
diff --git a/tests/gis_tests/geoadmin_deprecated/urls.py b/tests/gis_tests/geoadmin_deprecated/urls.py
index c27b1d7cda..ce237dbfd1 100644
--- a/tests/gis_tests/geoadmin_deprecated/urls.py
+++ b/tests/gis_tests/geoadmin_deprecated/urls.py
@@ -2,5 +2,5 @@ from django.contrib import admin
from django.urls import include, path
urlpatterns = [
- path('admin/', include(admin.site.urls)),
+ path("admin/", include(admin.site.urls)),
]
diff --git a/tests/gis_tests/geoapp/feeds.py b/tests/gis_tests/geoapp/feeds.py
index 185f3b56e3..26ee4a8172 100644
--- a/tests/gis_tests/geoapp/feeds.py
+++ b/tests/gis_tests/geoapp/feeds.py
@@ -4,14 +4,14 @@ from .models import City
class TestGeoRSS1(feeds.Feed):
- link = '/city/'
- title = 'Test GeoDjango Cities'
+ link = "/city/"
+ title = "Test GeoDjango Cities"
def items(self):
return City.objects.all()
def item_link(self, item):
- return '/city/%s/' % item.pk
+ return "/city/%s/" % item.pk
def item_geometry(self, item):
return item.point
@@ -56,16 +56,17 @@ class TestW3CGeo3(TestGeoRSS1):
def item_geometry(self, item):
from django.contrib.gis.geos import Polygon
+
return Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
# The feed dictionary to use for URLs.
feed_dict = {
- 'rss1': TestGeoRSS1,
- 'rss2': TestGeoRSS2,
- 'atom1': TestGeoAtom1,
- 'atom2': TestGeoAtom2,
- 'w3cgeo1': TestW3CGeo1,
- 'w3cgeo2': TestW3CGeo2,
- 'w3cgeo3': TestW3CGeo3,
+ "rss1": TestGeoRSS1,
+ "rss2": TestGeoRSS2,
+ "atom1": TestGeoAtom1,
+ "atom2": TestGeoAtom2,
+ "w3cgeo1": TestW3CGeo1,
+ "w3cgeo2": TestW3CGeo2,
+ "w3cgeo3": TestW3CGeo3,
}
diff --git a/tests/gis_tests/geoapp/models.py b/tests/gis_tests/geoapp/models.py
index 9845524fb4..42619e8a75 100644
--- a/tests/gis_tests/geoapp/models.py
+++ b/tests/gis_tests/geoapp/models.py
@@ -25,7 +25,7 @@ class City(NamedModel):
point = models.PointField()
class Meta:
- app_label = 'geoapp'
+ app_label = "geoapp"
# This is an inherited model from City
@@ -34,14 +34,16 @@ class PennsylvaniaCity(City):
founded = models.DateTimeField(null=True)
class Meta:
- app_label = 'geoapp'
+ app_label = "geoapp"
class State(NamedModel):
- poly = models.PolygonField(null=gisfield_may_be_null) # Allowing NULL geometries here.
+ poly = models.PolygonField(
+ null=gisfield_may_be_null
+ ) # Allowing NULL geometries here.
class Meta:
- app_label = 'geoapp'
+ app_label = "geoapp"
class Track(NamedModel):
@@ -59,8 +61,8 @@ class UniqueTogetherModel(models.Model):
point = models.PointField()
class Meta:
- unique_together = ('city', 'point')
- required_db_features = ['supports_geometry_field_unique_index']
+ unique_together = ("city", "point")
+ required_db_features = ["supports_geometry_field_unique_index"]
class Truth(models.Model):
@@ -76,7 +78,6 @@ class MinusOneSRID(models.Model):
class NonConcreteField(models.IntegerField):
-
def db_type(self, connection):
return None
diff --git a/tests/gis_tests/geoapp/sitemaps.py b/tests/gis_tests/geoapp/sitemaps.py
index 91e5d82bb4..e3566b066e 100644
--- a/tests/gis_tests/geoapp/sitemaps.py
+++ b/tests/gis_tests/geoapp/sitemaps.py
@@ -3,6 +3,6 @@ from django.contrib.gis.sitemaps import KMLSitemap, KMZSitemap
from .models import City, Country
sitemaps = {
- 'kml': KMLSitemap([City, Country]),
- 'kmz': KMZSitemap([City, Country]),
+ "kml": KMLSitemap([City, Country]),
+ "kmz": KMZSitemap([City, Country]),
}
diff --git a/tests/gis_tests/geoapp/test_expressions.py b/tests/gis_tests/geoapp/test_expressions.py
index 6ca8615d87..d0e92a9599 100644
--- a/tests/gis_tests/geoapp/test_expressions.py
+++ b/tests/gis_tests/geoapp/test_expressions.py
@@ -8,24 +8,30 @@ from .models import City, ManyPointModel, MultiFields
class GeoExpressionsTests(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test_geometry_value_annotation(self):
p = Point(1, 1, srid=4326)
point = City.objects.annotate(p=Value(p, GeometryField(srid=4326))).first().p
self.assertEqual(point, p)
- @skipUnlessDBFeature('supports_transform')
+ @skipUnlessDBFeature("supports_transform")
def test_geometry_value_annotation_different_srid(self):
p = Point(1, 1, srid=32140)
point = City.objects.annotate(p=Value(p, GeometryField(srid=4326))).first().p
- self.assertTrue(point.equals_exact(p.transform(4326, clone=True), 10 ** -5))
+ self.assertTrue(point.equals_exact(p.transform(4326, clone=True), 10**-5))
self.assertEqual(point.srid, 4326)
- @skipUnlessDBFeature('supports_geography')
+ @skipUnlessDBFeature("supports_geography")
def test_geography_value(self):
p = Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1)))
- area = City.objects.annotate(a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))).first().a
+ area = (
+ City.objects.annotate(
+ a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))
+ )
+ .first()
+ .a
+ )
self.assertAlmostEqual(area.sq_km, 12305.1, 0)
def test_update_from_other_field(self):
@@ -37,29 +43,37 @@ class GeoExpressionsTests(TestCase):
point3=p2.transform(3857, clone=True),
)
# Updating a point to a point of the same SRID.
- ManyPointModel.objects.filter(pk=obj.pk).update(point2=F('point1'))
+ ManyPointModel.objects.filter(pk=obj.pk).update(point2=F("point1"))
obj.refresh_from_db()
self.assertEqual(obj.point2, p1)
# Updating a point to a point with a different SRID.
if connection.features.supports_transform:
- ManyPointModel.objects.filter(pk=obj.pk).update(point3=F('point1'))
+ ManyPointModel.objects.filter(pk=obj.pk).update(point3=F("point1"))
obj.refresh_from_db()
- self.assertTrue(obj.point3.equals_exact(p1.transform(3857, clone=True), 0.1))
+ self.assertTrue(
+ obj.point3.equals_exact(p1.transform(3857, clone=True), 0.1)
+ )
def test_multiple_annotation(self):
multi_field = MultiFields.objects.create(
point=Point(1, 1),
- city=City.objects.get(name='Houston'),
+ city=City.objects.get(name="Houston"),
poly=Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))),
)
- qs = City.objects.values('name').annotate(
- distance=Min(functions.Distance('multifields__point', multi_field.city.point)),
- ).annotate(count=Count('multifields'))
+ qs = (
+ City.objects.values("name")
+ .annotate(
+ distance=Min(
+ functions.Distance("multifields__point", multi_field.city.point)
+ ),
+ )
+ .annotate(count=Count("multifields"))
+ )
self.assertTrue(qs.first())
- @skipUnlessDBFeature('has_Translate_function')
+ @skipUnlessDBFeature("has_Translate_function")
def test_update_with_expression(self):
city = City.objects.create(point=Point(1, 1, srid=4326))
- City.objects.filter(pk=city.pk).update(point=functions.Translate('point', 1, 1))
+ City.objects.filter(pk=city.pk).update(point=functions.Translate("point", 1, 1))
city.refresh_from_db()
self.assertEqual(city.point, Point(2, 2, srid=4326))
diff --git a/tests/gis_tests/geoapp/test_feeds.py b/tests/gis_tests/geoapp/test_feeds.py
index 037041e66e..e247d88535 100644
--- a/tests/gis_tests/geoapp/test_feeds.py
+++ b/tests/gis_tests/geoapp/test_feeds.py
@@ -7,10 +7,10 @@ from django.test import TestCase, modify_settings, override_settings
from .models import City
-@modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'})
-@override_settings(ROOT_URLCONF='gis_tests.geoapp.urls')
+@modify_settings(INSTALLED_APPS={"append": "django.contrib.sites"})
+@override_settings(ROOT_URLCONF="gis_tests.geoapp.urls")
class GeoFeedTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
@classmethod
def setUpTestData(cls):
@@ -25,64 +25,87 @@ class GeoFeedTest(TestCase):
def test_geofeed_rss(self):
"Tests geographic feeds using GeoRSS over RSSv2."
# Uses `GEOSGeometry` in `item_geometry`
- doc1 = minidom.parseString(self.client.get('/feeds/rss1/').content)
+ doc1 = minidom.parseString(self.client.get("/feeds/rss1/").content)
# Uses a 2-tuple in `item_geometry`
- doc2 = minidom.parseString(self.client.get('/feeds/rss2/').content)
+ doc2 = minidom.parseString(self.client.get("/feeds/rss2/").content)
feed1, feed2 = doc1.firstChild, doc2.firstChild
# Making sure the box got added to the second GeoRSS feed.
- self.assertChildNodes(feed2.getElementsByTagName('channel')[0],
- ['title', 'link', 'description', 'language',
- 'lastBuildDate', 'item', 'georss:box', 'atom:link']
- )
+ self.assertChildNodes(
+ feed2.getElementsByTagName("channel")[0],
+ [
+ "title",
+ "link",
+ "description",
+ "language",
+ "lastBuildDate",
+ "item",
+ "georss:box",
+ "atom:link",
+ ],
+ )
# Incrementing through the feeds.
for feed in [feed1, feed2]:
# Ensuring the georss namespace was added to the <rss> element.
- self.assertEqual(feed.getAttribute('xmlns:georss'), 'http://www.georss.org/georss')
- chan = feed.getElementsByTagName('channel')[0]
- items = chan.getElementsByTagName('item')
+ self.assertEqual(
+ feed.getAttribute("xmlns:georss"), "http://www.georss.org/georss"
+ )
+ chan = feed.getElementsByTagName("channel")[0]
+ items = chan.getElementsByTagName("item")
self.assertEqual(len(items), City.objects.count())
# Ensuring the georss element was added to each item in the feed.
for item in items:
- self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'georss:point'])
+ self.assertChildNodes(
+ item, ["title", "link", "description", "guid", "georss:point"]
+ )
def test_geofeed_atom(self):
"Testing geographic feeds using GeoRSS over Atom."
- doc1 = minidom.parseString(self.client.get('/feeds/atom1/').content)
- doc2 = minidom.parseString(self.client.get('/feeds/atom2/').content)
+ doc1 = minidom.parseString(self.client.get("/feeds/atom1/").content)
+ doc2 = minidom.parseString(self.client.get("/feeds/atom2/").content)
feed1, feed2 = doc1.firstChild, doc2.firstChild
# Making sure the box got added to the second GeoRSS feed.
- self.assertChildNodes(feed2, ['title', 'link', 'id', 'updated', 'entry', 'georss:box'])
+ self.assertChildNodes(
+ feed2, ["title", "link", "id", "updated", "entry", "georss:box"]
+ )
for feed in [feed1, feed2]:
# Ensuring the georsss namespace was added to the <feed> element.
- self.assertEqual(feed.getAttribute('xmlns:georss'), 'http://www.georss.org/georss')
- entries = feed.getElementsByTagName('entry')
+ self.assertEqual(
+ feed.getAttribute("xmlns:georss"), "http://www.georss.org/georss"
+ )
+ entries = feed.getElementsByTagName("entry")
self.assertEqual(len(entries), City.objects.count())
# Ensuring the georss element was added to each entry in the feed.
for entry in entries:
- self.assertChildNodes(entry, ['title', 'link', 'id', 'summary', 'georss:point'])
+ self.assertChildNodes(
+ entry, ["title", "link", "id", "summary", "georss:point"]
+ )
def test_geofeed_w3c(self):
"Testing geographic feeds using W3C Geo."
- doc = minidom.parseString(self.client.get('/feeds/w3cgeo1/').content)
+ doc = minidom.parseString(self.client.get("/feeds/w3cgeo1/").content)
feed = doc.firstChild
# Ensuring the geo namespace was added to the <feed> element.
- self.assertEqual(feed.getAttribute('xmlns:geo'), 'http://www.w3.org/2003/01/geo/wgs84_pos#')
- chan = feed.getElementsByTagName('channel')[0]
- items = chan.getElementsByTagName('item')
+ self.assertEqual(
+ feed.getAttribute("xmlns:geo"), "http://www.w3.org/2003/01/geo/wgs84_pos#"
+ )
+ chan = feed.getElementsByTagName("channel")[0]
+ items = chan.getElementsByTagName("item")
self.assertEqual(len(items), City.objects.count())
# Ensuring the geo:lat and geo:lon element was added to each item in the feed.
for item in items:
- self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'geo:lat', 'geo:lon'])
+ self.assertChildNodes(
+ item, ["title", "link", "description", "guid", "geo:lat", "geo:lon"]
+ )
# Boxes and Polygons aren't allowed in W3C Geo feeds.
with self.assertRaises(ValueError): # Box in <channel>
- self.client.get('/feeds/w3cgeo2/')
+ self.client.get("/feeds/w3cgeo2/")
with self.assertRaises(ValueError): # Polygons in <entry>
- self.client.get('/feeds/w3cgeo3/')
+ self.client.get("/feeds/w3cgeo3/")
diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py
index 67e4313f3f..076e51b7a2 100644
--- a/tests/gis_tests/geoapp/test_functions.py
+++ b/tests/gis_tests/geoapp/test_functions.py
@@ -4,9 +4,7 @@ import re
from decimal import Decimal
from django.contrib.gis.db.models import GeometryField, PolygonField, functions
-from django.contrib.gis.geos import (
- GEOSGeometry, 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 NotSupportedError, connection
from django.db.models import IntegerField, Sum, Value
@@ -23,12 +21,13 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
Please keep the tests in function's alphabetic order.
"""
- fixtures = ['initial']
+
+ fixtures = ["initial"]
def test_asgeojson(self):
if not connection.features.has_AsGeoJSON_function:
with self.assertRaises(NotSupportedError):
- list(Country.objects.annotate(json=functions.AsGeoJSON('mpoly')))
+ list(Country.objects.annotate(json=functions.AsGeoJSON("mpoly")))
return
pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}'
@@ -44,32 +43,36 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
'{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},'
'"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
)
- if 'crs' in connection.features.unsupported_geojson_options:
- del houston_json['crs']
- del chicago_json['crs']
- if 'bbox' in connection.features.unsupported_geojson_options:
- del chicago_json['bbox']
- del victoria_json['bbox']
- if 'precision' in connection.features.unsupported_geojson_options:
- chicago_json['coordinates'] = [-87.650175, 41.850385]
+ if "crs" in connection.features.unsupported_geojson_options:
+ del houston_json["crs"]
+ del chicago_json["crs"]
+ if "bbox" in connection.features.unsupported_geojson_options:
+ del chicago_json["bbox"]
+ del victoria_json["bbox"]
+ if "precision" in connection.features.unsupported_geojson_options:
+ chicago_json["coordinates"] = [-87.650175, 41.850385]
# Precision argument should only be an integer
with self.assertRaises(TypeError):
- City.objects.annotate(geojson=functions.AsGeoJSON('point', precision='foo'))
+ City.objects.annotate(geojson=functions.AsGeoJSON("point", precision="foo"))
# Reference queries and values.
# SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0)
# FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo';
self.assertJSONEqual(
pueblo_json,
- City.objects.annotate(geojson=functions.AsGeoJSON('point')).get(name='Pueblo').geojson
+ City.objects.annotate(geojson=functions.AsGeoJSON("point"))
+ .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.assertJSONEqual(
- City.objects.annotate(json=functions.AsGeoJSON('point', crs=True)).get(name='Houston').json,
+ City.objects.annotate(json=functions.AsGeoJSON("point", crs=True))
+ .get(name="Houston")
+ .json,
houston_json,
)
@@ -77,9 +80,9 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# WHERE "geoapp_city"."name" = 'Houston';
# This time we include the bounding box by using the `bbox` keyword.
self.assertJSONEqual(
- City.objects.annotate(
- geojson=functions.AsGeoJSON('point', bbox=True)
- ).get(name='Victoria').geojson,
+ City.objects.annotate(geojson=functions.AsGeoJSON("point", bbox=True))
+ .get(name="Victoria")
+ .geojson,
victoria_json,
)
@@ -88,21 +91,29 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# Finally, we set every available keyword.
# MariaDB doesn't limit the number of decimals in bbox.
if connection.ops.mariadb:
- chicago_json['bbox'] = [-87.650175, 41.850385, -87.650175, 41.850385]
+ chicago_json["bbox"] = [-87.650175, 41.850385, -87.650175, 41.850385]
try:
self.assertJSONEqual(
City.objects.annotate(
- geojson=functions.AsGeoJSON('point', bbox=True, crs=True, precision=5)
- ).get(name='Chicago').geojson,
+ geojson=functions.AsGeoJSON(
+ "point", bbox=True, crs=True, precision=5
+ )
+ )
+ .get(name="Chicago")
+ .geojson,
chicago_json,
)
except AssertionError:
# Give a second chance with different coords rounding.
- chicago_json['coordinates'][1] = 41.85038
+ chicago_json["coordinates"][1] = 41.85038
self.assertJSONEqual(
City.objects.annotate(
- geojson=functions.AsGeoJSON('point', bbox=True, crs=True, precision=5)
- ).get(name='Chicago').geojson,
+ geojson=functions.AsGeoJSON(
+ "point", bbox=True, crs=True, precision=5
+ )
+ )
+ .get(name="Chicago")
+ .geojson,
chicago_json,
)
@@ -112,25 +123,29 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# non-geometry field.
qs = City.objects.all()
with self.assertRaises(TypeError):
- qs.annotate(gml=functions.AsGML('name'))
- ptown = City.objects.annotate(gml=functions.AsGML('point', precision=9)).get(name='Pueblo')
+ qs.annotate(gml=functions.AsGML("name"))
+ ptown = City.objects.annotate(gml=functions.AsGML("point", precision=9)).get(
+ name="Pueblo"
+ )
if connection.ops.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>'
+ 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>'
+ r"-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>"
)
self.assertTrue(gml_regex.match(ptown.gml))
self.assertIn(
'<gml:pos srsDimension="2">',
- City.objects.annotate(gml=functions.AsGML('point', version=3)).get(name='Pueblo').gml
+ City.objects.annotate(gml=functions.AsGML("point", version=3))
+ .get(name="Pueblo")
+ .gml,
)
@skipUnlessDBFeature("has_AsKML_function")
@@ -138,46 +153,68 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# Should throw a TypeError when trying to obtain KML from a
# non-geometry field.
with self.assertRaises(TypeError):
- City.objects.annotate(kml=functions.AsKML('name'))
+ City.objects.annotate(kml=functions.AsKML("name"))
# Ensuring the KML is as expected.
- ptown = City.objects.annotate(kml=functions.AsKML('point', precision=9)).get(name='Pueblo')
- self.assertEqual('<Point><coordinates>-104.609252,38.255001</coordinates></Point>', ptown.kml)
+ ptown = City.objects.annotate(kml=functions.AsKML("point", precision=9)).get(
+ name="Pueblo"
+ )
+ self.assertEqual(
+ "<Point><coordinates>-104.609252,38.255001</coordinates></Point>", ptown.kml
+ )
@skipUnlessDBFeature("has_AsSVG_function")
def test_assvg(self):
with self.assertRaises(TypeError):
- City.objects.annotate(svg=functions.AsSVG('point', precision='foo'))
+ City.objects.annotate(svg=functions.AsSVG("point", 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.annotate(svg=functions.AsSVG('point')).get(name='Pueblo').svg)
- self.assertEqual(svg2, City.objects.annotate(svg=functions.AsSVG('point', relative=5)).get(name='Pueblo').svg)
+ svg2 = svg1.replace("c", "")
+ self.assertEqual(
+ svg1,
+ City.objects.annotate(svg=functions.AsSVG("point")).get(name="Pueblo").svg,
+ )
+ self.assertEqual(
+ svg2,
+ City.objects.annotate(svg=functions.AsSVG("point", relative=5))
+ .get(name="Pueblo")
+ .svg,
+ )
- @skipUnlessDBFeature('has_AsWKB_function')
+ @skipUnlessDBFeature("has_AsWKB_function")
def test_aswkb(self):
- wkb = City.objects.annotate(
- wkb=functions.AsWKB(Point(1, 2, srid=4326)),
- ).first().wkb
+ wkb = (
+ City.objects.annotate(
+ wkb=functions.AsWKB(Point(1, 2, srid=4326)),
+ )
+ .first()
+ .wkb
+ )
# WKB is either XDR or NDR encoded.
self.assertIn(
bytes(wkb),
(
- b'\x00\x00\x00\x00\x01?\xf0\x00\x00\x00\x00\x00\x00@\x00\x00'
- b'\x00\x00\x00\x00\x00',
- b'\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00'
- b'\x00\x00\x00\x00\x00@',
+ b"\x00\x00\x00\x00\x01?\xf0\x00\x00\x00\x00\x00\x00@\x00\x00"
+ b"\x00\x00\x00\x00\x00",
+ b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00"
+ b"\x00\x00\x00\x00\x00@",
),
)
- @skipUnlessDBFeature('has_AsWKT_function')
+ @skipUnlessDBFeature("has_AsWKT_function")
def test_aswkt(self):
- wkt = City.objects.annotate(
- wkt=functions.AsWKT(Point(1, 2, srid=4326)),
- ).first().wkt
- self.assertEqual(wkt, 'POINT (1.0 2.0)' if connection.ops.oracle else 'POINT(1 2)')
+ wkt = (
+ City.objects.annotate(
+ wkt=functions.AsWKT(Point(1, 2, srid=4326)),
+ )
+ .first()
+ .wkt
+ )
+ self.assertEqual(
+ wkt, "POINT (1.0 2.0)" if connection.ops.oracle else "POINT(1 2)"
+ )
@skipUnlessDBFeature("has_Azimuth_function")
def test_azimuth(self):
@@ -199,7 +236,9 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
return (4 * num_seg) + 1
expected_areas = (169, 136) if connection.ops.postgis else (171, 126)
- qs = Country.objects.annotate(circle=functions.BoundingCircle('mpoly')).order_by('name')
+ qs = Country.objects.annotate(
+ circle=functions.BoundingCircle("mpoly")
+ ).order_by("name")
self.assertAlmostEqual(qs[0].circle.area, expected_areas[0], 0)
self.assertAlmostEqual(qs[1].circle.area, expected_areas[1], 0)
if connection.ops.postgis:
@@ -211,8 +250,8 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
for num_seq in tests:
with self.subTest(num_seq=num_seq):
qs = Country.objects.annotate(
- circle=functions.BoundingCircle('mpoly', num_seg=num_seq),
- ).order_by('name')
+ circle=functions.BoundingCircle("mpoly", num_seg=num_seq),
+ ).order_by("name")
if connection.ops.postgis:
self.assertGreater(qs[0].circle.area, 168.4, 0)
self.assertLess(qs[0].circle.area, 169.5, 0)
@@ -225,21 +264,27 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_Centroid_function")
def test_centroid(self):
- qs = State.objects.exclude(poly__isnull=True).annotate(centroid=functions.Centroid('poly'))
- tol = 1.8 if connection.ops.mysql else (0.1 if connection.ops.oracle else 0.00001)
+ qs = State.objects.exclude(poly__isnull=True).annotate(
+ centroid=functions.Centroid("poly")
+ )
+ tol = (
+ 1.8 if connection.ops.mysql else (0.1 if connection.ops.oracle else 0.00001)
+ )
for state in qs:
self.assertTrue(state.poly.centroid.equals_exact(state.centroid, tol))
- with self.assertRaisesMessage(TypeError, "'Centroid' takes exactly 1 argument (2 given)"):
- State.objects.annotate(centroid=functions.Centroid('poly', 'poly'))
+ with self.assertRaisesMessage(
+ TypeError, "'Centroid' takes exactly 1 argument (2 given)"
+ ):
+ State.objects.annotate(centroid=functions.Centroid("poly", "poly"))
@skipUnlessDBFeature("has_Difference_function")
def test_difference(self):
geom = Point(5, 23, srid=4326)
- qs = Country.objects.annotate(diff=functions.Difference('mpoly', geom))
+ qs = Country.objects.annotate(diff=functions.Difference("mpoly", geom))
# Oracle does something screwy with the Texas geometry.
if connection.ops.oracle:
- qs = qs.exclude(name='Texas')
+ qs = qs.exclude(name="Texas")
for c in qs:
self.assertTrue(c.mpoly.difference(geom).equals(c.diff))
@@ -248,16 +293,16 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
def test_difference_mixed_srid(self):
"""Testing with mixed SRID (Country has default 4326)."""
geom = Point(556597.4, 2632018.6, srid=3857) # Spherical Mercator
- qs = Country.objects.annotate(difference=functions.Difference('mpoly', geom))
+ qs = Country.objects.annotate(difference=functions.Difference("mpoly", geom))
# Oracle does something screwy with the Texas geometry.
if connection.ops.oracle:
- qs = qs.exclude(name='Texas')
+ qs = qs.exclude(name="Texas")
for c in qs:
self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
@skipUnlessDBFeature("has_Envelope_function")
def test_envelope(self):
- countries = Country.objects.annotate(envelope=functions.Envelope('mpoly'))
+ countries = Country.objects.annotate(envelope=functions.Envelope("mpoly"))
for country in countries:
self.assertTrue(country.envelope.equals(country.mpoly.envelope))
@@ -271,8 +316,10 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
((0, 0), (0, 5), (5, 0), (0, 0)),
((1, 1), (3, 1), (1, 3), (1, 1)),
)
- State.objects.create(name='Foo', poly=Polygon(*rings))
- st = State.objects.annotate(force_polygon_cw=functions.ForcePolygonCW('poly')).get(name='Foo')
+ State.objects.create(name="Foo", poly=Polygon(*rings))
+ st = State.objects.annotate(
+ force_polygon_cw=functions.ForcePolygonCW("poly")
+ ).get(name="Foo")
self.assertEqual(rhr_rings, st.force_polygon_cw.coords)
@skipUnlessDBFeature("has_GeoHash_function")
@@ -280,16 +327,22 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# 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.annotate(geohash=functions.GeoHash('point')).get(name='Houston')
- h2 = City.objects.annotate(geohash=functions.GeoHash('point', precision=5)).get(name='Houston')
- self.assertEqual(ref_hash, h1.geohash[:len(ref_hash)])
+ ref_hash = "9vk1mfq8jx0c8e0386z6"
+ h1 = City.objects.annotate(geohash=functions.GeoHash("point")).get(
+ name="Houston"
+ )
+ h2 = City.objects.annotate(geohash=functions.GeoHash("point", precision=5)).get(
+ name="Houston"
+ )
+ self.assertEqual(ref_hash, h1.geohash[: len(ref_hash)])
self.assertEqual(ref_hash[:5], h2.geohash)
- @skipUnlessDBFeature('has_GeometryDistance_function')
+ @skipUnlessDBFeature("has_GeometryDistance_function")
def test_geometry_distance(self):
point = Point(-90, 40, srid=4326)
- qs = City.objects.annotate(distance=functions.GeometryDistance('point', point)).order_by('distance')
+ qs = City.objects.annotate(
+ distance=functions.GeometryDistance("point", point)
+ ).order_by("distance")
distances = (
2.99091995527296,
5.33507274054713,
@@ -307,7 +360,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_Intersection_function")
def test_intersection(self):
geom = Point(5, 23, srid=4326)
- qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom))
+ qs = Country.objects.annotate(inter=functions.Intersection("mpoly", geom))
for c in qs:
if connection.features.empty_intersection_returns_none:
self.assertIsNone(c.inter)
@@ -316,12 +369,20 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_IsValid_function")
def test_isvalid(self):
- valid_geom = fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
- invalid_geom = fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))')
- State.objects.create(name='valid', poly=valid_geom)
- State.objects.create(name='invalid', poly=invalid_geom)
- valid = State.objects.filter(name='valid').annotate(isvalid=functions.IsValid('poly')).first()
- invalid = State.objects.filter(name='invalid').annotate(isvalid=functions.IsValid('poly')).first()
+ valid_geom = fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))")
+ invalid_geom = fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))")
+ State.objects.create(name="valid", poly=valid_geom)
+ State.objects.create(name="invalid", poly=invalid_geom)
+ valid = (
+ State.objects.filter(name="valid")
+ .annotate(isvalid=functions.IsValid("poly"))
+ .first()
+ )
+ invalid = (
+ State.objects.filter(name="invalid")
+ .annotate(isvalid=functions.IsValid("poly"))
+ .first()
+ )
self.assertIs(valid.isvalid, True)
self.assertIs(invalid.isvalid, False)
@@ -329,12 +390,14 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
def test_area_with_regular_aggregate(self):
# Create projected country objects, for this test to work on all backends.
for c in Country.objects.all():
- CountryWebMercator.objects.create(name=c.name, mpoly=c.mpoly.transform(3857, clone=True))
+ CountryWebMercator.objects.create(
+ name=c.name, mpoly=c.mpoly.transform(3857, clone=True)
+ )
# Test in projected coordinate system
- qs = CountryWebMercator.objects.annotate(area_sum=Sum(functions.Area('mpoly')))
+ qs = CountryWebMercator.objects.annotate(area_sum=Sum(functions.Area("mpoly")))
# Some backends (e.g. Oracle) cannot group by multipolygon values, so
# defer such fields in the aggregation query.
- for c in qs.defer('mpoly'):
+ for c in qs.defer("mpoly"):
result = c.area_sum
# If the result is a measure object, get value.
if isinstance(result, Area):
@@ -348,43 +411,68 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
CountryWebMercator(name=c.name, mpoly=c.mpoly.transform(3857, clone=True))
for c in Country.objects.all()
)
- qs = CountryWebMercator.objects.annotate(area=functions.Area('mpoly'))
- self.assertEqual(qs.get(area__lt=Area(sq_km=500000)), CountryWebMercator.objects.get(name='New Zealand'))
+ qs = CountryWebMercator.objects.annotate(area=functions.Area("mpoly"))
+ self.assertEqual(
+ qs.get(area__lt=Area(sq_km=500000)),
+ CountryWebMercator.objects.get(name="New Zealand"),
+ )
- with self.assertRaisesMessage(ValueError, 'AreaField only accepts Area measurement objects.'):
+ with self.assertRaisesMessage(
+ ValueError, "AreaField only accepts Area measurement objects."
+ ):
qs.get(area__lt=500000)
@skipUnlessDBFeature("has_LineLocatePoint_function")
def test_line_locate_point(self):
- pos_expr = functions.LineLocatePoint(LineString((0, 0), (0, 3), srid=4326), Point(0, 1, srid=4326))
- self.assertAlmostEqual(State.objects.annotate(pos=pos_expr).first().pos, 0.3333333)
+ pos_expr = functions.LineLocatePoint(
+ LineString((0, 0), (0, 3), srid=4326), Point(0, 1, srid=4326)
+ )
+ self.assertAlmostEqual(
+ State.objects.annotate(pos=pos_expr).first().pos, 0.3333333
+ )
@skipUnlessDBFeature("has_MakeValid_function")
def test_make_valid(self):
- invalid_geom = fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))')
- State.objects.create(name='invalid', poly=invalid_geom)
- invalid = State.objects.filter(name='invalid').annotate(repaired=functions.MakeValid('poly')).first()
+ invalid_geom = fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))")
+ State.objects.create(name="invalid", poly=invalid_geom)
+ invalid = (
+ State.objects.filter(name="invalid")
+ .annotate(repaired=functions.MakeValid("poly"))
+ .first()
+ )
self.assertIs(invalid.repaired.valid, True)
- self.assertTrue(invalid.repaired.equals(fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))', srid=invalid.poly.srid)))
+ self.assertTrue(
+ invalid.repaired.equals(
+ fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))", srid=invalid.poly.srid)
+ )
+ )
- @skipUnlessDBFeature('has_MakeValid_function')
+ @skipUnlessDBFeature("has_MakeValid_function")
def test_make_valid_multipolygon(self):
invalid_geom = fromstr(
- 'POLYGON((0 0, 0 1 , 1 1 , 1 0, 0 0), (10 0, 10 1, 11 1, 11 0, 10 0))'
+ "POLYGON((0 0, 0 1 , 1 1 , 1 0, 0 0), (10 0, 10 1, 11 1, 11 0, 10 0))"
+ )
+ State.objects.create(name="invalid", poly=invalid_geom)
+ invalid = (
+ State.objects.filter(name="invalid")
+ .annotate(
+ repaired=functions.MakeValid("poly"),
+ )
+ .get()
)
- State.objects.create(name='invalid', poly=invalid_geom)
- invalid = State.objects.filter(name='invalid').annotate(
- repaired=functions.MakeValid('poly'),
- ).get()
self.assertIs(invalid.repaired.valid, True)
- self.assertTrue(invalid.repaired.equals(fromstr(
- 'MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0)), '
- '((10 0, 10 1, 11 1, 11 0, 10 0)))',
- srid=invalid.poly.srid,
- )))
+ self.assertTrue(
+ invalid.repaired.equals(
+ fromstr(
+ "MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0)), "
+ "((10 0, 10 1, 11 1, 11 0, 10 0)))",
+ srid=invalid.poly.srid,
+ )
+ )
+ )
self.assertEqual(len(invalid.repaired), 2)
- @skipUnlessDBFeature('has_MakeValid_function')
+ @skipUnlessDBFeature("has_MakeValid_function")
def test_make_valid_output_field(self):
# output_field is GeometryField instance because different geometry
# types can be returned.
@@ -396,17 +484,21 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_MemSize_function")
def test_memsize(self):
- ptown = City.objects.annotate(size=functions.MemSize('point')).get(name='Pueblo')
+ ptown = City.objects.annotate(size=functions.MemSize("point")).get(
+ name="Pueblo"
+ )
# Exact value depends on database and version.
self.assertTrue(20 <= ptown.size <= 105)
@skipUnlessDBFeature("has_NumGeom_function")
def test_num_geom(self):
# Both 'countries' only have two geometries.
- for c in Country.objects.annotate(num_geom=functions.NumGeometries('mpoly')):
+ for c in Country.objects.annotate(num_geom=functions.NumGeometries("mpoly")):
self.assertEqual(2, c.num_geom)
- qs = City.objects.filter(point__isnull=False).annotate(num_geom=functions.NumGeometries('point'))
+ qs = City.objects.filter(point__isnull=False).annotate(
+ num_geom=functions.NumGeometries("point")
+ )
for city in qs:
# The results for the number of geometries on non-collections
# depends on the database.
@@ -418,10 +510,10 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_NumPoint_function")
def test_num_points(self):
coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)]
- Track.objects.create(name='Foo', line=LineString(coords))
- qs = Track.objects.annotate(num_points=functions.NumPoints('line'))
+ Track.objects.create(name="Foo", line=LineString(coords))
+ qs = Track.objects.annotate(num_points=functions.NumPoints("line"))
self.assertEqual(qs.first().num_points, 2)
- mpoly_qs = Country.objects.annotate(num_points=functions.NumPoints('mpoly'))
+ mpoly_qs = Country.objects.annotate(num_points=functions.NumPoints("mpoly"))
if not connection.features.supports_num_points_poly:
for c in mpoly_qs:
self.assertIsNone(c.num_points)
@@ -430,20 +522,24 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
for c in mpoly_qs:
self.assertEqual(c.mpoly.num_points, c.num_points)
- for c in City.objects.annotate(num_points=functions.NumPoints('point')):
+ for c in City.objects.annotate(num_points=functions.NumPoints("point")):
self.assertEqual(c.num_points, 1)
@skipUnlessDBFeature("has_PointOnSurface_function")
def test_point_on_surface(self):
- qs = Country.objects.annotate(point_on_surface=functions.PointOnSurface('mpoly'))
+ qs = Country.objects.annotate(
+ point_on_surface=functions.PointOnSurface("mpoly")
+ )
for country in qs:
self.assertTrue(country.mpoly.intersection(country.point_on_surface))
@skipUnlessDBFeature("has_Reverse_function")
def test_reverse_geom(self):
coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)]
- Track.objects.create(name='Foo', line=LineString(coords))
- track = Track.objects.annotate(reverse_geom=functions.Reverse('line')).get(name='Foo')
+ Track.objects.create(name="Foo", line=LineString(coords))
+ track = Track.objects.annotate(reverse_geom=functions.Reverse("line")).get(
+ name="Foo"
+ )
coords.reverse()
self.assertEqual(tuple(coords), track.reverse_geom.coords)
@@ -451,7 +547,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
def test_scale(self):
xfac, yfac = 2, 3
tol = 5 # The low precision tolerance is for SpatiaLite
- qs = Country.objects.annotate(scaled=functions.Scale('mpoly', xfac, yfac))
+ qs = Country.objects.annotate(scaled=functions.Scale("mpoly", xfac, yfac))
for country in qs:
for p1, p2 in zip(country.mpoly, country.scaled):
for r1, r2 in zip(p1, p2):
@@ -459,7 +555,9 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
self.assertAlmostEqual(c1[0] * xfac, c2[0], tol)
self.assertAlmostEqual(c1[1] * yfac, c2[1], tol)
# Test float/Decimal values
- qs = Country.objects.annotate(scaled=functions.Scale('mpoly', 1.5, Decimal('2.5')))
+ qs = Country.objects.annotate(
+ scaled=functions.Scale("mpoly", 1.5, Decimal("2.5"))
+ )
self.assertGreater(qs[0].scaled.area, qs[0].mpoly.area)
@skipUnlessDBFeature("has_SnapToGrid_function")
@@ -467,22 +565,24 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# 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.annotate(snap=functions.SnapToGrid('mpoly', *bad_args))
- for bad_args in (('1.0',), (1.0, None), tuple(map(str, range(4)))):
+ Country.objects.annotate(snap=functions.SnapToGrid("mpoly", *bad_args))
+ for bad_args in (("1.0",), (1.0, None), tuple(map(str, range(4)))):
with self.assertRaises(TypeError):
- Country.objects.annotate(snap=functions.SnapToGrid('mpoly', *bad_args))
+ Country.objects.annotate(snap=functions.SnapToGrid("mpoly", *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))
+ 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`.
@@ -490,60 +590,70 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# 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)))')
+ 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.annotate(
- snap=functions.SnapToGrid('mpoly', 0.1)
- ).get(name='San Marino').snap,
- tol
+ Country.objects.annotate(snap=functions.SnapToGrid("mpoly", 0.1))
+ .get(name="San Marino")
+ .snap,
+ 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)))')
+ 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.annotate(
- snap=functions.SnapToGrid('mpoly', 0.05, 0.23)
- ).get(name='San Marino').snap,
- tol
+ Country.objects.annotate(snap=functions.SnapToGrid("mpoly", 0.05, 0.23))
+ .get(name="San Marino")
+ .snap,
+ 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)))'
+ "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.annotate(
- snap=functions.SnapToGrid('mpoly', 0.05, 0.23, 0.5, 0.17)
- ).get(name='San Marino').snap,
- tol
+ snap=functions.SnapToGrid("mpoly", 0.05, 0.23, 0.5, 0.17)
+ )
+ .get(name="San Marino")
+ .snap,
+ tol,
)
)
@skipUnlessDBFeature("has_SymDifference_function")
def test_sym_difference(self):
geom = Point(5, 23, srid=4326)
- qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom))
+ qs = Country.objects.annotate(
+ sym_difference=functions.SymDifference("mpoly", geom)
+ )
# Oracle does something screwy with the Texas geometry.
if connection.ops.oracle:
- qs = qs.exclude(name='Texas')
+ qs = qs.exclude(name="Texas")
for country in qs:
- self.assertTrue(country.mpoly.sym_difference(geom).equals(country.sym_difference))
+ self.assertTrue(
+ country.mpoly.sym_difference(geom).equals(country.sym_difference)
+ )
@skipUnlessDBFeature("has_Transform_function")
def test_transform(self):
# Pre-transformed points for Houston and Pueblo.
- ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774)
+ ptown = fromstr("POINT(992363.390841912 481455.395105533)", srid=2774)
# Asserting the result of the transform operation with the values in
# the pre-transformed points.
- h = City.objects.annotate(pt=functions.Transform('point', ptown.srid)).get(name='Pueblo')
+ h = City.objects.annotate(pt=functions.Transform("point", ptown.srid)).get(
+ name="Pueblo"
+ )
self.assertEqual(2774, h.pt.srid)
# Precision is low due to version variations in PROJ and GDAL.
self.assertLess(ptown.x - h.pt.x, 1)
@@ -552,7 +662,9 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_Translate_function")
def test_translate(self):
xfac, yfac = 5, -23
- qs = Country.objects.annotate(translated=functions.Translate('mpoly', xfac, yfac))
+ qs = Country.objects.annotate(
+ translated=functions.Translate("mpoly", xfac, yfac)
+ )
for c in qs:
for p1, p2 in zip(c.mpoly, c.translated):
for r1, r2 in zip(p1, p2):
@@ -563,15 +675,18 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# Some combined function tests
@skipUnlessDBFeature(
- "has_Difference_function", "has_Intersection_function",
- "has_SymDifference_function", "has_Union_function")
+ "has_Difference_function",
+ "has_Intersection_function",
+ "has_SymDifference_function",
+ "has_Union_function",
+ )
def test_diff_intersection_union(self):
geom = Point(5, 23, srid=4326)
qs = Country.objects.all().annotate(
- difference=functions.Difference('mpoly', geom),
- sym_difference=functions.SymDifference('mpoly', geom),
- union=functions.Union('mpoly', geom),
- intersection=functions.Intersection('mpoly', geom),
+ difference=functions.Difference("mpoly", geom),
+ sym_difference=functions.SymDifference("mpoly", geom),
+ union=functions.Union("mpoly", geom),
+ intersection=functions.Intersection("mpoly", geom),
)
if connection.ops.oracle:
@@ -593,18 +708,36 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
"""Union with all combinations of geometries/geometry fields."""
geom = Point(-95.363151, 29.763374, srid=4326)
- 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)
+ 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(union))
- union = City.objects.annotate(union=functions.Union(geom, 'point')).get(name='Dallas').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)
+ 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
+ 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")
@@ -614,24 +747,28 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
geom_3857 = geom.transform(3857, clone=True)
tol = 0.001
- for city in City.objects.annotate(union=functions.Union('point', geom_3857)):
+ 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')):
+ 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.'):
+ 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.'
+ msg = "GeoFunc function requires a GeometryField in position 1, got CharField."
with self.assertRaisesMessage(TypeError, msg):
- City.objects.annotate(geo=functions.GeoFunc('name'))
+ City.objects.annotate(geo=functions.GeoFunc("name"))
- msg = 'GeoFunc function requires a geometric argument in position 1.'
+ 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')
+ City.objects.annotate(union=functions.GeoFunc(1, "point")).get(
+ name="Dallas"
+ )
diff --git a/tests/gis_tests/geoapp/test_indexes.py b/tests/gis_tests/geoapp/test_indexes.py
index ce9376d810..cd58f8e941 100644
--- a/tests/gis_tests/geoapp/test_indexes.py
+++ b/tests/gis_tests/geoapp/test_indexes.py
@@ -15,9 +15,9 @@ class SchemaIndexesTests(TransactionTestCase):
with connection.cursor() as cursor:
constraints = connection.introspection.get_constraints(cursor, table)
return {
- name: constraint['columns']
+ name: constraint["columns"]
for name, constraint in constraints.items()
- if constraint['index']
+ if constraint["index"]
}
def has_spatial_indexes(self, table):
@@ -32,31 +32,31 @@ class SchemaIndexesTests(TransactionTestCase):
def test_using_sql(self):
if not connection.ops.postgis:
- self.skipTest('This is a PostGIS-specific test.')
- index = Index(fields=['point'])
+ self.skipTest("This is a PostGIS-specific test.")
+ index = Index(fields=["point"])
editor = connection.schema_editor()
self.assertIn(
- '%s USING ' % editor.quote_name(City._meta.db_table),
+ "%s USING " % editor.quote_name(City._meta.db_table),
str(index.create_sql(City, editor)),
)
- @isolate_apps('gis_tests.geoapp')
+ @isolate_apps("gis_tests.geoapp")
def test_namespaced_db_table(self):
if not connection.ops.postgis:
- self.skipTest('PostGIS-specific test.')
+ self.skipTest("PostGIS-specific test.")
class SchemaCity(models.Model):
point = models.PointField()
class Meta:
- app_label = 'geoapp'
+ app_label = "geoapp"
db_table = 'django_schema"."geoapp_schema_city'
- index = Index(fields=['point'])
+ index = Index(fields=["point"])
editor = connection.schema_editor()
create_index_sql = str(index.create_sql(SchemaCity, editor))
self.assertIn(
- '%s USING ' % editor.quote_name(SchemaCity._meta.db_table),
+ "%s USING " % editor.quote_name(SchemaCity._meta.db_table),
create_index_sql,
)
self.assertIn(
@@ -66,12 +66,12 @@ class SchemaIndexesTests(TransactionTestCase):
def test_index_name(self):
if not self.has_spatial_indexes(City._meta.db_table):
- self.skipTest('Spatial indexes in Meta.indexes are not supported.')
- index_name = 'custom_point_index_name'
- index = Index(fields=['point'], name=index_name)
+ self.skipTest("Spatial indexes in Meta.indexes are not supported.")
+ index_name = "custom_point_index_name"
+ index = Index(fields=["point"], name=index_name)
with connection.schema_editor() as editor:
editor.add_index(City, index)
indexes = self.get_indexes(City._meta.db_table)
self.assertIn(index_name, indexes)
- self.assertEqual(indexes[index_name], ['point'])
+ self.assertEqual(indexes[index_name], ["point"])
editor.remove_index(City, index)
diff --git a/tests/gis_tests/geoapp/test_regress.py b/tests/gis_tests/geoapp/test_regress.py
index 674f19ba54..9a9226f341 100644
--- a/tests/gis_tests/geoapp/test_regress.py
+++ b/tests/gis_tests/geoapp/test_regress.py
@@ -9,20 +9,20 @@ from .models import City, PennsylvaniaCity, State, Truth
class GeoRegressionTests(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test_update(self):
"Testing QuerySet.update() (#10411)."
- pueblo = City.objects.get(name='Pueblo')
+ pueblo = City.objects.get(name="Pueblo")
bak = pueblo.point.clone()
pueblo.point.y += 0.005
pueblo.point.x += 0.005
- City.objects.filter(name='Pueblo').update(point=pueblo.point)
+ City.objects.filter(name="Pueblo").update(point=pueblo.point)
pueblo.refresh_from_db()
self.assertAlmostEqual(bak.y + 0.005, pueblo.point.y, 6)
self.assertAlmostEqual(bak.x + 0.005, pueblo.point.x, 6)
- City.objects.filter(name='Pueblo').update(point=bak)
+ City.objects.filter(name="Pueblo").update(point=bak)
pueblo.refresh_from_db()
self.assertAlmostEqual(bak.y, pueblo.point.y, 6)
self.assertAlmostEqual(bak.x, pueblo.point.x, 6)
@@ -30,45 +30,61 @@ class GeoRegressionTests(TestCase):
def test_kmz(self):
"Testing `render_to_kmz` with non-ASCII data. See #11624."
name = "Ã…land Islands"
- places = [{
- 'name': name,
- 'description': name,
- 'kml': '<Point><coordinates>5.0,23.0</coordinates></Point>'
- }]
- render_to_kmz('gis/kml/placemarks.kml', {'places': places})
+ places = [
+ {
+ "name": name,
+ "description": name,
+ "kml": "<Point><coordinates>5.0,23.0</coordinates></Point>",
+ }
+ ]
+ render_to_kmz("gis/kml/placemarks.kml", {"places": places})
@skipUnlessDBFeature("supports_extent_aggr")
def test_extent(self):
"Testing `extent` on a table with a single point. See #11827."
- pnt = City.objects.get(name='Pueblo').point
+ pnt = City.objects.get(name="Pueblo").point
ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y)
- extent = City.objects.filter(name='Pueblo').aggregate(Extent('point'))['point__extent']
+ extent = City.objects.filter(name="Pueblo").aggregate(Extent("point"))[
+ "point__extent"
+ ]
for ref_val, val in zip(ref_ext, extent):
self.assertAlmostEqual(ref_val, val, 4)
def test_unicode_date(self):
"Testing dates are converted properly, even on SpatiaLite. See #16408."
founded = datetime(1857, 5, 23)
- PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)',
- founded=founded)
- self.assertEqual(founded, PennsylvaniaCity.objects.datetimes('founded', 'day')[0])
- self.assertEqual(founded, PennsylvaniaCity.objects.aggregate(Min('founded'))['founded__min'])
+ PennsylvaniaCity.objects.create(
+ name="Mansfield",
+ county="Tioga",
+ point="POINT(-77.071445 41.823881)",
+ founded=founded,
+ )
+ self.assertEqual(
+ founded, PennsylvaniaCity.objects.datetimes("founded", "day")[0]
+ )
+ self.assertEqual(
+ founded, PennsylvaniaCity.objects.aggregate(Min("founded"))["founded__min"]
+ )
def test_empty_count(self):
"Testing that PostGISAdapter.__eq__ does check empty strings. See #13670."
# contrived example, but need a geo lookup paired with an id__in lookup
- pueblo = City.objects.get(name='Pueblo')
+ pueblo = City.objects.get(name="Pueblo")
state = State.objects.filter(poly__contains=pueblo.point)
cities_within_state = City.objects.filter(id__in=state)
# .count() should not throw TypeError in __eq__
self.assertEqual(cities_within_state.count(), 1)
- @skipUnlessDBFeature('allows_group_by_lob')
+ @skipUnlessDBFeature("allows_group_by_lob")
def test_defer_or_only_with_annotate(self):
"Regression for #16409. Make sure defer() and only() work with annotate()"
- self.assertIsInstance(list(City.objects.annotate(Count('point')).defer('name')), list)
- self.assertIsInstance(list(City.objects.annotate(Count('point')).only('name')), list)
+ self.assertIsInstance(
+ list(City.objects.annotate(Count("point")).defer("name")), list
+ )
+ self.assertIsInstance(
+ list(City.objects.annotate(Count("point")).only("name")), list
+ )
def test_boolean_conversion(self):
"Testing Boolean value conversion with the spatial backend, see #15169."
diff --git a/tests/gis_tests/geoapp/test_serializers.py b/tests/gis_tests/geoapp/test_serializers.py
index 6d4b959026..a67a4f16db 100644
--- a/tests/gis_tests/geoapp/test_serializers.py
+++ b/tests/gis_tests/geoapp/test_serializers.py
@@ -8,7 +8,7 @@ from .models import City, MultiFields, PennsylvaniaCity
class GeoJSONSerializerTests(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test_builtin_serializers(self):
"""
@@ -17,17 +17,17 @@ class GeoJSONSerializerTests(TestCase):
all_formats = set(serializers.get_serializer_formats())
public_formats = set(serializers.get_public_serializer_formats())
- self.assertIn('geojson', all_formats),
- self.assertIn('geojson', public_formats)
+ self.assertIn("geojson", all_formats),
+ self.assertIn("geojson", public_formats)
def test_serialization_base(self):
- geojson = serializers.serialize('geojson', City.objects.all().order_by('name'))
+ geojson = serializers.serialize("geojson", City.objects.all().order_by("name"))
geodata = json.loads(geojson)
- self.assertEqual(len(geodata['features']), len(City.objects.all()))
- self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point')
- self.assertEqual(geodata['features'][0]['properties']['name'], 'Chicago')
- first_city = City.objects.all().order_by('name').first()
- self.assertEqual(geodata['features'][0]['properties']['pk'], str(first_city.pk))
+ self.assertEqual(len(geodata["features"]), len(City.objects.all()))
+ self.assertEqual(geodata["features"][0]["geometry"]["type"], "Point")
+ self.assertEqual(geodata["features"][0]["properties"]["name"], "Chicago")
+ first_city = City.objects.all().order_by("name").first()
+ self.assertEqual(geodata["features"][0]["properties"]["pk"], str(first_city.pk))
def test_geometry_field_option(self):
"""
@@ -35,49 +35,56 @@ class GeoJSONSerializerTests(TestCase):
can be used to specify the field to use as the 'geometry' key.
"""
MultiFields.objects.create(
- city=City.objects.first(), name='Name', point=Point(5, 23),
- poly=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))
+ city=City.objects.first(),
+ name="Name",
+ point=Point(5, 23),
+ poly=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))),
+ )
- geojson = serializers.serialize('geojson', MultiFields.objects.all())
+ geojson = serializers.serialize("geojson", MultiFields.objects.all())
geodata = json.loads(geojson)
- self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point')
+ self.assertEqual(geodata["features"][0]["geometry"]["type"], "Point")
geojson = serializers.serialize(
- 'geojson',
- MultiFields.objects.all(),
- geometry_field='poly'
+ "geojson", MultiFields.objects.all(), geometry_field="poly"
)
geodata = json.loads(geojson)
- self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon')
+ self.assertEqual(geodata["features"][0]["geometry"]["type"], "Polygon")
# geometry_field is considered even if not in fields (#26138).
geojson = serializers.serialize(
- 'geojson',
+ "geojson",
MultiFields.objects.all(),
- geometry_field='poly',
- fields=('city',)
+ geometry_field="poly",
+ fields=("city",),
)
geodata = json.loads(geojson)
- self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon')
+ self.assertEqual(geodata["features"][0]["geometry"]["type"], "Polygon")
def test_fields_option(self):
"""
The fields option allows to define a subset of fields to be present in
the 'properties' of the generated output.
"""
- PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
+ PennsylvaniaCity.objects.create(
+ name="Mansfield", county="Tioga", point="POINT(-77.071445 41.823881)"
+ )
geojson = serializers.serialize(
- 'geojson', PennsylvaniaCity.objects.all(), fields=('county', 'point'),
+ "geojson",
+ PennsylvaniaCity.objects.all(),
+ fields=("county", "point"),
)
geodata = json.loads(geojson)
- self.assertIn('county', geodata['features'][0]['properties'])
- self.assertNotIn('founded', geodata['features'][0]['properties'])
- self.assertNotIn('pk', geodata['features'][0]['properties'])
+ self.assertIn("county", geodata["features"][0]["properties"])
+ self.assertNotIn("founded", geodata["features"][0]["properties"])
+ self.assertNotIn("pk", geodata["features"][0]["properties"])
def test_srid_option(self):
- geojson = serializers.serialize('geojson', City.objects.all().order_by('name'), srid=2847)
+ geojson = serializers.serialize(
+ "geojson", City.objects.all().order_by("name"), srid=2847
+ )
geodata = json.loads(geojson)
- coordinates = geodata['features'][0]['geometry']['coordinates']
+ coordinates = geodata["features"][0]["geometry"]["coordinates"]
# Different PROJ versions use different transformations, all are
# correct as having a 1 meter accuracy.
self.assertAlmostEqual(coordinates[0], 1564802, -1)
@@ -88,4 +95,4 @@ class GeoJSONSerializerTests(TestCase):
GeoJSON cannot be deserialized.
"""
with self.assertRaises(serializers.base.SerializerDoesNotExist):
- serializers.deserialize('geojson', '{}')
+ serializers.deserialize("geojson", "{}")
diff --git a/tests/gis_tests/geoapp/test_sitemaps.py b/tests/gis_tests/geoapp/test_sitemaps.py
index 1dbd57fd71..7907a71592 100644
--- a/tests/gis_tests/geoapp/test_sitemaps.py
+++ b/tests/gis_tests/geoapp/test_sitemaps.py
@@ -9,10 +9,11 @@ from django.test import TestCase, modify_settings, override_settings
from .models import City, Country
-@modify_settings(INSTALLED_APPS={'append': ['django.contrib.sites', 'django.contrib.sitemaps']})
-@override_settings(ROOT_URLCONF='gis_tests.geoapp.urls')
+@modify_settings(
+ INSTALLED_APPS={"append": ["django.contrib.sites", "django.contrib.sitemaps"]}
+)
+@override_settings(ROOT_URLCONF="gis_tests.geoapp.urls")
class GeoSitemapTest(TestCase):
-
@classmethod
def setUpTestData(cls):
Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
@@ -25,34 +26,46 @@ class GeoSitemapTest(TestCase):
def test_geositemap_kml(self):
"Tests KML/KMZ geographic sitemaps."
- for kml_type in ('kml', 'kmz'):
- doc = minidom.parseString(self.client.get('/sitemaps/%s.xml' % kml_type).content)
+ for kml_type in ("kml", "kmz"):
+ doc = minidom.parseString(
+ self.client.get("/sitemaps/%s.xml" % kml_type).content
+ )
# Ensuring the right sitemaps namespace is present.
urlset = doc.firstChild
- self.assertEqual(urlset.getAttribute('xmlns'), 'http://www.sitemaps.org/schemas/sitemap/0.9')
+ self.assertEqual(
+ urlset.getAttribute("xmlns"),
+ "http://www.sitemaps.org/schemas/sitemap/0.9",
+ )
- urls = urlset.getElementsByTagName('url')
+ urls = urlset.getElementsByTagName("url")
self.assertEqual(2, len(urls)) # Should only be 2 sitemaps.
for url in urls:
- self.assertChildNodes(url, ['loc'])
+ self.assertChildNodes(url, ["loc"])
# Getting the relative URL since we don't have a real site.
- kml_url = url.getElementsByTagName('loc')[0].childNodes[0].data.split('http://example.com')[1]
+ kml_url = (
+ url.getElementsByTagName("loc")[0]
+ .childNodes[0]
+ .data.split("http://example.com")[1]
+ )
- if kml_type == 'kml':
+ if kml_type == "kml":
kml_doc = minidom.parseString(self.client.get(kml_url).content)
- elif kml_type == 'kmz':
+ elif kml_type == "kmz":
# Have to decompress KMZ before parsing.
buf = BytesIO(self.client.get(kml_url).content)
with zipfile.ZipFile(buf) as zf:
self.assertEqual(1, len(zf.filelist))
- self.assertEqual('doc.kml', zf.filelist[0].filename)
- kml_doc = minidom.parseString(zf.read('doc.kml'))
+ self.assertEqual("doc.kml", zf.filelist[0].filename)
+ kml_doc = minidom.parseString(zf.read("doc.kml"))
# Ensuring the correct number of placemarks are in the KML doc.
- if 'city' in kml_url:
+ if "city" in kml_url:
model = City
- elif 'country' in kml_url:
+ elif "country" in kml_url:
model = Country
- self.assertEqual(model.objects.count(), len(kml_doc.getElementsByTagName('Placemark')))
+ self.assertEqual(
+ model.objects.count(),
+ len(kml_doc.getElementsByTagName("Placemark")),
+ )
diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py
index afd26eeb65..33d209bcdb 100644
--- a/tests/gis_tests/geoapp/tests.py
+++ b/tests/gis_tests/geoapp/tests.py
@@ -4,8 +4,16 @@ from io import StringIO
from django.contrib.gis import gdal
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,
+ GeometryCollection,
+ GEOSGeometry,
+ LinearRing,
+ LineString,
+ MultiLineString,
+ MultiPoint,
+ MultiPolygon,
+ Point,
+ Polygon,
+ fromstr,
)
from django.core.management import call_command
from django.db import DatabaseError, NotSupportedError, connection
@@ -15,13 +23,20 @@ from django.test.utils import CaptureQueriesContext
from ..utils import skipUnlessGISLookup
from .models import (
- City, Country, Feature, MinusOneSRID, MultiFields, NonConcreteModel,
- PennsylvaniaCity, State, Track,
+ City,
+ Country,
+ Feature,
+ MinusOneSRID,
+ MultiFields,
+ NonConcreteModel,
+ PennsylvaniaCity,
+ State,
+ Track,
)
class GeoModelTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test_fixtures(self):
"Testing geographic model initialization from fixtures."
@@ -34,13 +49,13 @@ class GeoModelTest(TestCase):
"Testing Lazy-Geometry support (using the GeometryProxy)."
# Testing on a Point
pnt = Point(0, 0)
- nullcity = City(name='NullCity', point=pnt)
+ nullcity = City(name="NullCity", point=pnt)
nullcity.save()
# Making sure TypeError is thrown when trying to set with an
# incompatible type.
for bad in [5, 2.0, LineString((0, 0), (1, 1))]:
- with self.assertRaisesMessage(TypeError, 'Cannot set'):
+ with self.assertRaisesMessage(TypeError, "Cannot set"):
nullcity.point = bad
# Now setting with a compatible GEOS Geometry, saving, and ensuring
@@ -54,15 +69,19 @@ class GeoModelTest(TestCase):
nullcity.save()
# Ensuring the point was saved correctly after saving
- self.assertEqual(new, City.objects.get(name='NullCity').point)
+ self.assertEqual(new, City.objects.get(name="NullCity").point)
# Setting the X and Y of the Point
nullcity.point.x = 23
nullcity.point.y = 5
# Checking assignments pre & post-save.
- self.assertNotEqual(Point(23, 5, srid=4326), City.objects.get(name='NullCity').point)
+ self.assertNotEqual(
+ Point(23, 5, srid=4326), City.objects.get(name="NullCity").point
+ )
nullcity.save()
- self.assertEqual(Point(23, 5, srid=4326), City.objects.get(name='NullCity').point)
+ self.assertEqual(
+ Point(23, 5, srid=4326), City.objects.get(name="NullCity").point
+ )
nullcity.delete()
# Testing on a Polygon
@@ -71,18 +90,18 @@ class GeoModelTest(TestCase):
# Creating a State object using a built Polygon
ply = Polygon(shell, inner)
- nullstate = State(name='NullState', poly=ply)
+ nullstate = State(name="NullState", poly=ply)
self.assertEqual(4326, nullstate.poly.srid) # SRID auto-set from None
nullstate.save()
- ns = State.objects.get(name='NullState')
+ ns = State.objects.get(name="NullState")
self.assertEqual(connection.ops.Adapter._fix_polygon(ply), ns.poly)
# Testing the `ogr` and `srs` lazy-geometry properties.
self.assertIsInstance(ns.poly.ogr, gdal.OGRGeometry)
self.assertEqual(ns.poly.wkb, ns.poly.ogr.wkb)
self.assertIsInstance(ns.poly.srs, gdal.SpatialReference)
- self.assertEqual('WGS 84', ns.poly.srs.name)
+ self.assertEqual("WGS 84", ns.poly.srs.name)
# Changing the interior ring on the poly attribute.
new_inner = LinearRing((30, 30), (30, 70), (70, 70), (70, 30), (30, 30))
@@ -92,7 +111,7 @@ class GeoModelTest(TestCase):
ns.save()
self.assertEqual(
connection.ops.Adapter._fix_polygon(ply),
- State.objects.get(name='NullState').poly
+ State.objects.get(name="NullState").poly,
)
ns.delete()
@@ -100,7 +119,7 @@ class GeoModelTest(TestCase):
def test_lookup_insert_transform(self):
"Testing automatic transform for lookups and inserts."
# San Antonio in 'WGS84' (SRID 4326)
- sa_4326 = 'POINT (-98.493183 29.424170)'
+ sa_4326 = "POINT (-98.493183 29.424170)"
wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84
# San Antonio in 'WGS 84 / Pseudo-Mercator' (SRID 3857)
other_srid_pnt = wgs_pnt.transform(3857, clone=True)
@@ -111,13 +130,13 @@ class GeoModelTest(TestCase):
tx = Country.objects.get(mpoly__contains=other_srid_pnt)
else:
tx = Country.objects.get(mpoly__intersects=other_srid_pnt)
- self.assertEqual('Texas', tx.name)
+ self.assertEqual("Texas", tx.name)
# Creating San Antonio. Remember the Alamo.
- sa = City.objects.create(name='San Antonio', point=other_srid_pnt)
+ sa = City.objects.create(name="San Antonio", point=other_srid_pnt)
# Now verifying that San Antonio was transformed correctly
- sa = City.objects.get(name='San Antonio')
+ sa = City.objects.get(name="San Antonio")
self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6)
self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6)
@@ -134,23 +153,31 @@ class GeoModelTest(TestCase):
def test_geometryfield(self):
"Testing the general GeometryField."
- Feature(name='Point', geom=Point(1, 1)).save()
- Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save()
- Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save()
- Feature(name='GeometryCollection',
- geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)),
- Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save()
-
- f_1 = Feature.objects.get(name='Point')
+ Feature(name="Point", geom=Point(1, 1)).save()
+ Feature(name="LineString", geom=LineString((0, 0), (1, 1), (5, 5))).save()
+ Feature(
+ name="Polygon",
+ geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))),
+ ).save()
+ Feature(
+ name="GeometryCollection",
+ geom=GeometryCollection(
+ Point(2, 2),
+ LineString((0, 0), (2, 2)),
+ Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))),
+ ),
+ ).save()
+
+ f_1 = Feature.objects.get(name="Point")
self.assertIsInstance(f_1.geom, Point)
self.assertEqual((1.0, 1.0), f_1.geom.tuple)
- f_2 = Feature.objects.get(name='LineString')
+ f_2 = Feature.objects.get(name="LineString")
self.assertIsInstance(f_2.geom, LineString)
self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple)
- f_3 = Feature.objects.get(name='Polygon')
+ f_3 = Feature.objects.get(name="Polygon")
self.assertIsInstance(f_3.geom, Polygon)
- f_4 = Feature.objects.get(name='GeometryCollection')
+ f_4 = Feature.objects.get(name="GeometryCollection")
self.assertIsInstance(f_4.geom, GeometryCollection)
self.assertEqual(f_3.geom, f_4.geom[2])
@@ -158,11 +185,15 @@ class GeoModelTest(TestCase):
def test_inherited_geofields(self):
"Database functions on inherited Geometry fields."
# Creating a Pennsylvanian city.
- PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
+ 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.annotate(new_point=functions.Transform('point', srid=32128))
+ qs = PennsylvaniaCity.objects.annotate(
+ new_point=functions.Transform("point", srid=32128)
+ )
self.assertEqual(1, qs.count())
for pc in qs:
@@ -171,10 +202,12 @@ class GeoModelTest(TestCase):
def test_raw_sql_query(self):
"Testing raw SQL query."
cities1 = City.objects.all()
- point_select = connection.ops.select % 'point'
- cities2 = list(City.objects.raw(
- 'select id, name, %s as point from geoapp_city' % point_select
- ))
+ point_select = connection.ops.select % "point"
+ cities2 = list(
+ City.objects.raw(
+ "select id, name, %s as point from geoapp_city" % point_select
+ )
+ )
self.assertEqual(len(cities1), len(cities2))
with self.assertNumQueries(0): # Ensure point isn't deferred.
self.assertIsInstance(cities2[0].point, Point)
@@ -184,18 +217,18 @@ class GeoModelTest(TestCase):
Test a dumpdata/loaddata cycle with geographic data.
"""
out = StringIO()
- original_data = list(City.objects.all().order_by('name'))
- call_command('dumpdata', 'geoapp.City', stdout=out)
+ original_data = list(City.objects.all().order_by("name"))
+ call_command("dumpdata", "geoapp.City", stdout=out)
result = out.getvalue()
- houston = City.objects.get(name='Houston')
+ houston = City.objects.get(name="Houston")
self.assertIn('"point": "%s"' % houston.point.ewkt, result)
# Reload now dumped data
- with tempfile.NamedTemporaryFile(mode='w', suffix='.json') as tmp:
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as tmp:
tmp.write(result)
tmp.seek(0)
- call_command('loaddata', tmp.name, verbosity=0)
- self.assertEqual(original_data, list(City.objects.all().order_by('name')))
+ call_command("loaddata", tmp.name, verbosity=0)
+ self.assertEqual(original_data, list(City.objects.all().order_by("name")))
@skipUnlessDBFeature("supports_empty_geometries")
def test_empty_geometries(self):
@@ -211,7 +244,7 @@ class GeoModelTest(TestCase):
]
for klass in geometry_classes:
g = klass(srid=4326)
- feature = Feature.objects.create(name='Empty %s' % klass.__name__, geom=g)
+ feature = Feature.objects.create(name="Empty %s" % klass.__name__, geom=g)
feature.refresh_from_db()
if klass is LinearRing:
# LinearRing isn't representable in WKB, so GEOSGeomtry.wkb
@@ -222,21 +255,21 @@ class GeoModelTest(TestCase):
class GeoLookupTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test_disjoint_lookup(self):
"Testing the `disjoint` lookup type."
- ptown = City.objects.get(name='Pueblo')
+ ptown = City.objects.get(name="Pueblo")
qs1 = City.objects.filter(point__disjoint=ptown.point)
self.assertEqual(7, qs1.count())
qs2 = State.objects.filter(poly__disjoint=ptown.point)
self.assertEqual(1, qs2.count())
- self.assertEqual('Kansas', qs2[0].name)
+ self.assertEqual("Kansas", qs2[0].name)
def test_contains_contained_lookups(self):
"Testing the 'contained', 'contains', and 'bbcontains' lookup types."
# Getting Texas, yes we were a country -- once ;)
- texas = Country.objects.get(name='Texas')
+ texas = Country.objects.get(name="Texas")
# Seeing what cities are in Texas, should get Houston and Dallas,
# and Oklahoma City because 'contained' only checks on the
@@ -244,69 +277,80 @@ class GeoLookupTest(TestCase):
if connection.features.supports_contained_lookup:
qs = City.objects.filter(point__contained=texas.mpoly)
self.assertEqual(3, qs.count())
- cities = ['Houston', 'Dallas', 'Oklahoma City']
+ cities = ["Houston", "Dallas", "Oklahoma City"]
for c in qs:
self.assertIn(c.name, cities)
# Pulling out some cities.
- houston = City.objects.get(name='Houston')
- wellington = City.objects.get(name='Wellington')
- pueblo = City.objects.get(name='Pueblo')
- okcity = City.objects.get(name='Oklahoma City')
- lawrence = City.objects.get(name='Lawrence')
+ houston = City.objects.get(name="Houston")
+ wellington = City.objects.get(name="Wellington")
+ pueblo = City.objects.get(name="Pueblo")
+ okcity = City.objects.get(name="Oklahoma City")
+ lawrence = City.objects.get(name="Lawrence")
# Now testing contains on the countries using the points for
# Houston and Wellington.
tx = Country.objects.get(mpoly__contains=houston.point) # Query w/GEOSGeometry
- nz = Country.objects.get(mpoly__contains=wellington.point.hex) # Query w/EWKBHEX
- self.assertEqual('Texas', tx.name)
- self.assertEqual('New Zealand', nz.name)
+ nz = Country.objects.get(
+ mpoly__contains=wellington.point.hex
+ ) # Query w/EWKBHEX
+ self.assertEqual("Texas", tx.name)
+ self.assertEqual("New Zealand", nz.name)
# Testing `contains` on the states using the point for Lawrence.
ks = State.objects.get(poly__contains=lawrence.point)
- self.assertEqual('Kansas', ks.name)
+ self.assertEqual("Kansas", ks.name)
# Pueblo and Oklahoma City (even though OK City is within the bounding box of Texas)
# are not contained in Texas or New Zealand.
- self.assertEqual(len(Country.objects.filter(mpoly__contains=pueblo.point)), 0) # Query w/GEOSGeometry object
- self.assertEqual(len(Country.objects.filter(mpoly__contains=okcity.point.wkt)), 0) # Query w/WKT
+ self.assertEqual(
+ len(Country.objects.filter(mpoly__contains=pueblo.point)), 0
+ ) # Query w/GEOSGeometry object
+ self.assertEqual(
+ len(Country.objects.filter(mpoly__contains=okcity.point.wkt)), 0
+ ) # Query w/WKT
# OK City is contained w/in bounding box of Texas.
if connection.features.supports_bbcontains_lookup:
qs = Country.objects.filter(mpoly__bbcontains=okcity.point)
self.assertEqual(1, len(qs))
- self.assertEqual('Texas', qs[0].name)
+ self.assertEqual("Texas", qs[0].name)
@skipUnlessDBFeature("supports_crosses_lookup")
def test_crosses_lookup(self):
- Track.objects.create(
- name='Line1',
- line=LineString([(-95, 29), (-60, 0)])
- )
+ Track.objects.create(name="Line1", line=LineString([(-95, 29), (-60, 0)]))
self.assertEqual(
- Track.objects.filter(line__crosses=LineString([(-95, 0), (-60, 29)])).count(),
- 1
+ Track.objects.filter(
+ line__crosses=LineString([(-95, 0), (-60, 29)])
+ ).count(),
+ 1,
)
self.assertEqual(
- Track.objects.filter(line__crosses=LineString([(-95, 30), (0, 30)])).count(),
- 0
+ Track.objects.filter(
+ line__crosses=LineString([(-95, 30), (0, 30)])
+ ).count(),
+ 0,
)
@skipUnlessDBFeature("supports_isvalid_lookup")
def test_isvalid_lookup(self):
- invalid_geom = fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))')
- State.objects.create(name='invalid', poly=invalid_geom)
+ invalid_geom = fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))")
+ State.objects.create(name="invalid", poly=invalid_geom)
qs = State.objects.all()
- if connection.ops.oracle or (connection.ops.mysql and connection.mysql_version < (8, 0, 0)):
+ if connection.ops.oracle or (
+ connection.ops.mysql and connection.mysql_version < (8, 0, 0)
+ ):
# Kansas has adjacent vertices with distance 6.99244813842e-12
# which is smaller than the default Oracle tolerance.
# It's invalid on MySQL < 8 also.
- qs = qs.exclude(name='Kansas')
- self.assertEqual(State.objects.filter(name='Kansas', poly__isvalid=False).count(), 1)
+ qs = qs.exclude(name="Kansas")
+ self.assertEqual(
+ State.objects.filter(name="Kansas", poly__isvalid=False).count(), 1
+ )
self.assertEqual(qs.filter(poly__isvalid=False).count(), 1)
self.assertEqual(qs.filter(poly__isvalid=True).count(), qs.count() - 1)
- @skipUnlessGISLookup('left', 'right')
+ @skipUnlessGISLookup("left", "right")
def test_left_right_lookups(self):
"Testing the 'left' and 'right' lookup types."
# Left: A << B => true if xmax(A) < xmin(B)
@@ -314,22 +358,28 @@ class GeoLookupTest(TestCase):
# See: BOX2D_left() and BOX2D_right() in lwgeom_box2dfloat4.c in PostGIS source.
# Getting the borders for Colorado & Kansas
- co_border = State.objects.get(name='Colorado').poly
- ks_border = State.objects.get(name='Kansas').poly
+ co_border = State.objects.get(name="Colorado").poly
+ ks_border = State.objects.get(name="Kansas").poly
# Note: Wellington has an 'X' value of 174, so it will not be considered
# to the left of CO.
# These cities should be strictly to the right of the CO border.
- cities = ['Houston', 'Dallas', 'Oklahoma City',
- 'Lawrence', 'Chicago', 'Wellington']
+ cities = [
+ "Houston",
+ "Dallas",
+ "Oklahoma City",
+ "Lawrence",
+ "Chicago",
+ "Wellington",
+ ]
qs = City.objects.filter(point__right=co_border)
self.assertEqual(6, len(qs))
for c in qs:
self.assertIn(c.name, cities)
# These cities should be strictly to the right of the KS border.
- cities = ['Chicago', 'Wellington']
+ cities = ["Chicago", "Wellington"]
qs = City.objects.filter(point__right=ks_border)
self.assertEqual(2, len(qs))
for c in qs:
@@ -338,9 +388,9 @@ class GeoLookupTest(TestCase):
# Note: Wellington has an 'X' value of 174, so it will not be considered
# to the left of CO.
vic = City.objects.get(point__left=co_border)
- self.assertEqual('Victoria', vic.name)
+ self.assertEqual("Victoria", vic.name)
- cities = ['Pueblo', 'Victoria']
+ cities = ["Pueblo", "Victoria"]
qs = City.objects.filter(point__left=ks_border)
self.assertEqual(2, len(qs))
for c in qs:
@@ -348,32 +398,32 @@ class GeoLookupTest(TestCase):
@skipUnlessGISLookup("strictly_above", "strictly_below")
def test_strictly_above_below_lookups(self):
- dallas = City.objects.get(name='Dallas')
+ dallas = City.objects.get(name="Dallas")
self.assertQuerysetEqual(
- City.objects.filter(point__strictly_above=dallas.point).order_by('name'),
- ['Chicago', 'Lawrence', 'Oklahoma City', 'Pueblo', 'Victoria'],
- lambda b: b.name
+ City.objects.filter(point__strictly_above=dallas.point).order_by("name"),
+ ["Chicago", "Lawrence", "Oklahoma City", "Pueblo", "Victoria"],
+ lambda b: b.name,
)
self.assertQuerysetEqual(
- City.objects.filter(point__strictly_below=dallas.point).order_by('name'),
- ['Houston', 'Wellington'],
- lambda b: b.name
+ City.objects.filter(point__strictly_below=dallas.point).order_by("name"),
+ ["Houston", "Wellington"],
+ lambda b: b.name,
)
def test_equals_lookups(self):
"Testing the 'same_as' and 'equals' lookup types."
- pnt = fromstr('POINT (-95.363151 29.763374)', srid=4326)
+ pnt = fromstr("POINT (-95.363151 29.763374)", srid=4326)
c1 = City.objects.get(point=pnt)
c2 = City.objects.get(point__same_as=pnt)
c3 = City.objects.get(point__equals=pnt)
for c in [c1, c2, c3]:
- self.assertEqual('Houston', c.name)
+ self.assertEqual("Houston", c.name)
@skipUnlessDBFeature("supports_null_geometries")
def test_null_geometries(self):
"Testing NULL geometry support, and the `isnull` lookup type."
# Creating a state with a NULL boundary.
- State.objects.create(name='Puerto Rico')
+ State.objects.create(name="Puerto Rico")
# Querying for both NULL and Non-NULL values.
nullqs = State.objects.filter(poly__isnull=True)
@@ -381,7 +431,7 @@ class GeoLookupTest(TestCase):
# Puerto Rico should be NULL (it's a commonwealth unincorporated territory)
self.assertEqual(1, len(nullqs))
- self.assertEqual('Puerto Rico', nullqs[0].name)
+ self.assertEqual("Puerto Rico", nullqs[0].name)
# GeometryField=None is an alias for __isnull=True.
self.assertCountEqual(State.objects.filter(poly=None), nullqs)
self.assertCountEqual(State.objects.exclude(poly=None), validqs)
@@ -389,110 +439,135 @@ class GeoLookupTest(TestCase):
# The valid states should be Colorado & Kansas
self.assertEqual(2, len(validqs))
state_names = [s.name for s in validqs]
- self.assertIn('Colorado', state_names)
- self.assertIn('Kansas', state_names)
+ self.assertIn("Colorado", state_names)
+ self.assertIn("Kansas", state_names)
# Saving another commonwealth w/a NULL geometry.
- nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
+ nmi = State.objects.create(name="Northern Mariana Islands", poly=None)
self.assertIsNone(nmi.poly)
# Assigning a geometry and saving -- then UPDATE back to NULL.
- nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
+ nmi.poly = "POLYGON((0 0,1 0,1 1,1 0,0 0))"
nmi.save()
- State.objects.filter(name='Northern Mariana Islands').update(poly=None)
- self.assertIsNone(State.objects.get(name='Northern Mariana Islands').poly)
+ State.objects.filter(name="Northern Mariana Islands").update(poly=None)
+ self.assertIsNone(State.objects.get(name="Northern Mariana Islands").poly)
- @skipUnlessDBFeature('supports_null_geometries', 'supports_crosses_lookup', 'supports_relate_lookup')
+ @skipUnlessDBFeature(
+ "supports_null_geometries", "supports_crosses_lookup", "supports_relate_lookup"
+ )
def test_null_geometries_excluded_in_lookups(self):
"""NULL features are excluded in spatial lookup functions."""
- null = State.objects.create(name='NULL', poly=None)
+ null = State.objects.create(name="NULL", poly=None)
queries = [
- ('equals', Point(1, 1)),
- ('disjoint', Point(1, 1)),
- ('touches', Point(1, 1)),
- ('crosses', LineString((0, 0), (1, 1), (5, 5))),
- ('within', Point(1, 1)),
- ('overlaps', LineString((0, 0), (1, 1), (5, 5))),
- ('contains', LineString((0, 0), (1, 1), (5, 5))),
- ('intersects', LineString((0, 0), (1, 1), (5, 5))),
- ('relate', (Point(1, 1), 'T*T***FF*')),
- ('same_as', Point(1, 1)),
- ('exact', Point(1, 1)),
- ('coveredby', Point(1, 1)),
- ('covers', Point(1, 1)),
+ ("equals", Point(1, 1)),
+ ("disjoint", Point(1, 1)),
+ ("touches", Point(1, 1)),
+ ("crosses", LineString((0, 0), (1, 1), (5, 5))),
+ ("within", Point(1, 1)),
+ ("overlaps", LineString((0, 0), (1, 1), (5, 5))),
+ ("contains", LineString((0, 0), (1, 1), (5, 5))),
+ ("intersects", LineString((0, 0), (1, 1), (5, 5))),
+ ("relate", (Point(1, 1), "T*T***FF*")),
+ ("same_as", Point(1, 1)),
+ ("exact", Point(1, 1)),
+ ("coveredby", Point(1, 1)),
+ ("covers", Point(1, 1)),
]
for lookup, geom in queries:
with self.subTest(lookup=lookup):
- self.assertNotIn(null, State.objects.filter(**{'poly__%s' % lookup: geom}))
+ self.assertNotIn(
+ null, State.objects.filter(**{"poly__%s" % lookup: geom})
+ )
def test_wkt_string_in_lookup(self):
# Valid WKT strings don't emit error logs.
- with self.assertNoLogs('django.contrib.gis', 'ERROR'):
- State.objects.filter(poly__intersects='LINESTRING(0 0, 1 1, 5 5)')
+ with self.assertNoLogs("django.contrib.gis", "ERROR"):
+ State.objects.filter(poly__intersects="LINESTRING(0 0, 1 1, 5 5)")
@skipUnlessDBFeature("supports_relate_lookup")
def test_relate_lookup(self):
"Testing the 'relate' lookup type."
# To make things more interesting, we will have our Texas reference point in
# different SRIDs.
- pnt1 = fromstr('POINT (649287.0363174 4177429.4494686)', srid=2847)
- pnt2 = fromstr('POINT(-98.4919715741052 29.4333344025053)', srid=4326)
+ 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 raises a TypeError when
# initializing the QuerySet.
with self.assertRaises(ValueError):
- Country.objects.filter(mpoly__relate=(23, 'foo'))
+ Country.objects.filter(mpoly__relate=(23, "foo"))
# Making sure the right exception is raised for the given
# bad arguments.
- for bad_args, e in [((pnt1, 0), ValueError), ((pnt2, 'T*T***FF*', 0), ValueError)]:
+ for bad_args, e in [
+ ((pnt1, 0), ValueError),
+ ((pnt2, "T*T***FF*", 0), ValueError),
+ ]:
qs = Country.objects.filter(mpoly__relate=bad_args)
with self.assertRaises(e):
qs.count()
- contains_mask = 'T*T***FF*'
- within_mask = 'T*F**F***'
- intersects_mask = 'T********'
+ contains_mask = "T*T***FF*"
+ within_mask = "T*F**F***"
+ intersects_mask = "T********"
# Relate works differently on Oracle.
if connection.ops.oracle:
- contains_mask = 'contains'
- within_mask = 'inside'
+ contains_mask = "contains"
+ within_mask = "inside"
# TODO: This is not quite the same as the PostGIS mask above
- intersects_mask = 'overlapbdyintersect'
+ intersects_mask = "overlapbdyintersect"
# Testing contains relation mask.
if connection.features.supports_transform:
self.assertEqual(
Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name,
- 'Texas',
+ "Texas",
)
- self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name)
+ self.assertEqual(
+ "Texas", Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name
+ )
# Testing within relation mask.
- ks = State.objects.get(name='Kansas')
- self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, within_mask)).name)
+ ks = State.objects.get(name="Kansas")
+ self.assertEqual(
+ "Lawrence", City.objects.get(point__relate=(ks.poly, within_mask)).name
+ )
# Testing intersection relation mask.
if not connection.ops.oracle:
if connection.features.supports_transform:
self.assertEqual(
Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name,
- 'Texas',
+ "Texas",
)
- self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name)
- self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name)
+ self.assertEqual(
+ "Texas", Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name
+ )
+ self.assertEqual(
+ "Lawrence",
+ City.objects.get(point__relate=(ks.poly, intersects_mask)).name,
+ )
# With a complex geometry expression
- mask = 'anyinteract' if connection.ops.oracle else within_mask
- self.assertFalse(City.objects.exclude(point__relate=(functions.Union('point', 'point'), mask)))
+ mask = "anyinteract" if connection.ops.oracle else within_mask
+ self.assertFalse(
+ City.objects.exclude(
+ point__relate=(functions.Union("point", "point"), mask)
+ )
+ )
def test_gis_lookups_with_complex_expressions(self):
- multiple_arg_lookups = {'dwithin', 'relate'} # These lookups are tested elsewhere.
+ multiple_arg_lookups = {
+ "dwithin",
+ "relate",
+ } # These lookups are tested elsewhere.
lookups = connection.ops.gis_operators.keys() - multiple_arg_lookups
- self.assertTrue(lookups, 'No lookups found')
+ self.assertTrue(lookups, "No lookups found")
for lookup in lookups:
with self.subTest(lookup):
- City.objects.filter(**{'point__' + lookup: functions.Union('point', 'point')}).exists()
+ City.objects.filter(
+ **{"point__" + lookup: functions.Union("point", "point")}
+ ).exists()
def test_subquery_annotation(self):
multifields = MultiFields.objects.create(
@@ -501,18 +576,20 @@ class GeoLookupTest(TestCase):
poly=Polygon.from_bbox((0, 0, 2, 2)),
)
qs = MultiFields.objects.annotate(
- city_point=Subquery(City.objects.filter(
- id=OuterRef('city'),
- ).values('point')),
+ city_point=Subquery(
+ City.objects.filter(
+ id=OuterRef("city"),
+ ).values("point")
+ ),
).filter(
- city_point__within=F('poly'),
+ city_point__within=F("poly"),
)
self.assertEqual(qs.get(), multifields)
class GeoQuerySetTest(TestCase):
# TODO: GeoQuerySet is removed, organize these test better.
- fixtures = ['initial']
+ fixtures = ["initial"]
@skipUnlessDBFeature("supports_extent_aggr")
def test_extent(self):
@@ -522,21 +599,30 @@ class GeoQuerySetTest(TestCase):
# Reference query:
# `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');`
# => BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203)
- expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
+ expected = (
+ -96.8016128540039,
+ 29.7633724212646,
+ -95.3631439208984,
+ 32.782058715820,
+ )
- qs = City.objects.filter(name__in=('Houston', 'Dallas'))
- extent = qs.aggregate(Extent('point'))['point__extent']
+ qs = City.objects.filter(name__in=("Houston", "Dallas"))
+ extent = qs.aggregate(Extent("point"))["point__extent"]
for val, exp in zip(extent, expected):
self.assertAlmostEqual(exp, val, 4)
- self.assertIsNone(City.objects.filter(name=('Smalltown')).aggregate(Extent('point'))['point__extent'])
+ self.assertIsNone(
+ City.objects.filter(name=("Smalltown")).aggregate(Extent("point"))[
+ "point__extent"
+ ]
+ )
@skipUnlessDBFeature("supports_extent_aggr")
def test_extent_with_limit(self):
"""
Testing if extent supports limit.
"""
- extent1 = City.objects.all().aggregate(Extent('point'))['point__extent']
- extent2 = City.objects.all()[:3].aggregate(Extent('point'))['point__extent']
+ extent1 = City.objects.all().aggregate(Extent("point"))["point__extent"]
+ extent2 = City.objects.all()[:3].aggregate(Extent("point"))["point__extent"]
self.assertNotEqual(extent1, extent2)
def test_make_line(self):
@@ -545,90 +631,94 @@ class GeoQuerySetTest(TestCase):
"""
if not connection.features.supports_make_line_aggr:
with self.assertRaises(NotSupportedError):
- City.objects.all().aggregate(MakeLine('point'))
+ City.objects.all().aggregate(MakeLine("point"))
return
# MakeLine on an inappropriate field returns simply None
- self.assertIsNone(State.objects.aggregate(MakeLine('poly'))['poly__makeline'])
+ self.assertIsNone(State.objects.aggregate(MakeLine("poly"))["poly__makeline"])
# Reference query:
# SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city;
ref_line = GEOSGeometry(
- 'LINESTRING(-95.363151 29.763374,-96.801611 32.782057,'
- '-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,'
- '-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)',
- srid=4326
+ "LINESTRING(-95.363151 29.763374,-96.801611 32.782057,"
+ "-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,"
+ "-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)",
+ srid=4326,
)
# We check for equality with a tolerance of 10e-5 which is a lower bound
# of the precisions of ref_line coordinates
- line = City.objects.aggregate(MakeLine('point'))['point__makeline']
+ line = City.objects.aggregate(MakeLine("point"))["point__makeline"]
self.assertTrue(
- ref_line.equals_exact(line, tolerance=10e-5),
- "%s != %s" % (ref_line, line)
+ ref_line.equals_exact(line, tolerance=10e-5), "%s != %s" % (ref_line, line)
)
- @skipUnlessDBFeature('supports_union_aggr')
+ @skipUnlessDBFeature("supports_union_aggr")
def test_unionagg(self):
"""
Testing the `Union` aggregate.
"""
- tx = Country.objects.get(name='Texas').mpoly
+ tx = Country.objects.get(name="Texas").mpoly
# Houston, Dallas -- Ordering may differ depending on backend or GEOS version.
- union = GEOSGeometry('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
+ union = GEOSGeometry("MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)")
qs = City.objects.filter(point__within=tx)
with self.assertRaises(ValueError):
- qs.aggregate(Union('name'))
+ qs.aggregate(Union("name"))
# Using `field_name` keyword argument in one query and specifying an
# order in the other (which should not be used because this is
# an aggregate method on a spatial column)
- u1 = qs.aggregate(Union('point'))['point__union']
- u2 = qs.order_by('name').aggregate(Union('point'))['point__union']
+ u1 = qs.aggregate(Union("point"))["point__union"]
+ u2 = qs.order_by("name").aggregate(Union("point"))["point__union"]
self.assertTrue(union.equals(u1))
self.assertTrue(union.equals(u2))
- qs = City.objects.filter(name='NotACity')
- self.assertIsNone(qs.aggregate(Union('point'))['point__union'])
+ qs = City.objects.filter(name="NotACity")
+ self.assertIsNone(qs.aggregate(Union("point"))["point__union"])
- @skipUnlessDBFeature('supports_union_aggr')
+ @skipUnlessDBFeature("supports_union_aggr")
def test_geoagg_subquery(self):
- tx = Country.objects.get(name='Texas')
- union = GEOSGeometry('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
+ tx = Country.objects.get(name="Texas")
+ union = GEOSGeometry("MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)")
# Use distinct() to force the usage of a subquery for aggregation.
with CaptureQueriesContext(connection) as ctx:
- self.assertIs(union.equals(
- City.objects.filter(point__within=tx.mpoly).distinct().aggregate(
- Union('point'),
- )['point__union'],
- ), True)
- self.assertIn('subquery', ctx.captured_queries[0]['sql'])
-
- @skipUnlessDBFeature('supports_tolerance_parameter')
+ self.assertIs(
+ union.equals(
+ City.objects.filter(point__within=tx.mpoly)
+ .distinct()
+ .aggregate(
+ Union("point"),
+ )["point__union"],
+ ),
+ True,
+ )
+ self.assertIn("subquery", ctx.captured_queries[0]["sql"])
+
+ @skipUnlessDBFeature("supports_tolerance_parameter")
def test_unionagg_tolerance(self):
City.objects.create(
- point=fromstr('POINT(-96.467222 32.751389)', srid=4326),
- name='Forney',
+ point=fromstr("POINT(-96.467222 32.751389)", srid=4326),
+ name="Forney",
)
- tx = Country.objects.get(name='Texas').mpoly
+ tx = Country.objects.get(name="Texas").mpoly
# Tolerance is greater than distance between Forney and Dallas, that's
# why Dallas is ignored.
forney_houston = GEOSGeometry(
- 'MULTIPOINT(-95.363151 29.763374, -96.467222 32.751389)',
+ "MULTIPOINT(-95.363151 29.763374, -96.467222 32.751389)",
srid=4326,
)
self.assertIs(
forney_houston.equals_exact(
City.objects.filter(point__within=tx).aggregate(
- Union('point', tolerance=32000),
- )['point__union'],
+ Union("point", tolerance=32000),
+ )["point__union"],
tolerance=10e-6,
),
True,
)
- @skipUnlessDBFeature('supports_tolerance_parameter')
+ @skipUnlessDBFeature("supports_tolerance_parameter")
def test_unionagg_tolerance_escaping(self):
- tx = Country.objects.get(name='Texas').mpoly
+ tx = Country.objects.get(name="Texas").mpoly
with self.assertRaises(DatabaseError):
City.objects.filter(point__within=tx).aggregate(
- Union('point', tolerance='0.05))), (((1'),
+ Union("point", tolerance="0.05))), (((1"),
)
def test_within_subquery(self):
@@ -637,13 +727,16 @@ class GeoQuerySetTest(TestCase):
(#14483).
"""
tex_cities = City.objects.filter(
- point__within=Country.objects.filter(name='Texas').values('mpoly')).order_by('name')
- self.assertEqual(list(tex_cities.values_list('name', flat=True)), ['Dallas', 'Houston'])
+ point__within=Country.objects.filter(name="Texas").values("mpoly")
+ ).order_by("name")
+ self.assertEqual(
+ list(tex_cities.values_list("name", flat=True)), ["Dallas", "Houston"]
+ )
def test_non_concrete_field(self):
- NonConcreteModel.objects.create(point=Point(0, 0), name='name')
+ NonConcreteModel.objects.create(point=Point(0, 0), name="name")
list(NonConcreteModel.objects.all())
def test_values_srid(self):
for c, v in zip(City.objects.all(), City.objects.values()):
- self.assertEqual(c.point.srid, v['point'].srid)
+ self.assertEqual(c.point.srid, v["point"].srid)
diff --git a/tests/gis_tests/geoapp/urls.py b/tests/gis_tests/geoapp/urls.py
index 8597387f82..a7dd805c8c 100644
--- a/tests/gis_tests/geoapp/urls.py
+++ b/tests/gis_tests/geoapp/urls.py
@@ -7,20 +7,22 @@ from .feeds import feed_dict
from .sitemaps import sitemaps
urlpatterns = [
- path('feeds/<path:url>/', gis_views.feed, {'feed_dict': feed_dict}),
+ path("feeds/<path:url>/", gis_views.feed, {"feed_dict": feed_dict}),
]
urlpatterns += [
- path('sitemaps/<section>.xml', sitemap_views.sitemap, {'sitemaps': sitemaps}),
+ path("sitemaps/<section>.xml", sitemap_views.sitemap, {"sitemaps": sitemaps}),
]
urlpatterns += [
path(
- 'sitemaps/kml/<label>/<model>/<field_name>.kml',
+ "sitemaps/kml/<label>/<model>/<field_name>.kml",
gis_sitemap_views.kml,
- name='django.contrib.gis.sitemaps.views.kml'),
+ name="django.contrib.gis.sitemaps.views.kml",
+ ),
path(
- 'sitemaps/kml/<label>/<model>/<field_name>.kmz',
+ "sitemaps/kml/<label>/<model>/<field_name>.kmz",
gis_sitemap_views.kmz,
- name='django.contrib.gis.sitemaps.views.kmz'),
+ name="django.contrib.gis.sitemaps.views.kmz",
+ ),
]
diff --git a/tests/gis_tests/geogapp/models.py b/tests/gis_tests/geogapp/models.py
index 6aa0b1f00e..c5c550feba 100644
--- a/tests/gis_tests/geogapp/models.py
+++ b/tests/gis_tests/geogapp/models.py
@@ -15,7 +15,7 @@ class City(NamedModel):
point = models.PointField(geography=True)
class Meta:
- app_label = 'geogapp'
+ app_label = "geogapp"
class Zipcode(NamedModel):
@@ -28,7 +28,7 @@ class County(NamedModel):
mpoly = models.MultiPolygonField(geography=True)
class Meta:
- app_label = 'geogapp'
+ app_label = "geogapp"
def __str__(self):
- return ' County, '.join([self.name, self.state])
+ return " County, ".join([self.name, self.state])
diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py
index 7f465f5753..819b86545f 100644
--- a/tests/gis_tests/geogapp/tests.py
+++ b/tests/gis_tests/geogapp/tests.py
@@ -15,7 +15,7 @@ from .models import City, County, Zipcode
class GeographyTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test01_fixture_load(self):
"Ensure geography features loaded properly."
@@ -24,26 +24,28 @@ class GeographyTest(TestCase):
@skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
def test02_distance_lookup(self):
"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)))
- .order_by('name')
- .values_list('name', flat=True))
- cities2 = list(City.objects
- .filter(point__dwithin=(z.poly, D(mi=500)))
- .order_by('name')
- .values_list('name', flat=True))
+ z = Zipcode.objects.get(code="77002")
+ cities1 = list(
+ City.objects.filter(point__distance_lte=(z.poly, D(mi=500)))
+ .order_by("name")
+ .values_list("name", flat=True)
+ )
+ cities2 = list(
+ City.objects.filter(point__dwithin=(z.poly, D(mi=500)))
+ .order_by("name")
+ .values_list("name", flat=True)
+ )
for cities in [cities1, cities2]:
- self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
+ self.assertEqual(["Dallas", "Houston", "Oklahoma City"], cities)
def test04_invalid_operators_functions(self):
"Ensuring exceptions are raised for operators & functions invalid on geography fields."
if not connection.ops.postgis:
- self.skipTest('This is a PostGIS-specific test.')
+ self.skipTest("This is a PostGIS-specific test.")
# Only a subset of the geometry functions & operator are available
# to PostGIS geography types. For more information, visit:
# http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_GeographyFunctions
- z = Zipcode.objects.get(code='77002')
+ z = Zipcode.objects.get(code="77002")
# ST_Within not available.
with self.assertRaises(ValueError):
City.objects.filter(point__within=z.poly).count()
@@ -52,7 +54,7 @@ class GeographyTest(TestCase):
City.objects.filter(point__contained=z.poly).count()
# Regression test for #14060, `~=` was never really implemented for PostGIS.
- htown = City.objects.get(name='Houston')
+ htown = City.objects.get(name="Houston")
with self.assertRaises(ValueError):
City.objects.get(point__exact=htown.point)
@@ -63,22 +65,26 @@ class GeographyTest(TestCase):
from django.contrib.gis.utils import LayerMapping
# Getting the shapefile and mapping dictionary.
- shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data'))
- co_shp = os.path.join(shp_path, 'counties', 'counties.shp')
+ shp_path = os.path.realpath(
+ os.path.join(os.path.dirname(__file__), "..", "data")
+ )
+ co_shp = os.path.join(shp_path, "counties", "counties.shp")
co_mapping = {
- 'name': 'Name',
- 'state': 'State',
- 'mpoly': 'MULTIPOLYGON',
+ "name": "Name",
+ "state": "State",
+ "mpoly": "MULTIPOLYGON",
}
# Reference county names, number of polygons, and state names.
- names = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo']
+ names = ["Bexar", "Galveston", "Harris", "Honolulu", "Pueblo"]
num_polys = [1, 2, 1, 19, 1] # Number of polygons for each.
- st_names = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado']
+ st_names = ["Texas", "Texas", "Texas", "Hawaii", "Colorado"]
- lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269, unique='name')
+ lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269, unique="name")
lm.save(silent=True, strict=True)
- for c, name, num_poly, state in zip(County.objects.order_by('name'), names, num_polys, st_names):
+ for c, name, num_poly, state in zip(
+ County.objects.order_by("name"), names, num_polys, st_names
+ ):
self.assertEqual(4326, c.mpoly.srid)
self.assertEqual(num_poly, len(c.mpoly))
self.assertEqual(name, c.name)
@@ -86,7 +92,7 @@ class GeographyTest(TestCase):
class GeographyFunctionTests(FuncTestMixin, TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
@skipUnlessDBFeature("supports_extent_aggr")
def test_cast_aggregate(self):
@@ -96,11 +102,16 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
"""
if not connection.features.supports_geography:
self.skipTest("This test needs geography support")
- expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
- res = City.objects.filter(
- name__in=('Houston', 'Dallas')
- ).aggregate(extent=models.Extent(Cast('point', models.PointField())))
- for val, exp in zip(res['extent'], expected):
+ expected = (
+ -96.8016128540039,
+ 29.7633724212646,
+ -95.3631439208984,
+ 32.782058715820,
+ )
+ res = City.objects.filter(name__in=("Houston", "Dallas")).aggregate(
+ extent=models.Extent(Cast("point", models.PointField()))
+ )
+ for val, exp in zip(res["extent"], expected):
self.assertAlmostEqual(exp, val, 4)
@skipUnlessDBFeature("has_Distance_function", "supports_distance_geodetic")
@@ -119,10 +130,10 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
ref_dists = [0, 4899.68, 8081.30, 9115.15]
else:
ref_dists = [0, 4891.20, 8071.64, 9123.95]
- htown = City.objects.get(name='Houston')
+ htown = City.objects.get(name="Houston")
qs = Zipcode.objects.annotate(
- distance=Distance('poly', htown.point),
- distance2=Distance(htown.point, 'poly'),
+ 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)
@@ -135,7 +146,7 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
if not connection.ops.spatialite:
# Distance function combined with a lookup.
- hzip = Zipcode.objects.get(code='77002')
+ hzip = Zipcode.objects.get(code="77002")
self.assertEqual(qs.get(distance__lte=0), hzip)
@skipUnlessDBFeature("has_Area_function", "supports_area_geodetic")
@@ -144,7 +155,7 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
Testing that Area calculations work on geography columns.
"""
# SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
- z = Zipcode.objects.annotate(area=Area('poly')).get(code='77002')
+ z = Zipcode.objects.annotate(area=Area("poly")).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
@@ -154,5 +165,7 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_Area_function")
@skipIfDBFeature("supports_area_geodetic")
def test_geodetic_area_raises_if_not_supported(self):
- with self.assertRaisesMessage(NotSupportedError, 'Area on geodetic coordinate systems not supported.'):
- Zipcode.objects.annotate(area=Area('poly')).get(code='77002')
+ with self.assertRaisesMessage(
+ NotSupportedError, "Area on geodetic coordinate systems not supported."
+ ):
+ Zipcode.objects.annotate(area=Area("poly")).get(code="77002")
diff --git a/tests/gis_tests/geos_tests/test_coordseq.py b/tests/gis_tests/geos_tests/test_coordseq.py
index f6a0ff89c7..507a22d1a0 100644
--- a/tests/gis_tests/geos_tests/test_coordseq.py
+++ b/tests/gis_tests/geos_tests/test_coordseq.py
@@ -3,14 +3,13 @@ from django.test import SimpleTestCase
class GEOSCoordSeqTest(SimpleTestCase):
-
def test_getitem(self):
coord_seq = LineString([(x, x) for x in range(2)]).coord_seq
for i in (0, 1):
with self.subTest(i):
self.assertEqual(coord_seq[i], (i, i))
for i in (-3, 10):
- msg = 'invalid GEOS Geometry index: %s' % i
+ msg = "invalid GEOS Geometry index: %s" % i
with self.subTest(i):
with self.assertRaisesMessage(IndexError, msg):
coord_seq[i]
diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py
index 08169f38ab..d37d826d39 100644
--- a/tests/gis_tests/geos_tests/test_geos.py
+++ b/tests/gis_tests/geos_tests/test_geos.py
@@ -9,8 +9,17 @@ from unittest import mock, skipIf
from django.contrib.gis import gdal
from django.contrib.gis.geos import (
- GeometryCollection, GEOSException, GEOSGeometry, LinearRing, LineString,
- MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, fromfile,
+ GeometryCollection,
+ GEOSException,
+ GEOSGeometry,
+ LinearRing,
+ LineString,
+ MultiLineString,
+ MultiPoint,
+ MultiPolygon,
+ Point,
+ Polygon,
+ fromfile,
fromstr,
)
from django.contrib.gis.geos.libgeos import geos_version_tuple
@@ -23,7 +32,6 @@ from ..test_data import TestDataMixin
class GEOSTest(SimpleTestCase, TestDataMixin):
-
def test_wkt(self):
"Testing WKT output."
for g in self.geometries.wkt_out:
@@ -32,11 +40,11 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertEqual(g.ewkt, geom.wkt)
def test_wkt_invalid(self):
- msg = 'String input unrecognized as WKT EWKT, and HEXEWKB.'
+ msg = "String input unrecognized as WKT EWKT, and HEXEWKB."
with self.assertRaisesMessage(ValueError, msg):
- fromstr('POINT(٠٠١ ٠)')
+ fromstr("POINT(٠٠١ ٠)")
with self.assertRaisesMessage(ValueError, msg):
- fromstr('SRID=٧٥٨٣;POINT(100 0)')
+ fromstr("SRID=٧٥٨٣;POINT(100 0)")
def test_hex(self):
"Testing HEX output."
@@ -47,12 +55,14 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_hexewkb(self):
"Testing (HEX)EWKB output."
# For testing HEX(EWKB).
- ogc_hex = b'01010000000000000000000000000000000000F03F'
- ogc_hex_3d = b'01010000800000000000000000000000000000F03F0000000000000040'
+ ogc_hex = b"01010000000000000000000000000000000000F03F"
+ ogc_hex_3d = b"01010000800000000000000000000000000000F03F0000000000000040"
# `SELECT ST_AsHEXEWKB(ST_GeomFromText('POINT(0 1)', 4326));`
- hexewkb_2d = b'0101000020E61000000000000000000000000000000000F03F'
+ hexewkb_2d = b"0101000020E61000000000000000000000000000000000F03F"
# `SELECT ST_AsHEXEWKB(ST_GeomFromEWKT('SRID=4326;POINT(0 1 2)'));`
- hexewkb_3d = b'01010000A0E61000000000000000000000000000000000F03F0000000000000040'
+ hexewkb_3d = (
+ b"01010000A0E61000000000000000000000000000000000F03F0000000000000040"
+ )
pnt_2d = Point(0, 1, srid=4326)
pnt_3d = Point(0, 1, 2, srid=4326)
@@ -79,7 +89,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"Testing KML output."
for tg in self.geometries.wkt_out:
geom = fromstr(tg.wkt)
- kml = getattr(tg, 'kml', False)
+ kml = getattr(tg, "kml", False)
if kml:
self.assertEqual(kml, geom.kml)
@@ -92,7 +102,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Bad WKB
with self.assertRaises(GEOSException):
- GEOSGeometry(memoryview(b'0'))
+ GEOSGeometry(memoryview(b"0"))
class NotAGeometry:
pass
@@ -133,7 +143,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
srids = (-1, 32140)
for srid in srids:
for p in self.geometries.polygons:
- ewkt = 'SRID=%d;%s' % (srid, p.wkt)
+ ewkt = "SRID=%d;%s" % (srid, p.wkt)
poly = fromstr(ewkt)
self.assertEqual(srid, poly.srid)
self.assertEqual(srid, poly.shell.srid)
@@ -143,7 +153,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"Testing GeoJSON input/output (via GDAL)."
for g in self.geometries.json_geoms:
geom = GEOSGeometry(g.wkt)
- if not hasattr(g, 'not_equal'):
+ if not hasattr(g, "not_equal"):
# Loading jsons to prevent decimal differences
self.assertEqual(json.loads(g.json), json.loads(geom.json))
self.assertEqual(json.loads(g.json), json.loads(geom.geojson))
@@ -155,16 +165,16 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"coordinates": [2, 49],
"crs": {
"type": "name",
- "properties": {
- "name": "urn:ogc:def:crs:EPSG::4322"
- }
- }
+ "properties": {"name": "urn:ogc:def:crs:EPSG::4322"},
+ },
}
- self.assertEqual(GEOSGeometry(json.dumps(geojson_data)), Point(2, 49, srid=4322))
+ self.assertEqual(
+ GEOSGeometry(json.dumps(geojson_data)), Point(2, 49, srid=4322)
+ )
def test_fromfile(self):
"Testing the fromfile() factory."
- ref_pnt = GEOSGeometry('POINT(5 23)')
+ ref_pnt = GEOSGeometry("POINT(5 23)")
wkt_f = BytesIO()
wkt_f.write(ref_pnt.wkt.encode())
@@ -180,18 +190,18 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_eq(self):
"Testing equivalence."
- p = fromstr('POINT(5 23)')
+ p = fromstr("POINT(5 23)")
self.assertEqual(p, p.wkt)
- self.assertNotEqual(p, 'foo')
- ls = fromstr('LINESTRING(0 0, 1 1, 5 5)')
+ self.assertNotEqual(p, "foo")
+ ls = fromstr("LINESTRING(0 0, 1 1, 5 5)")
self.assertEqual(ls, ls.wkt)
- self.assertNotEqual(p, 'bar')
- self.assertEqual(p, 'POINT(5.0 23.0)')
+ self.assertNotEqual(p, "bar")
+ self.assertEqual(p, "POINT(5.0 23.0)")
# Error shouldn't be raise on equivalence testing with
# an invalid type.
for g in (p, ls):
self.assertIsNotNone(g)
- self.assertNotEqual(g, {'foo': 'bar'})
+ self.assertNotEqual(g, {"foo": "bar"})
self.assertIsNot(g, False)
def test_hash(self):
@@ -228,16 +238,16 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# WKT contains no SRID so will not equal
self.assertNotEqual(p2, p2.wkt)
# SRID of 0
- self.assertEqual(p0, 'SRID=0;POINT (5 23)')
- self.assertNotEqual(p1, 'SRID=0;POINT (5 23)')
+ self.assertEqual(p0, "SRID=0;POINT (5 23)")
+ self.assertNotEqual(p1, "SRID=0;POINT (5 23)")
def test_points(self):
"Testing Point objects."
- prev = fromstr('POINT(0 0)')
+ prev = fromstr("POINT(0 0)")
for p in self.geometries.points:
# Creating the point from the WKT
pnt = fromstr(p.wkt)
- self.assertEqual(pnt.geom_type, 'Point')
+ self.assertEqual(pnt.geom_type, "Point")
self.assertEqual(pnt.geom_typeid, 0)
self.assertEqual(pnt.dims, 0)
self.assertEqual(p.x, pnt.x)
@@ -250,7 +260,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertAlmostEqual(p.y, pnt.tuple[1], 9)
# Testing the third dimension, and getting the tuple arguments
- if hasattr(p, 'z'):
+ if hasattr(p, "z"):
self.assertIs(pnt.hasz, True)
self.assertEqual(p.z, pnt.z)
self.assertEqual(p.z, pnt.tuple[2], 9)
@@ -288,16 +298,16 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
prev = pnt # setting the previous geometry
def test_point_reverse(self):
- point = GEOSGeometry('POINT(144.963 -37.8143)', 4326)
+ point = GEOSGeometry("POINT(144.963 -37.8143)", 4326)
self.assertEqual(point.srid, 4326)
point.reverse()
- self.assertEqual(point.ewkt, 'SRID=4326;POINT (-37.8143 144.963)')
+ self.assertEqual(point.ewkt, "SRID=4326;POINT (-37.8143 144.963)")
def test_multipoints(self):
"Testing MultiPoint objects."
for mp in self.geometries.multipoints:
mpnt = fromstr(mp.wkt)
- self.assertEqual(mpnt.geom_type, 'MultiPoint')
+ self.assertEqual(mpnt.geom_type, "MultiPoint")
self.assertEqual(mpnt.geom_typeid, 4)
self.assertEqual(mpnt.dims, 0)
@@ -309,24 +319,24 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertEqual(mp.centroid, mpnt.centroid.tuple)
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_type, "Point")
self.assertEqual(p.geom_typeid, 0)
self.assertIs(p.empty, False)
self.assertIs(p.valid, True)
def test_linestring(self):
"Testing LineString objects."
- prev = fromstr('POINT(0 0)')
+ prev = fromstr("POINT(0 0)")
for line in self.geometries.linestrings:
ls = fromstr(line.wkt)
- self.assertEqual(ls.geom_type, 'LineString')
+ self.assertEqual(ls.geom_type, "LineString")
self.assertEqual(ls.geom_typeid, 1)
self.assertEqual(ls.dims, 1)
self.assertIs(ls.empty, False)
self.assertIs(ls.ring, False)
- if hasattr(line, 'centroid'):
+ if hasattr(line, "centroid"):
self.assertEqual(line.centroid, ls.centroid.tuple)
- if hasattr(line, 'tup'):
+ if hasattr(line, "tup"):
self.assertEqual(line.tup, ls.tuple)
self.assertEqual(ls, fromstr(line.wkt))
@@ -340,65 +350,81 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertEqual(ls, LineString(*ls.tuple)) # as individual arguments
self.assertEqual(ls, LineString([list(tup) for tup in ls.tuple])) # as list
# Point individual arguments
- self.assertEqual(ls.wkt, LineString(*tuple(Point(tup) for tup in ls.tuple)).wkt)
+ self.assertEqual(
+ ls.wkt, LineString(*tuple(Point(tup) for tup in ls.tuple)).wkt
+ )
if numpy:
- self.assertEqual(ls, LineString(numpy.array(ls.tuple))) # as numpy array
+ self.assertEqual(
+ ls, LineString(numpy.array(ls.tuple))
+ ) # as numpy array
- with self.assertRaisesMessage(TypeError, 'Each coordinate should be a sequence (list or tuple)'):
+ with self.assertRaisesMessage(
+ TypeError, "Each coordinate should be a sequence (list or tuple)"
+ ):
LineString((0, 0))
- with self.assertRaisesMessage(ValueError, 'LineString requires at least 2 points, got 1.'):
+ with self.assertRaisesMessage(
+ ValueError, "LineString requires at least 2 points, got 1."
+ ):
LineString([(0, 0)])
if numpy:
- with self.assertRaisesMessage(ValueError, 'LineString requires at least 2 points, got 1.'):
+ with self.assertRaisesMessage(
+ ValueError, "LineString requires at least 2 points, got 1."
+ ):
LineString(numpy.array([(0, 0)]))
- with mock.patch('django.contrib.gis.geos.linestring.numpy', False):
- with self.assertRaisesMessage(TypeError, 'Invalid initialization input for LineStrings.'):
- LineString('wrong input')
+ with mock.patch("django.contrib.gis.geos.linestring.numpy", False):
+ with self.assertRaisesMessage(
+ TypeError, "Invalid initialization input for LineStrings."
+ ):
+ LineString("wrong input")
# Test __iter__().
- self.assertEqual(list(LineString((0, 0), (1, 1), (2, 2))), [(0, 0), (1, 1), (2, 2)])
+ self.assertEqual(
+ list(LineString((0, 0), (1, 1), (2, 2))), [(0, 0), (1, 1), (2, 2)]
+ )
def test_linestring_reverse(self):
- line = GEOSGeometry('LINESTRING(144.963 -37.8143,151.2607 -33.887)', 4326)
+ line = GEOSGeometry("LINESTRING(144.963 -37.8143,151.2607 -33.887)", 4326)
self.assertEqual(line.srid, 4326)
line.reverse()
- self.assertEqual(line.ewkt, 'SRID=4326;LINESTRING (151.2607 -33.887, 144.963 -37.8143)')
+ self.assertEqual(
+ line.ewkt, "SRID=4326;LINESTRING (151.2607 -33.887, 144.963 -37.8143)"
+ )
def _test_is_counterclockwise(self):
lr = LinearRing((0, 0), (1, 0), (0, 1), (0, 0))
self.assertIs(lr.is_counterclockwise, True)
lr.reverse()
self.assertIs(lr.is_counterclockwise, False)
- msg = 'Orientation of an empty LinearRing cannot be determined.'
+ msg = "Orientation of an empty LinearRing cannot be determined."
with self.assertRaisesMessage(ValueError, msg):
LinearRing().is_counterclockwise
- @skipIf(geos_version_tuple() < (3, 7), 'GEOS >= 3.7.0 is required')
+ @skipIf(geos_version_tuple() < (3, 7), "GEOS >= 3.7.0 is required")
def test_is_counterclockwise(self):
self._test_is_counterclockwise()
- @skipIf(geos_version_tuple() < (3, 7), 'GEOS >= 3.7.0 is required')
+ @skipIf(geos_version_tuple() < (3, 7), "GEOS >= 3.7.0 is required")
def test_is_counterclockwise_geos_error(self):
- with mock.patch('django.contrib.gis.geos.prototypes.cs_is_ccw') as mocked:
+ with mock.patch("django.contrib.gis.geos.prototypes.cs_is_ccw") as mocked:
mocked.return_value = 0
- mocked.func_name = 'GEOSCoordSeq_isCCW'
+ mocked.func_name = "GEOSCoordSeq_isCCW"
msg = 'Error encountered in GEOS C function "GEOSCoordSeq_isCCW".'
with self.assertRaisesMessage(GEOSException, msg):
LinearRing((0, 0), (1, 0), (0, 1), (0, 0)).is_counterclockwise
- @mock.patch('django.contrib.gis.geos.libgeos.geos_version', lambda: b'3.6.9')
+ @mock.patch("django.contrib.gis.geos.libgeos.geos_version", lambda: b"3.6.9")
def test_is_counterclockwise_fallback(self):
self._test_is_counterclockwise()
def test_multilinestring(self):
"Testing MultiLineString objects."
- prev = fromstr('POINT(0 0)')
+ prev = fromstr("POINT(0 0)")
for line in self.geometries.multilinestrings:
ml = fromstr(line.wkt)
- self.assertEqual(ml.geom_type, 'MultiLineString')
+ self.assertEqual(ml.geom_type, "MultiLineString")
self.assertEqual(ml.geom_typeid, 5)
self.assertEqual(ml.dims, 1)
@@ -410,20 +436,22 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
prev = ml
for ls in ml:
- self.assertEqual(ls.geom_type, 'LineString')
+ self.assertEqual(ls.geom_type, "LineString")
self.assertEqual(ls.geom_typeid, 1)
self.assertIs(ls.empty, False)
with self.assertRaises(IndexError):
ml.__getitem__(len(ml))
self.assertEqual(ml.wkt, MultiLineString(*tuple(s.clone() for s in ml)).wkt)
- self.assertEqual(ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml)))
+ self.assertEqual(
+ ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml))
+ )
def test_linearring(self):
"Testing LinearRing objects."
for rr in self.geometries.linearrings:
lr = fromstr(rr.wkt)
- self.assertEqual(lr.geom_type, 'LinearRing')
+ self.assertEqual(lr.geom_type, "LinearRing")
self.assertEqual(lr.geom_typeid, 2)
self.assertEqual(lr.dims, 1)
self.assertEqual(rr.n_p, len(lr))
@@ -437,14 +465,20 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
if numpy:
self.assertEqual(lr, LinearRing(numpy.array(lr.tuple)))
- with self.assertRaisesMessage(ValueError, 'LinearRing requires at least 4 points, got 3.'):
+ with self.assertRaisesMessage(
+ ValueError, "LinearRing requires at least 4 points, got 3."
+ ):
LinearRing((0, 0), (1, 1), (0, 0))
- with self.assertRaisesMessage(ValueError, 'LinearRing requires at least 4 points, got 1.'):
+ with self.assertRaisesMessage(
+ ValueError, "LinearRing requires at least 4 points, got 1."
+ ):
LinearRing([(0, 0)])
if numpy:
- with self.assertRaisesMessage(ValueError, 'LinearRing requires at least 4 points, got 1.'):
+ with self.assertRaisesMessage(
+ ValueError, "LinearRing requires at least 4 points, got 1."
+ ):
LinearRing(numpy.array([(0, 0)]))
def test_linearring_json(self):
@@ -464,16 +498,16 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
bbox = (0, 0, 1, x)
p = Polygon.from_bbox(bbox)
y = p.extent[-1]
- self.assertEqual(format(x, '.13f'), format(y, '.13f'))
+ self.assertEqual(format(x, ".13f"), format(y, ".13f"))
def test_polygons(self):
"Testing Polygon objects."
- prev = fromstr('POINT(0 0)')
+ prev = fromstr("POINT(0 0)")
for p in self.geometries.polygons:
# Creating the Polygon, testing its properties.
poly = fromstr(p.wkt)
- self.assertEqual(poly.geom_type, 'Polygon')
+ self.assertEqual(poly.geom_type, "Polygon")
self.assertEqual(poly.geom_typeid, 3)
self.assertEqual(poly.dims, 2)
self.assertIs(poly.empty, False)
@@ -495,7 +529,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Testing the exterior ring
ring = poly.exterior_ring
- self.assertEqual(ring.geom_type, 'LinearRing')
+ self.assertEqual(ring.geom_type, "LinearRing")
self.assertEqual(ring.geom_typeid, 2)
if p.ext_ring_cs:
self.assertEqual(p.ext_ring_cs, ring.tuple)
@@ -511,14 +545,14 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Testing __iter__
for r in poly:
- self.assertEqual(r.geom_type, 'LinearRing')
+ self.assertEqual(r.geom_type, "LinearRing")
self.assertEqual(r.geom_typeid, 2)
# Testing polygon construction.
with self.assertRaises(TypeError):
Polygon(0, [1, 2, 3])
with self.assertRaises(TypeError):
- Polygon('foo')
+ Polygon("foo")
# Polygon(shell, (hole1, ... holeN))
ext_ring, *int_rings = poly
@@ -530,15 +564,17 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Constructing with tuples of LinearRings.
self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt)
- self.assertEqual(poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt)
+ self.assertEqual(
+ poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt
+ )
def test_polygons_templates(self):
# Accessing Polygon attributes in templates should work.
engine = Engine()
- template = engine.from_string('{{ polygons.0.wkt }}')
+ template = engine.from_string("{{ polygons.0.wkt }}")
polygons = [fromstr(p.wkt) for p in self.geometries.multipolygons[:2]]
- content = template.render(Context({'polygons': polygons}))
- self.assertIn('MULTIPOLYGON (((100', content)
+ content = template.render(Context({"polygons": polygons}))
+ self.assertIn("MULTIPOLYGON (((100", content)
def test_polygon_comparison(self):
p1 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
@@ -553,10 +589,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_multipolygons(self):
"Testing MultiPolygon objects."
- fromstr('POINT (0 0)')
+ fromstr("POINT (0 0)")
for mp in self.geometries.multipolygons:
mpoly = fromstr(mp.wkt)
- self.assertEqual(mpoly.geom_type, 'MultiPolygon')
+ self.assertEqual(mpoly.geom_type, "MultiPolygon")
self.assertEqual(mpoly.geom_typeid, 6)
self.assertEqual(mpoly.dims, 2)
self.assertEqual(mp.valid, mpoly.valid)
@@ -568,10 +604,12 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
with self.assertRaises(IndexError):
mpoly.__getitem__(len(mpoly))
for p in mpoly:
- self.assertEqual(p.geom_type, 'Polygon')
+ self.assertEqual(p.geom_type, "Polygon")
self.assertEqual(p.geom_typeid, 3)
self.assertIs(p.valid, True)
- self.assertEqual(mpoly.wkt, MultiPolygon(*tuple(poly.clone() for poly in mpoly)).wkt)
+ self.assertEqual(
+ mpoly.wkt, MultiPolygon(*tuple(poly.clone() for poly in mpoly)).wkt
+ )
def test_memory_hijinks(self):
"Testing Geometry __del__() on rings and polygons."
@@ -605,8 +643,12 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
poly = fromstr(p.wkt)
cs = poly.exterior_ring.coord_seq
- self.assertEqual(p.ext_ring_cs, cs.tuple) # done in the Polygon test too.
- self.assertEqual(len(p.ext_ring_cs), len(cs)) # Making sure __len__ works
+ self.assertEqual(
+ p.ext_ring_cs, cs.tuple
+ ) # done in the Polygon test too.
+ self.assertEqual(
+ len(p.ext_ring_cs), len(cs)
+ ) # Making sure __len__ works
# Checks __getitem__ and __setitem__
for i in range(len(p.ext_ring_cs)):
@@ -628,9 +670,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_relate_pattern(self):
"Testing relate() and relate_pattern()."
- g = fromstr('POINT (0 0)')
+ g = fromstr("POINT (0 0)")
with self.assertRaises(GEOSException):
- g.relate_pattern(0, 'invalid pattern, yo')
+ g.relate_pattern(0, "invalid pattern, yo")
for rg in self.geometries.relate_geoms:
a = fromstr(rg.wkt_a)
b = fromstr(rg.wkt_b)
@@ -691,7 +733,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
d1 = fromstr(self.geometries.sdiff_geoms[i].wkt)
d2 = a.sym_difference(b)
self.assertTrue(d1.equals(d2))
- self.assertTrue(d1.equals(a ^ b)) # __xor__ is symmetric difference operator
+ self.assertTrue(
+ d1.equals(a ^ b)
+ ) # __xor__ is symmetric difference operator
a ^= b # testing __ixor__
self.assertTrue(d1.equals(a))
@@ -703,7 +747,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
with self.assertRaises(ctypes.ArgumentError):
g.buffer(bg.width, quadsegs=1.1)
- self._test_buffer(self.geometries.buffer_geoms, 'buffer')
+ self._test_buffer(self.geometries.buffer_geoms, "buffer")
def test_buffer_with_style(self):
bg = self.geometries.buffer_with_style_geoms[0]
@@ -728,8 +772,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
g.buffer_with_style(bg.width, join_style=66)
self._test_buffer(
- itertools.chain(self.geometries.buffer_geoms, self.geometries.buffer_with_style_geoms),
- 'buffer_with_style',
+ itertools.chain(
+ self.geometries.buffer_geoms, self.geometries.buffer_with_style_geoms
+ ),
+ "buffer_with_style",
)
def _test_buffer(self, geometries, buffer_method_name):
@@ -742,7 +788,13 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Constructing our buffer
buf_kwargs = {
kwarg_name: getattr(bg, kwarg_name)
- for kwarg_name in ('width', 'quadsegs', 'end_cap_style', 'join_style', 'mitre_limit')
+ for kwarg_name in (
+ "width",
+ "quadsegs",
+ "end_cap_style",
+ "join_style",
+ "mitre_limit",
+ )
if hasattr(bg, kwarg_name)
}
buf = getattr(g, buffer_method_name)(**buf_kwargs)
@@ -778,7 +830,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
pnt.srid = 3084
self.assertEqual(3084, pnt.srid)
with self.assertRaises(ctypes.ArgumentError):
- pnt.srid = '4326'
+ pnt.srid = "4326"
# Testing SRID keyword on fromstr(), and on Polygon rings.
poly = fromstr(self.geometries.polygons[1].wkt, srid=4269)
@@ -789,7 +841,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertEqual(4326, poly.shell.srid)
# Testing SRID keyword on GeometryCollection
- gc = GeometryCollection(Point(5, 23), LineString((0, 0), (1.5, 1.5), (3, 3)), srid=32021)
+ gc = GeometryCollection(
+ Point(5, 23), LineString((0, 0), (1.5, 1.5), (3, 3)), srid=32021
+ )
self.assertEqual(32021, gc.srid)
for i in range(len(gc)):
self.assertEqual(32021, gc[i].srid)
@@ -797,7 +851,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# GEOS may get the SRID from HEXEWKB
# 'POINT(5 23)' at SRID=4326 in hex form -- obtained from PostGIS
# using `SELECT GeomFromText('POINT (5 23)', 4326);`.
- hex = '0101000020E610000000000000000014400000000000003740'
+ hex = "0101000020E610000000000000000014400000000000003740"
p1 = fromstr(hex)
self.assertEqual(4326, p1.srid)
@@ -813,26 +867,35 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# Input geometries that have an SRID.
self.assertEqual(GEOSGeometry(pnt.ewkt, srid=pnt.srid).srid, pnt.srid)
self.assertEqual(GEOSGeometry(pnt.ewkb, srid=pnt.srid).srid, pnt.srid)
- with self.assertRaisesMessage(ValueError, 'Input geometry already has SRID: %d.' % pnt.srid):
+ with self.assertRaisesMessage(
+ ValueError, "Input geometry already has SRID: %d." % pnt.srid
+ ):
GEOSGeometry(pnt.ewkt, srid=1)
- with self.assertRaisesMessage(ValueError, 'Input geometry already has SRID: %d.' % pnt.srid):
+ with self.assertRaisesMessage(
+ ValueError, "Input geometry already has SRID: %d." % pnt.srid
+ ):
GEOSGeometry(pnt.ewkb, srid=1)
def test_custom_srid(self):
"""Test with a null srid and a srid unknown to GDAL."""
for srid in [None, 999999]:
pnt = Point(111200, 220900, srid=srid)
- self.assertTrue(pnt.ewkt.startswith(("SRID=%s;" % srid if srid else '') + "POINT (111200"))
+ self.assertTrue(
+ pnt.ewkt.startswith(
+ ("SRID=%s;" % srid if srid else "") + "POINT (111200"
+ )
+ )
self.assertIsInstance(pnt.ogr, gdal.OGRGeometry)
self.assertIsNone(pnt.srs)
# Test conversion from custom to a known srid
c2w = gdal.CoordTransform(
gdal.SpatialReference(
- '+proj=mill +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R_A +ellps=WGS84 '
- '+datum=WGS84 +units=m +no_defs'
+ "+proj=mill +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R_A +ellps=WGS84 "
+ "+datum=WGS84 +units=m +no_defs"
),
- gdal.SpatialReference(4326))
+ gdal.SpatialReference(4326),
+ )
new_pnt = pnt.transform(c2w, clone=True)
self.assertEqual(new_pnt.srid, 4326)
self.assertAlmostEqual(new_pnt.x, 1, 1)
@@ -852,7 +915,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
shell_tup = poly.shell.tuple
new_coords = []
for point in shell_tup:
- new_coords.append((point[0] + 500., point[1] + 500.))
+ new_coords.append((point[0] + 500.0, point[1] + 500.0))
new_shell = LinearRing(*tuple(new_coords))
# Assigning polygon's exterior ring w/the new shell
@@ -886,7 +949,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
for j in range(len(poly)):
r = poly[j]
for k in range(len(r)):
- r[k] = (r[k][0] + 500., r[k][1] + 500.)
+ r[k] = (r[k][0] + 500.0, r[k][1] + 500.0)
poly[j] = r
self.assertNotEqual(mpoly[i], poly)
@@ -950,7 +1013,12 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
pol = Polygon()
pol[:] = (((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)),)
- self.assertEqual(pol, Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)),))
+ self.assertEqual(
+ pol,
+ Polygon(
+ ((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)),
+ ),
+ )
pol[:] = ()
self.assertEqual(pol, Polygon())
@@ -969,19 +1037,19 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"Testing three-dimensional geometries."
# Testing a 3D Point
pnt = Point(2, 3, 8)
- self.assertEqual((2., 3., 8.), pnt.coords)
+ self.assertEqual((2.0, 3.0, 8.0), pnt.coords)
with self.assertRaises(TypeError):
- pnt.tuple = (1., 2.)
- pnt.coords = (1., 2., 3.)
- self.assertEqual((1., 2., 3.), pnt.coords)
+ pnt.tuple = (1.0, 2.0)
+ pnt.coords = (1.0, 2.0, 3.0)
+ self.assertEqual((1.0, 2.0, 3.0), pnt.coords)
# Testing a 3D LineString
- ls = LineString((2., 3., 8.), (50., 250., -117.))
- self.assertEqual(((2., 3., 8.), (50., 250., -117.)), ls.tuple)
+ ls = LineString((2.0, 3.0, 8.0), (50.0, 250.0, -117.0))
+ self.assertEqual(((2.0, 3.0, 8.0), (50.0, 250.0, -117.0)), ls.tuple)
with self.assertRaises(TypeError):
- ls.__setitem__(0, (1., 2.))
- ls[0] = (1., 2., 3.)
- self.assertEqual((1., 2., 3.), ls[0])
+ ls.__setitem__(0, (1.0, 2.0))
+ ls[0] = (1.0, 2.0, 3.0)
+ self.assertEqual((1.0, 2.0, 3.0), ls[0])
def test_distance(self):
"Testing the distance() function."
@@ -1023,17 +1091,17 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"Testing empty geometries and collections."
geoms = [
GeometryCollection([]),
- fromstr('GEOMETRYCOLLECTION EMPTY'),
+ fromstr("GEOMETRYCOLLECTION EMPTY"),
GeometryCollection(),
- fromstr('POINT EMPTY'),
+ fromstr("POINT EMPTY"),
Point(),
- fromstr('LINESTRING EMPTY'),
+ fromstr("LINESTRING EMPTY"),
LineString(),
- fromstr('POLYGON EMPTY'),
+ fromstr("POLYGON EMPTY"),
Polygon(),
- fromstr('MULTILINESTRING EMPTY'),
+ fromstr("MULTILINESTRING EMPTY"),
MultiLineString(),
- fromstr('MULTIPOLYGON EMPTY'),
+ fromstr("MULTIPOLYGON EMPTY"),
MultiPolygon(()),
MultiPolygon(),
]
@@ -1062,7 +1130,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
g.x
elif isinstance(g, Polygon):
lr = g.shell
- self.assertEqual('LINEARRING EMPTY', lr.wkt)
+ self.assertEqual("LINEARRING EMPTY", lr.wkt)
self.assertEqual(0, len(lr))
self.assertIs(lr.empty, True)
with self.assertRaises(IndexError):
@@ -1081,7 +1149,11 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
gc = GeometryCollection(LineString((0, 0), (1, 1)), Point(0, 0))
self.assertEqual(gc.dims, 1)
- gc = GeometryCollection(LineString((0, 0), (1, 1)), Polygon(((0, 0), (0, 1), (1, 1), (0, 0))), Point(0, 0))
+ gc = GeometryCollection(
+ LineString((0, 0), (1, 1)),
+ Polygon(((0, 0), (0, 1), (1, 1), (0, 0))),
+ Point(0, 0),
+ )
self.assertEqual(gc.dims, 2)
def test_collections_of_collections(self):
@@ -1092,7 +1164,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
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)
+ gc_wkt = "GEOMETRYCOLLECTION(%s)" % ",".join(coll)
# Should construct ok from WKT
gc1 = GEOSGeometry(gc_wkt)
@@ -1105,24 +1177,27 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_gdal(self):
"Testing `ogr` and `srs` properties."
- g1 = fromstr('POINT(5 23)')
+ g1 = fromstr("POINT(5 23)")
self.assertIsInstance(g1.ogr, gdal.OGRGeometry)
self.assertIsNone(g1.srs)
- g1_3d = fromstr('POINT(5 23 8)')
+ g1_3d = fromstr("POINT(5 23 8)")
self.assertIsInstance(g1_3d.ogr, gdal.OGRGeometry)
self.assertEqual(g1_3d.ogr.z, 8)
- g2 = fromstr('LINESTRING(0 0, 5 5, 23 23)', srid=4326)
+ g2 = fromstr("LINESTRING(0 0, 5 5, 23 23)", srid=4326)
self.assertIsInstance(g2.ogr, gdal.OGRGeometry)
self.assertIsInstance(g2.srs, gdal.SpatialReference)
self.assertEqual(g2.hex, g2.ogr.hex)
- self.assertEqual('WGS 84', g2.srs.name)
+ self.assertEqual("WGS 84", g2.srs.name)
def test_copy(self):
"Testing use with the Python `copy` module."
import copy
- poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))')
+
+ poly = GEOSGeometry(
+ "POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))"
+ )
cpy1 = copy.copy(poly)
cpy2 = copy.deepcopy(poly)
self.assertNotEqual(poly._ptr, cpy1._ptr)
@@ -1130,15 +1205,17 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_transform(self):
"Testing `transform` method."
- orig = GEOSGeometry('POINT (-104.609 38.255)', 4326)
- trans = GEOSGeometry('POINT (992385.4472045 481455.4944650)', 2774)
+ orig = GEOSGeometry("POINT (-104.609 38.255)", 4326)
+ trans = GEOSGeometry("POINT (992385.4472045 481455.4944650)", 2774)
# Using a srid, a SpatialReference object, and a CoordTransform object
# for transformations.
t1, t2, t3 = orig.clone(), orig.clone(), orig.clone()
t1.transform(trans.srid)
- t2.transform(gdal.SpatialReference('EPSG:2774'))
- ct = gdal.CoordTransform(gdal.SpatialReference('WGS84'), gdal.SpatialReference(2774))
+ t2.transform(gdal.SpatialReference("EPSG:2774"))
+ ct = gdal.CoordTransform(
+ gdal.SpatialReference("WGS84"), gdal.SpatialReference(2774)
+ )
t3.transform(ct)
# Testing use of the `clone` keyword.
@@ -1155,42 +1232,42 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertAlmostEqual(trans.y, p.y, prec)
def test_transform_3d(self):
- p3d = GEOSGeometry('POINT (5 23 100)', 4326)
+ p3d = GEOSGeometry("POINT (5 23 100)", 4326)
p3d.transform(2774)
self.assertAlmostEqual(p3d.z, 100, 3)
def test_transform_noop(self):
- """ Testing `transform` method (SRID match) """
+ """Testing `transform` method (SRID match)"""
# transform() should no-op if source & dest SRIDs match,
# regardless of whether GDAL is available.
- g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
+ g = GEOSGeometry("POINT (-104.609 38.255)", 4326)
gt = g.tuple
g.transform(4326)
self.assertEqual(g.tuple, gt)
self.assertEqual(g.srid, 4326)
- g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
+ g = GEOSGeometry("POINT (-104.609 38.255)", 4326)
g1 = g.transform(4326, clone=True)
self.assertEqual(g1.tuple, g.tuple)
self.assertEqual(g1.srid, 4326)
self.assertIsNot(g1, g, "Clone didn't happen")
def test_transform_nosrid(self):
- """ Testing `transform` method (no SRID or negative SRID) """
+ """Testing `transform` method (no SRID or negative SRID)"""
- g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
+ g = GEOSGeometry("POINT (-104.609 38.255)", srid=None)
with self.assertRaises(GEOSException):
g.transform(2774)
- g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
+ g = GEOSGeometry("POINT (-104.609 38.255)", srid=None)
with self.assertRaises(GEOSException):
g.transform(2774, clone=True)
- g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
+ g = GEOSGeometry("POINT (-104.609 38.255)", srid=-1)
with self.assertRaises(GEOSException):
g.transform(2774)
- g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
+ g = GEOSGeometry("POINT (-104.609 38.255)", srid=-1)
with self.assertRaises(GEOSException):
g.transform(2774, clone=True)
@@ -1216,6 +1293,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
# 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(self.geometries.points)
tgeoms.extend(get_geoms(self.geometries.multilinestrings, 4326))
tgeoms.extend(get_geoms(self.geometries.polygons, 3084))
@@ -1231,7 +1309,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_prepared(self):
"Testing PreparedGeometry support."
# Creating a simple multipolygon and getting a prepared version.
- mpoly = GEOSGeometry('MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0)),((5 5,5 10,10 10,10 5,5 5)))')
+ mpoly = GEOSGeometry(
+ "MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0)),((5 5,5 10,10 10,10 5,5 5)))"
+ )
prep = mpoly.prepared
# A set of test points.
@@ -1242,7 +1322,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt))
self.assertEqual(mpoly.covers(pnt), prep.covers(pnt))
- self.assertTrue(prep.crosses(fromstr('LINESTRING(1 1, 15 15)')))
+ self.assertTrue(prep.crosses(fromstr("LINESTRING(1 1, 15 15)")))
self.assertTrue(prep.disjoint(Point(-5, -5)))
poly = Polygon(((-1, -1), (1, 1), (1, 0), (-1, -1)))
self.assertTrue(prep.overlaps(poly))
@@ -1257,12 +1337,14 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_line_merge(self):
"Testing line merge support"
- ref_geoms = (fromstr('LINESTRING(1 1, 1 1, 3 3)'),
- fromstr('MULTILINESTRING((1 1, 3 3), (3 3, 4 2))'),
- )
- ref_merged = (fromstr('LINESTRING(1 1, 3 3)'),
- fromstr('LINESTRING (1 1, 3 3, 4 2)'),
- )
+ ref_geoms = (
+ fromstr("LINESTRING(1 1, 1 1, 3 3)"),
+ fromstr("MULTILINESTRING((1 1, 3 3), (3 3, 4 2))"),
+ )
+ ref_merged = (
+ fromstr("LINESTRING(1 1, 3 3)"),
+ fromstr("LINESTRING (1 1, 3 3, 4 2)"),
+ )
for geom, merged in zip(ref_geoms, ref_merged):
self.assertEqual(merged, geom.merged)
@@ -1278,13 +1360,15 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertFalse(g.valid)
self.assertIsInstance(g.valid_reason, str)
- self.assertTrue(g.valid_reason.startswith("Too few points in geometry component"))
+ self.assertTrue(
+ g.valid_reason.startswith("Too few points in geometry component")
+ )
def test_linearref(self):
"Testing linear referencing"
- ls = fromstr('LINESTRING(0 0, 0 10, 10 10, 10 0)')
- mls = fromstr('MULTILINESTRING((0 0, 0 10), (10 0, 10 10))')
+ ls = fromstr("LINESTRING(0 0, 0 10, 10 10, 10 0)")
+ mls = fromstr("MULTILINESTRING((0 0, 0 10), (10 0, 10 10))")
self.assertEqual(ls.project(Point(0, 20)), 10.0)
self.assertEqual(ls.project(Point(7, 6)), 24)
@@ -1306,39 +1390,39 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
"""
point = Point(4.337844, 50.827537, srid=4326)
path, args, kwargs = point.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.point.Point')
+ self.assertEqual(path, "django.contrib.gis.geos.point.Point")
self.assertEqual(args, (4.337844, 50.827537))
- self.assertEqual(kwargs, {'srid': 4326})
+ self.assertEqual(kwargs, {"srid": 4326})
ls = LineString(((0, 0), (1, 1)))
path, args, kwargs = ls.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.linestring.LineString')
+ self.assertEqual(path, "django.contrib.gis.geos.linestring.LineString")
self.assertEqual(args, (((0, 0), (1, 1)),))
self.assertEqual(kwargs, {})
ls2 = LineString([Point(0, 0), Point(1, 1)], srid=4326)
path, args, kwargs = ls2.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.linestring.LineString')
+ self.assertEqual(path, "django.contrib.gis.geos.linestring.LineString")
self.assertEqual(args, ([Point(0, 0), Point(1, 1)],))
- self.assertEqual(kwargs, {'srid': 4326})
+ self.assertEqual(kwargs, {"srid": 4326})
ext_coords = ((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))
int_coords = ((0.4, 0.4), (0.4, 0.6), (0.6, 0.6), (0.6, 0.4), (0.4, 0.4))
poly = Polygon(ext_coords, int_coords)
path, args, kwargs = poly.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.polygon.Polygon')
+ self.assertEqual(path, "django.contrib.gis.geos.polygon.Polygon")
self.assertEqual(args, (ext_coords, int_coords))
self.assertEqual(kwargs, {})
lr = LinearRing((0, 0), (0, 1), (1, 1), (0, 0))
path, args, kwargs = lr.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.linestring.LinearRing')
+ self.assertEqual(path, "django.contrib.gis.geos.linestring.LinearRing")
self.assertEqual(args, ((0, 0), (0, 1), (1, 1), (0, 0)))
self.assertEqual(kwargs, {})
mp = MultiPoint(Point(0, 0), Point(1, 1))
path, args, kwargs = mp.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.collections.MultiPoint')
+ self.assertEqual(path, "django.contrib.gis.geos.collections.MultiPoint")
self.assertEqual(args, (Point(0, 0), Point(1, 1)))
self.assertEqual(kwargs, {})
@@ -1346,7 +1430,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
ls2 = LineString((2, 2), (3, 3))
mls = MultiLineString(ls1, ls2)
path, args, kwargs = mls.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.collections.MultiLineString')
+ self.assertEqual(path, "django.contrib.gis.geos.collections.MultiLineString")
self.assertEqual(args, (ls1, ls2))
self.assertEqual(kwargs, {})
@@ -1354,15 +1438,17 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
p2 = Polygon(((1, 1), (1, 2), (2, 2), (1, 1)))
mp = MultiPolygon(p1, p2)
path, args, kwargs = mp.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.collections.MultiPolygon')
+ self.assertEqual(path, "django.contrib.gis.geos.collections.MultiPolygon")
self.assertEqual(args, (p1, p2))
self.assertEqual(kwargs, {})
poly = Polygon(((0, 0), (0, 1), (1, 1), (0, 0)))
gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)
path, args, kwargs = gc.deconstruct()
- self.assertEqual(path, 'django.contrib.gis.geos.collections.GeometryCollection')
- self.assertEqual(args, (Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly))
+ self.assertEqual(path, "django.contrib.gis.geos.collections.GeometryCollection")
+ self.assertEqual(
+ args, (Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)
+ )
self.assertEqual(kwargs, {})
def test_subclassing(self):
@@ -1370,6 +1456,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
GEOSGeometry subclass may itself be subclassed without being forced-cast
to the parent class during `__init__`.
"""
+
class ExtendedPolygon(Polygon):
def __init__(self, *args, data=0, **kwargs):
super().__init__(*args, **kwargs)
@@ -1381,7 +1468,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
ext_poly = ExtendedPolygon(((0, 0), (0, 1), (1, 1), (0, 0)), data=3)
self.assertEqual(type(ext_poly), ExtendedPolygon)
# ExtendedPolygon.__str__ should be called (instead of Polygon.__str__).
- self.assertEqual(str(ext_poly), "EXT_POLYGON - data: 3 - POLYGON ((0 0, 0 1, 1 1, 0 0))")
+ self.assertEqual(
+ str(ext_poly), "EXT_POLYGON - data: 3 - POLYGON ((0 0, 0 1, 1 1, 0 0))"
+ )
self.assertJSONEqual(
ext_poly.json,
'{"coordinates": [[[0, 0], [0, 1], [1, 1], [0, 0]]], "type": "Polygon"}',
@@ -1389,56 +1478,63 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
def test_geos_version_tuple(self):
versions = (
- (b'3.0.0rc4-CAPI-1.3.3', (3, 0, 0)),
- (b'3.0.0-CAPI-1.4.1', (3, 0, 0)),
- (b'3.4.0dev-CAPI-1.8.0', (3, 4, 0)),
- (b'3.4.0dev-CAPI-1.8.0 r0', (3, 4, 0)),
- (b'3.6.2-CAPI-1.10.2 4d2925d6', (3, 6, 2)),
+ (b"3.0.0rc4-CAPI-1.3.3", (3, 0, 0)),
+ (b"3.0.0-CAPI-1.4.1", (3, 0, 0)),
+ (b"3.4.0dev-CAPI-1.8.0", (3, 4, 0)),
+ (b"3.4.0dev-CAPI-1.8.0 r0", (3, 4, 0)),
+ (b"3.6.2-CAPI-1.10.2 4d2925d6", (3, 6, 2)),
)
for version_string, version_tuple in versions:
with self.subTest(version_string=version_string):
- with mock.patch('django.contrib.gis.geos.libgeos.geos_version', lambda: version_string):
+ with mock.patch(
+ "django.contrib.gis.geos.libgeos.geos_version",
+ lambda: version_string,
+ ):
self.assertEqual(geos_version_tuple(), version_tuple)
def test_from_gml(self):
self.assertEqual(
- GEOSGeometry('POINT(0 0)'),
+ GEOSGeometry("POINT(0 0)"),
GEOSGeometry.from_gml(
'<gml:Point gml:id="p21" srsName="http://www.opengis.net/def/crs/EPSG/0/4326">'
' <gml:pos srsDimension="2">0 0</gml:pos>'
- '</gml:Point>'
+ "</gml:Point>"
),
)
def test_from_ewkt(self):
- self.assertEqual(GEOSGeometry.from_ewkt('SRID=1;POINT(1 1)'), Point(1, 1, srid=1))
- self.assertEqual(GEOSGeometry.from_ewkt('POINT(1 1)'), Point(1, 1))
+ self.assertEqual(
+ GEOSGeometry.from_ewkt("SRID=1;POINT(1 1)"), Point(1, 1, srid=1)
+ )
+ self.assertEqual(GEOSGeometry.from_ewkt("POINT(1 1)"), Point(1, 1))
def test_from_ewkt_empty_string(self):
- msg = 'Expected WKT but got an empty string.'
+ msg = "Expected WKT but got an empty string."
with self.assertRaisesMessage(ValueError, msg):
- GEOSGeometry.from_ewkt('')
+ GEOSGeometry.from_ewkt("")
with self.assertRaisesMessage(ValueError, msg):
- GEOSGeometry.from_ewkt('SRID=1;')
+ GEOSGeometry.from_ewkt("SRID=1;")
def test_from_ewkt_invalid_srid(self):
- msg = 'EWKT has invalid SRID part.'
+ msg = "EWKT has invalid SRID part."
with self.assertRaisesMessage(ValueError, msg):
- GEOSGeometry.from_ewkt('SRUD=1;POINT(1 1)')
+ GEOSGeometry.from_ewkt("SRUD=1;POINT(1 1)")
with self.assertRaisesMessage(ValueError, msg):
- GEOSGeometry.from_ewkt('SRID=WGS84;POINT(1 1)')
+ GEOSGeometry.from_ewkt("SRID=WGS84;POINT(1 1)")
def test_fromstr_scientific_wkt(self):
- self.assertEqual(GEOSGeometry('POINT(1.0e-1 1.0e+1)'), Point(.1, 10))
+ self.assertEqual(GEOSGeometry("POINT(1.0e-1 1.0e+1)"), Point(0.1, 10))
def test_normalize(self):
g = MultiPoint(Point(0, 0), Point(2, 2), Point(1, 1))
self.assertIsNone(g.normalize())
- self.assertTrue(g.equals_exact(MultiPoint(Point(2, 2), Point(1, 1), Point(0, 0))))
+ self.assertTrue(
+ g.equals_exact(MultiPoint(Point(2, 2), Point(1, 1), Point(0, 0)))
+ )
- @skipIf(geos_version_tuple() < (3, 8), 'GEOS >= 3.8.0 is required')
+ @skipIf(geos_version_tuple() < (3, 8), "GEOS >= 3.8.0 is required")
def test_make_valid(self):
- poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 0, 23 23, 0 0))')
+ poly = GEOSGeometry("POLYGON((0 0, 0 23, 23 0, 23 23, 0 0))")
self.assertIs(poly.valid, False)
valid_poly = poly.make_valid()
self.assertIs(valid_poly.valid, True)
@@ -1448,10 +1544,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertIs(valid_poly2.valid, True)
self.assertEqual(valid_poly, valid_poly2)
- @mock.patch('django.contrib.gis.geos.libgeos.geos_version', lambda: b'3.7.3')
+ @mock.patch("django.contrib.gis.geos.libgeos.geos_version", lambda: b"3.7.3")
def test_make_valid_geos_version(self):
- msg = 'GEOSGeometry.make_valid() requires GEOS >= 3.8.0.'
- poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 0, 23 23, 0 0))')
+ msg = "GEOSGeometry.make_valid() requires GEOS >= 3.8.0."
+ poly = GEOSGeometry("POLYGON((0 0, 0 23, 23 0, 23 23, 0 0))")
with self.assertRaisesMessage(GEOSException, msg):
poly.make_valid()
diff --git a/tests/gis_tests/geos_tests/test_geos_mutation.py b/tests/gis_tests/geos_tests/test_geos_mutation.py
index 2eedef31d9..c239ab3efe 100644
--- a/tests/gis_tests/geos_tests/test_geos_mutation.py
+++ b/tests/gis_tests/geos_tests/test_geos_mutation.py
@@ -5,7 +5,12 @@
import unittest
from django.contrib.gis.geos import (
- LinearRing, LineString, MultiPoint, Point, Polygon, fromstr,
+ LinearRing,
+ LineString,
+ MultiPoint,
+ Point,
+ Polygon,
+ fromstr,
)
@@ -66,8 +71,9 @@ def api_get_length(x):
geos_function_tests = [
- val for name, val in vars().items()
- if hasattr(val, '__call__') and name.startswith('api_get_')
+ val
+ for name, val in vars().items()
+ if hasattr(val, "__call__") and name.startswith("api_get_")
]
@@ -78,7 +84,7 @@ class GEOSMutationTest(unittest.TestCase):
"""
def test00_GEOSIndexException(self):
- 'Testing Geometry IndexError'
+ "Testing Geometry IndexError"
p = Point(1, 2)
for i in range(-2, 2):
p._checkindex(i)
@@ -88,87 +94,124 @@ class GEOSMutationTest(unittest.TestCase):
p._checkindex(-3)
def test01_PointMutations(self):
- 'Testing Point mutations'
- for p in (Point(1, 2, 3), fromstr('POINT (1 2 3)')):
- self.assertEqual(p._get_single_external(1), 2.0, 'Point _get_single_external')
+ "Testing Point mutations"
+ for p in (Point(1, 2, 3), fromstr("POINT (1 2 3)")):
+ self.assertEqual(
+ p._get_single_external(1), 2.0, "Point _get_single_external"
+ )
# _set_single
p._set_single(0, 100)
- self.assertEqual(p.coords, (100.0, 2.0, 3.0), 'Point _set_single')
+ self.assertEqual(p.coords, (100.0, 2.0, 3.0), "Point _set_single")
# _set_list
p._set_list(2, (50, 3141))
- self.assertEqual(p.coords, (50.0, 3141.0), 'Point _set_list')
+ self.assertEqual(p.coords, (50.0, 3141.0), "Point _set_list")
def test02_PointExceptions(self):
- 'Testing Point exceptions'
+ "Testing Point exceptions"
with self.assertRaises(TypeError):
Point(range(1))
with self.assertRaises(TypeError):
Point(range(4))
def test03_PointApi(self):
- 'Testing Point API'
+ "Testing Point API"
q = Point(4, 5, 3)
- for p in (Point(1, 2, 3), fromstr('POINT (1 2 3)')):
+ for p in (Point(1, 2, 3), fromstr("POINT (1 2 3)")):
p[0:2] = [4, 5]
for f in geos_function_tests:
- self.assertEqual(f(q), f(p), 'Point ' + f.__name__)
+ self.assertEqual(f(q), f(p), "Point " + f.__name__)
def test04_LineStringMutations(self):
- 'Testing LineString mutations'
- for ls in (LineString((1, 0), (4, 1), (6, -1)),
- fromstr('LINESTRING (1 0,4 1,6 -1)')):
- self.assertEqual(ls._get_single_external(1), (4.0, 1.0), 'LineString _get_single_external')
+ "Testing LineString mutations"
+ for ls in (
+ LineString((1, 0), (4, 1), (6, -1)),
+ fromstr("LINESTRING (1 0,4 1,6 -1)"),
+ ):
+ self.assertEqual(
+ ls._get_single_external(1),
+ (4.0, 1.0),
+ "LineString _get_single_external",
+ )
# _set_single
ls._set_single(0, (-50, 25))
- self.assertEqual(ls.coords, ((-50.0, 25.0), (4.0, 1.0), (6.0, -1.0)), 'LineString _set_single')
+ self.assertEqual(
+ ls.coords,
+ ((-50.0, 25.0), (4.0, 1.0), (6.0, -1.0)),
+ "LineString _set_single",
+ )
# _set_list
ls._set_list(2, ((-50.0, 25.0), (6.0, -1.0)))
- self.assertEqual(ls.coords, ((-50.0, 25.0), (6.0, -1.0)), 'LineString _set_list')
+ self.assertEqual(
+ ls.coords, ((-50.0, 25.0), (6.0, -1.0)), "LineString _set_list"
+ )
lsa = LineString(ls.coords)
for f in geos_function_tests:
- self.assertEqual(f(lsa), f(ls), 'LineString ' + f.__name__)
+ self.assertEqual(f(lsa), f(ls), "LineString " + f.__name__)
def test05_Polygon(self):
- 'Testing Polygon mutations'
- for pg in (Polygon(((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)),
- ((5, 4), (6, 4), (6, 3), (5, 4))),
- fromstr('POLYGON ((1 0,4 1,6 -1,8 10,1 0),(5 4,6 4,6 3,5 4))')):
- self.assertEqual(pg._get_single_external(0),
- LinearRing((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)),
- 'Polygon _get_single_external(0)')
- self.assertEqual(pg._get_single_external(1),
- LinearRing((5, 4), (6, 4), (6, 3), (5, 4)),
- 'Polygon _get_single_external(1)')
+ "Testing Polygon mutations"
+ for pg in (
+ Polygon(
+ ((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)),
+ ((5, 4), (6, 4), (6, 3), (5, 4)),
+ ),
+ fromstr("POLYGON ((1 0,4 1,6 -1,8 10,1 0),(5 4,6 4,6 3,5 4))"),
+ ):
+ self.assertEqual(
+ pg._get_single_external(0),
+ LinearRing((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)),
+ "Polygon _get_single_external(0)",
+ )
+ self.assertEqual(
+ pg._get_single_external(1),
+ LinearRing((5, 4), (6, 4), (6, 3), (5, 4)),
+ "Polygon _get_single_external(1)",
+ )
# _set_list
- pg._set_list(2, (((1, 2), (10, 0), (12, 9), (-1, 15), (1, 2)), ((4, 2), (5, 2), (5, 3), (4, 2))))
+ pg._set_list(
+ 2,
+ (
+ ((1, 2), (10, 0), (12, 9), (-1, 15), (1, 2)),
+ ((4, 2), (5, 2), (5, 3), (4, 2)),
+ ),
+ )
self.assertEqual(
pg.coords,
- (((1.0, 2.0), (10.0, 0.0), (12.0, 9.0), (-1.0, 15.0), (1.0, 2.0)),
- ((4.0, 2.0), (5.0, 2.0), (5.0, 3.0), (4.0, 2.0))),
- 'Polygon _set_list')
+ (
+ ((1.0, 2.0), (10.0, 0.0), (12.0, 9.0), (-1.0, 15.0), (1.0, 2.0)),
+ ((4.0, 2.0), (5.0, 2.0), (5.0, 3.0), (4.0, 2.0)),
+ ),
+ "Polygon _set_list",
+ )
lsa = Polygon(*pg.coords)
for f in geos_function_tests:
- self.assertEqual(f(lsa), f(pg), 'Polygon ' + f.__name__)
+ self.assertEqual(f(lsa), f(pg), "Polygon " + f.__name__)
def test06_Collection(self):
- 'Testing Collection mutations'
+ "Testing Collection mutations"
points = (
MultiPoint(*map(Point, ((3, 4), (-1, 2), (5, -4), (2, 8)))),
- fromstr('MULTIPOINT (3 4,-1 2,5 -4,2 8)'),
+ fromstr("MULTIPOINT (3 4,-1 2,5 -4,2 8)"),
)
for mp in points:
- self.assertEqual(mp._get_single_external(2), Point(5, -4), 'Collection _get_single_external')
+ self.assertEqual(
+ mp._get_single_external(2),
+ Point(5, -4),
+ "Collection _get_single_external",
+ )
mp._set_list(3, map(Point, ((5, 5), (3, -2), (8, 1))))
- self.assertEqual(mp.coords, ((5.0, 5.0), (3.0, -2.0), (8.0, 1.0)), 'Collection _set_list')
+ self.assertEqual(
+ mp.coords, ((5.0, 5.0), (3.0, -2.0), (8.0, 1.0)), "Collection _set_list"
+ )
lsa = MultiPoint(*map(Point, ((5, 5), (3, -2), (8, 1))))
for f in geos_function_tests:
- self.assertEqual(f(lsa), f(mp), 'MultiPoint ' + f.__name__)
+ self.assertEqual(f(lsa), f(mp), "MultiPoint " + f.__name__)
diff --git a/tests/gis_tests/geos_tests/test_io.py b/tests/gis_tests/geos_tests/test_io.py
index a2efc650c8..b9d24cc63e 100644
--- a/tests/gis_tests/geos_tests/test_io.py
+++ b/tests/gis_tests/geos_tests/test_io.py
@@ -1,18 +1,23 @@
import binascii
from django.contrib.gis.geos import (
- GEOSGeometry, Point, Polygon, WKBReader, WKBWriter, WKTReader, WKTWriter,
+ GEOSGeometry,
+ Point,
+ Polygon,
+ WKBReader,
+ WKBWriter,
+ WKTReader,
+ WKTWriter,
)
from django.contrib.gis.geos.libgeos import geos_version_tuple
from django.test import SimpleTestCase
class GEOSIOTest(SimpleTestCase):
-
def test01_wktreader(self):
# Creating a WKTReader instance
wkt_r = WKTReader()
- wkt = 'POINT (5 23)'
+ wkt = "POINT (5 23)"
# read() should return a GEOSGeometry
ref = GEOSGeometry(wkt)
@@ -26,7 +31,7 @@ class GEOSIOTest(SimpleTestCase):
with self.assertRaises(TypeError):
wkt_r.read(1)
with self.assertRaises(TypeError):
- wkt_r.read(memoryview(b'foo'))
+ wkt_r.read(memoryview(b"foo"))
def test02_wktwriter(self):
# Creating a WKTWriter instance, testing its ptr property.
@@ -34,24 +39,24 @@ class GEOSIOTest(SimpleTestCase):
with self.assertRaises(TypeError):
wkt_w.ptr = WKTReader.ptr_type()
- ref = GEOSGeometry('POINT (5 23)')
- ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)'
+ ref = GEOSGeometry("POINT (5 23)")
+ ref_wkt = "POINT (5.0000000000000000 23.0000000000000000)"
self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
def test_wktwriter_constructor_arguments(self):
wkt_w = WKTWriter(dim=3, trim=True, precision=3)
- ref = GEOSGeometry('POINT (5.34562 23 1.5)')
+ ref = GEOSGeometry("POINT (5.34562 23 1.5)")
if geos_version_tuple() > (3, 10):
- ref_wkt = 'POINT Z (5.346 23 1.5)'
+ ref_wkt = "POINT Z (5.346 23 1.5)"
else:
- ref_wkt = 'POINT Z (5.35 23 1.5)'
+ ref_wkt = "POINT Z (5.35 23 1.5)"
self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
def test03_wkbreader(self):
# Creating a WKBReader instance
wkb_r = WKBReader()
- hex = b'000000000140140000000000004037000000000000'
+ hex = b"000000000140140000000000004037000000000000"
wkb = memoryview(binascii.a2b_hex(hex))
ref = GEOSGeometry(hex)
@@ -72,17 +77,17 @@ class GEOSIOTest(SimpleTestCase):
# Representations of 'POINT (5 23)' in hex -- one normal and
# the other with the byte order changed.
- g = GEOSGeometry('POINT (5 23)')
- hex1 = b'010100000000000000000014400000000000003740'
+ g = GEOSGeometry("POINT (5 23)")
+ hex1 = b"010100000000000000000014400000000000003740"
wkb1 = memoryview(binascii.a2b_hex(hex1))
- hex2 = b'000000000140140000000000004037000000000000'
+ hex2 = b"000000000140140000000000004037000000000000"
wkb2 = memoryview(binascii.a2b_hex(hex2))
self.assertEqual(hex1, wkb_w.write_hex(g))
self.assertEqual(wkb1, wkb_w.write(g))
# Ensuring bad byteorders are not accepted.
- for bad_byteorder in (-1, 2, 523, 'foo', None):
+ for bad_byteorder in (-1, 2, 523, "foo", None):
# Equivalent of `wkb_w.byteorder = bad_byteorder`
with self.assertRaises(ValueError):
wkb_w._set_byteorder(bad_byteorder)
@@ -96,17 +101,21 @@ class GEOSIOTest(SimpleTestCase):
wkb_w.byteorder = 1
# Now, trying out the 3D and SRID flags.
- g = GEOSGeometry('POINT (5 23 17)')
+ g = GEOSGeometry("POINT (5 23 17)")
g.srid = 4326
- hex3d = b'0101000080000000000000144000000000000037400000000000003140'
+ hex3d = b"0101000080000000000000144000000000000037400000000000003140"
wkb3d = memoryview(binascii.a2b_hex(hex3d))
- hex3d_srid = b'01010000A0E6100000000000000000144000000000000037400000000000003140'
+ hex3d_srid = (
+ b"01010000A0E6100000000000000000144000000000000037400000000000003140"
+ )
wkb3d_srid = memoryview(binascii.a2b_hex(hex3d_srid))
# Ensuring bad output dimensions are not accepted
- for bad_outdim in (-1, 0, 1, 4, 423, 'foo', None):
- with self.assertRaisesMessage(ValueError, 'WKB output dimension must be 2 or 3'):
+ for bad_outdim in (-1, 0, 1, 4, 423, "foo", None):
+ with self.assertRaisesMessage(
+ ValueError, "WKB output dimension must be 2 or 3"
+ ):
wkb_w.outdim = bad_outdim
# Now setting the output dimensions to be 3
@@ -123,53 +132,73 @@ class GEOSIOTest(SimpleTestCase):
def test_wkt_writer_trim(self):
wkt_w = WKTWriter()
self.assertFalse(wkt_w.trim)
- self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1.0000000000000000 1.0000000000000000)')
+ self.assertEqual(
+ wkt_w.write(Point(1, 1)), b"POINT (1.0000000000000000 1.0000000000000000)"
+ )
wkt_w.trim = True
self.assertTrue(wkt_w.trim)
- self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1 1)')
- self.assertEqual(wkt_w.write(Point(1.1, 1)), b'POINT (1.1 1)')
- self.assertEqual(wkt_w.write(Point(1. / 3, 1)), b'POINT (0.3333333333333333 1)')
+ self.assertEqual(wkt_w.write(Point(1, 1)), b"POINT (1 1)")
+ self.assertEqual(wkt_w.write(Point(1.1, 1)), b"POINT (1.1 1)")
+ self.assertEqual(
+ wkt_w.write(Point(1.0 / 3, 1)), b"POINT (0.3333333333333333 1)"
+ )
wkt_w.trim = False
self.assertFalse(wkt_w.trim)
- self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1.0000000000000000 1.0000000000000000)')
+ self.assertEqual(
+ wkt_w.write(Point(1, 1)), b"POINT (1.0000000000000000 1.0000000000000000)"
+ )
def test_wkt_writer_precision(self):
wkt_w = WKTWriter()
self.assertIsNone(wkt_w.precision)
- self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3333333333333333 0.6666666666666666)')
+ self.assertEqual(
+ wkt_w.write(Point(1.0 / 3, 2.0 / 3)),
+ b"POINT (0.3333333333333333 0.6666666666666666)",
+ )
wkt_w.precision = 1
self.assertEqual(wkt_w.precision, 1)
- self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3 0.7)')
+ self.assertEqual(wkt_w.write(Point(1.0 / 3, 2.0 / 3)), b"POINT (0.3 0.7)")
wkt_w.precision = 0
self.assertEqual(wkt_w.precision, 0)
- self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0 1)')
+ self.assertEqual(wkt_w.write(Point(1.0 / 3, 2.0 / 3)), b"POINT (0 1)")
wkt_w.precision = None
self.assertIsNone(wkt_w.precision)
- self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3333333333333333 0.6666666666666666)')
+ self.assertEqual(
+ wkt_w.write(Point(1.0 / 3, 2.0 / 3)),
+ b"POINT (0.3333333333333333 0.6666666666666666)",
+ )
- with self.assertRaisesMessage(AttributeError, 'WKT output rounding precision must be '):
- wkt_w.precision = 'potato'
+ with self.assertRaisesMessage(
+ AttributeError, "WKT output rounding precision must be "
+ ):
+ wkt_w.precision = "potato"
def test_empty_point_wkb(self):
p = Point(srid=4326)
wkb_w = WKBWriter()
wkb_w.srid = False
- with self.assertRaisesMessage(ValueError, 'Empty point is not representable in WKB.'):
+ with self.assertRaisesMessage(
+ ValueError, "Empty point is not representable in WKB."
+ ):
wkb_w.write(p)
- with self.assertRaisesMessage(ValueError, 'Empty point is not representable in WKB.'):
+ with self.assertRaisesMessage(
+ ValueError, "Empty point is not representable in WKB."
+ ):
wkb_w.write_hex(p)
wkb_w.srid = True
- for byteorder, hex in enumerate([
- b'0020000001000010E67FF80000000000007FF8000000000000',
- b'0101000020E6100000000000000000F87F000000000000F87F',
- ]):
+ for byteorder, hex in enumerate(
+ [
+ b"0020000001000010E67FF80000000000007FF8000000000000",
+ b"0101000020E6100000000000000000F87F000000000000F87F",
+ ]
+ ):
wkb_w.byteorder = byteorder
self.assertEqual(wkb_w.write_hex(p), hex)
self.assertEqual(GEOSGeometry(wkb_w.write_hex(p)), p)
@@ -181,14 +210,18 @@ class GEOSIOTest(SimpleTestCase):
p_no_srid = Polygon()
wkb_w = WKBWriter()
wkb_w.srid = True
- for byteorder, hexes in enumerate([
- (b'000000000300000000', b'0020000003000010E600000000'),
- (b'010300000000000000', b'0103000020E610000000000000'),
- ]):
+ for byteorder, hexes in enumerate(
+ [
+ (b"000000000300000000", b"0020000003000010E600000000"),
+ (b"010300000000000000", b"0103000020E610000000000000"),
+ ]
+ ):
wkb_w.byteorder = byteorder
for srid, hex in enumerate(hexes):
wkb_w.srid = srid
self.assertEqual(wkb_w.write_hex(p), hex)
- self.assertEqual(GEOSGeometry(wkb_w.write_hex(p)), p if srid else p_no_srid)
+ self.assertEqual(
+ GEOSGeometry(wkb_w.write_hex(p)), p if srid else p_no_srid
+ )
self.assertEqual(wkb_w.write(p), memoryview(binascii.a2b_hex(hex)))
self.assertEqual(GEOSGeometry(wkb_w.write(p)), p if srid else p_no_srid)
diff --git a/tests/gis_tests/geos_tests/test_mutable_list.py b/tests/gis_tests/geos_tests/test_mutable_list.py
index bb085b2fb2..a092f603cb 100644
--- a/tests/gis_tests/geos_tests/test_mutable_list.py
+++ b/tests/gis_tests/geos_tests/test_mutable_list.py
@@ -29,7 +29,7 @@ class UserListA(ListMixin):
# this would work:
# self._list = self._mytype(items)
# but then we wouldn't be testing length parameter
- itemList = ['x'] * length
+ itemList = ["x"] * length
for i, v in enumerate(items):
itemList[i] = v
@@ -59,6 +59,7 @@ class ListMixinTest(unittest.TestCase):
Tests base class ListMixin by comparing a list clone which is
a ListMixin subclass with a real Python list.
"""
+
limit = 3
listType = UserListA
@@ -75,57 +76,61 @@ class ListMixinTest(unittest.TestCase):
return [*range(-1 - self.limit, 0), *range(1, 1 + self.limit)]
def test01_getslice(self):
- 'Slice retrieval'
+ "Slice retrieval"
pl, ul = self.lists_of_len()
for i in self.limits_plus(1):
- self.assertEqual(pl[i:], ul[i:], 'slice [%d:]' % (i))
- self.assertEqual(pl[:i], ul[:i], 'slice [:%d]' % (i))
+ self.assertEqual(pl[i:], ul[i:], "slice [%d:]" % (i))
+ self.assertEqual(pl[:i], ul[:i], "slice [:%d]" % (i))
for j in self.limits_plus(1):
- self.assertEqual(pl[i:j], ul[i:j], 'slice [%d:%d]' % (i, j))
+ self.assertEqual(pl[i:j], ul[i:j], "slice [%d:%d]" % (i, j))
for k in self.step_range():
- self.assertEqual(pl[i:j:k], ul[i:j:k], 'slice [%d:%d:%d]' % (i, j, k))
+ self.assertEqual(
+ pl[i:j:k], ul[i:j:k], "slice [%d:%d:%d]" % (i, j, k)
+ )
for k in self.step_range():
- self.assertEqual(pl[i::k], ul[i::k], 'slice [%d::%d]' % (i, k))
- self.assertEqual(pl[:i:k], ul[:i:k], 'slice [:%d:%d]' % (i, k))
+ self.assertEqual(pl[i::k], ul[i::k], "slice [%d::%d]" % (i, k))
+ self.assertEqual(pl[:i:k], ul[:i:k], "slice [:%d:%d]" % (i, k))
for k in self.step_range():
- self.assertEqual(pl[::k], ul[::k], 'slice [::%d]' % (k))
+ self.assertEqual(pl[::k], ul[::k], "slice [::%d]" % (k))
def test02_setslice(self):
- 'Slice assignment'
+ "Slice assignment"
+
def setfcn(x, i, j, k, L):
x[i:j:k] = range(L)
+
pl, ul = self.lists_of_len()
for slen in range(self.limit + 1):
ssl = nextRange(slen)
ul[:] = ssl
pl[:] = ssl
- self.assertEqual(pl, ul[:], 'set slice [:]')
+ self.assertEqual(pl, ul[:], "set slice [:]")
for i in self.limits_plus(1):
ssl = nextRange(slen)
ul[i:] = ssl
pl[i:] = ssl
- self.assertEqual(pl, ul[:], 'set slice [%d:]' % (i))
+ self.assertEqual(pl, ul[:], "set slice [%d:]" % (i))
ssl = nextRange(slen)
ul[:i] = ssl
pl[:i] = ssl
- self.assertEqual(pl, ul[:], 'set slice [:%d]' % (i))
+ self.assertEqual(pl, ul[:], "set slice [:%d]" % (i))
for j in self.limits_plus(1):
ssl = nextRange(slen)
ul[i:j] = ssl
pl[i:j] = ssl
- self.assertEqual(pl, ul[:], 'set slice [%d:%d]' % (i, j))
+ self.assertEqual(pl, ul[:], "set slice [%d:%d]" % (i, j))
for k in self.step_range():
ssl = nextRange(len(ul[i:j:k]))
ul[i:j:k] = ssl
pl[i:j:k] = ssl
- self.assertEqual(pl, ul[:], 'set slice [%d:%d:%d]' % (i, j, k))
+ self.assertEqual(pl, ul[:], "set slice [%d:%d:%d]" % (i, j, k))
sliceLen = len(ul[i:j:k])
with self.assertRaises(ValueError):
@@ -138,83 +143,86 @@ class ListMixinTest(unittest.TestCase):
ssl = nextRange(len(ul[i::k]))
ul[i::k] = ssl
pl[i::k] = ssl
- self.assertEqual(pl, ul[:], 'set slice [%d::%d]' % (i, k))
+ self.assertEqual(pl, ul[:], "set slice [%d::%d]" % (i, k))
ssl = nextRange(len(ul[:i:k]))
ul[:i:k] = ssl
pl[:i:k] = ssl
- self.assertEqual(pl, ul[:], 'set slice [:%d:%d]' % (i, k))
+ self.assertEqual(pl, ul[:], "set slice [:%d:%d]" % (i, k))
for k in self.step_range():
ssl = nextRange(len(ul[::k]))
ul[::k] = ssl
pl[::k] = ssl
- self.assertEqual(pl, ul[:], 'set slice [::%d]' % (k))
+ self.assertEqual(pl, ul[:], "set slice [::%d]" % (k))
def test03_delslice(self):
- 'Delete slice'
+ "Delete slice"
for Len in range(self.limit):
pl, ul = self.lists_of_len(Len)
del pl[:]
del ul[:]
- self.assertEqual(pl[:], ul[:], 'del slice [:]')
+ self.assertEqual(pl[:], ul[:], "del slice [:]")
for i in range(-Len - 1, Len + 1):
pl, ul = self.lists_of_len(Len)
del pl[i:]
del ul[i:]
- self.assertEqual(pl[:], ul[:], 'del slice [%d:]' % (i))
+ self.assertEqual(pl[:], ul[:], "del slice [%d:]" % (i))
pl, ul = self.lists_of_len(Len)
del pl[:i]
del ul[:i]
- self.assertEqual(pl[:], ul[:], 'del slice [:%d]' % (i))
+ self.assertEqual(pl[:], ul[:], "del slice [:%d]" % (i))
for j in range(-Len - 1, Len + 1):
pl, ul = self.lists_of_len(Len)
del pl[i:j]
del ul[i:j]
- self.assertEqual(pl[:], ul[:], 'del slice [%d:%d]' % (i, j))
+ self.assertEqual(pl[:], ul[:], "del slice [%d:%d]" % (i, j))
for k in [*range(-Len - 1, 0), *range(1, Len)]:
pl, ul = self.lists_of_len(Len)
del pl[i:j:k]
del ul[i:j:k]
- self.assertEqual(pl[:], ul[:], 'del slice [%d:%d:%d]' % (i, j, k))
+ self.assertEqual(
+ pl[:], ul[:], "del slice [%d:%d:%d]" % (i, j, k)
+ )
for k in [*range(-Len - 1, 0), *range(1, Len)]:
pl, ul = self.lists_of_len(Len)
del pl[:i:k]
del ul[:i:k]
- self.assertEqual(pl[:], ul[:], 'del slice [:%d:%d]' % (i, k))
+ self.assertEqual(pl[:], ul[:], "del slice [:%d:%d]" % (i, k))
pl, ul = self.lists_of_len(Len)
del pl[i::k]
del ul[i::k]
- self.assertEqual(pl[:], ul[:], 'del slice [%d::%d]' % (i, k))
+ self.assertEqual(pl[:], ul[:], "del slice [%d::%d]" % (i, k))
for k in [*range(-Len - 1, 0), *range(1, Len)]:
pl, ul = self.lists_of_len(Len)
del pl[::k]
del ul[::k]
- self.assertEqual(pl[:], ul[:], 'del slice [::%d]' % (k))
+ self.assertEqual(pl[:], ul[:], "del slice [::%d]" % (k))
def test04_get_set_del_single(self):
- 'Get/set/delete single item'
+ "Get/set/delete single item"
pl, ul = self.lists_of_len()
for i in self.limits_plus(0):
- self.assertEqual(pl[i], ul[i], 'get single item [%d]' % i)
+ self.assertEqual(pl[i], ul[i], "get single item [%d]" % i)
for i in self.limits_plus(0):
pl, ul = self.lists_of_len()
pl[i] = 100
ul[i] = 100
- self.assertEqual(pl[:], ul[:], 'set single item [%d]' % i)
+ self.assertEqual(pl[:], ul[:], "set single item [%d]" % i)
for i in self.limits_plus(0):
pl, ul = self.lists_of_len()
del pl[i]
del ul[i]
- self.assertEqual(pl[:], ul[:], 'del single item [%d]' % i)
+ self.assertEqual(pl[:], ul[:], "del single item [%d]" % i)
def test05_out_of_range_exceptions(self):
- 'Out of range exceptions'
+ "Out of range exceptions"
+
def setfcn(x, i):
x[i] = 20
@@ -223,6 +231,7 @@ class ListMixinTest(unittest.TestCase):
def delfcn(x, i):
del x[i]
+
pl, ul = self.lists_of_len()
for i in (-1 - self.limit, self.limit):
with self.assertRaises(IndexError): # 'set index %d' % i)
@@ -233,39 +242,40 @@ class ListMixinTest(unittest.TestCase):
delfcn(ul, i)
def test06_list_methods(self):
- 'List methods'
+ "List methods"
pl, ul = self.lists_of_len()
pl.append(40)
ul.append(40)
- self.assertEqual(pl[:], ul[:], 'append')
+ self.assertEqual(pl[:], ul[:], "append")
pl.extend(range(50, 55))
ul.extend(range(50, 55))
- self.assertEqual(pl[:], ul[:], 'extend')
+ self.assertEqual(pl[:], ul[:], "extend")
pl.reverse()
ul.reverse()
- self.assertEqual(pl[:], ul[:], 'reverse')
+ self.assertEqual(pl[:], ul[:], "reverse")
for i in self.limits_plus(1):
pl, ul = self.lists_of_len()
pl.insert(i, 50)
ul.insert(i, 50)
- self.assertEqual(pl[:], ul[:], 'insert at %d' % i)
+ self.assertEqual(pl[:], ul[:], "insert at %d" % i)
for i in self.limits_plus(0):
pl, ul = self.lists_of_len()
- self.assertEqual(pl.pop(i), ul.pop(i), 'popped value at %d' % i)
- self.assertEqual(pl[:], ul[:], 'after pop at %d' % i)
+ self.assertEqual(pl.pop(i), ul.pop(i), "popped value at %d" % i)
+ self.assertEqual(pl[:], ul[:], "after pop at %d" % i)
pl, ul = self.lists_of_len()
- self.assertEqual(pl.pop(), ul.pop(i), 'popped value')
- self.assertEqual(pl[:], ul[:], 'after pop')
+ self.assertEqual(pl.pop(), ul.pop(i), "popped value")
+ self.assertEqual(pl[:], ul[:], "after pop")
pl, ul = self.lists_of_len()
def popfcn(x, i):
x.pop(i)
+
with self.assertRaises(IndexError):
popfcn(ul, self.limit)
with self.assertRaises(IndexError):
@@ -273,29 +283,30 @@ class ListMixinTest(unittest.TestCase):
pl, ul = self.lists_of_len()
for val in range(self.limit):
- self.assertEqual(pl.index(val), ul.index(val), 'index of %d' % val)
+ self.assertEqual(pl.index(val), ul.index(val), "index of %d" % val)
for val in self.limits_plus(2):
- self.assertEqual(pl.count(val), ul.count(val), 'count %d' % val)
+ self.assertEqual(pl.count(val), ul.count(val), "count %d" % val)
for val in range(self.limit):
pl, ul = self.lists_of_len()
pl.remove(val)
ul.remove(val)
- self.assertEqual(pl[:], ul[:], 'after remove val %d' % val)
+ self.assertEqual(pl[:], ul[:], "after remove val %d" % val)
def indexfcn(x, v):
return x.index(v)
def removefcn(x, v):
return x.remove(v)
+
with self.assertRaises(ValueError):
indexfcn(ul, 40)
with self.assertRaises(ValueError):
removefcn(ul, 40)
def test07_allowed_types(self):
- 'Type-restricted list'
+ "Type-restricted list"
pl, ul = self.lists_of_len()
ul._allowed = int
ul[1] = 50
@@ -303,13 +314,14 @@ class ListMixinTest(unittest.TestCase):
def setfcn(x, i, v):
x[i] = v
+
with self.assertRaises(TypeError):
- setfcn(ul, 2, 'hello')
+ setfcn(ul, 2, "hello")
with self.assertRaises(TypeError):
- setfcn(ul, slice(0, 3, 2), ('hello', 'goodbye'))
+ setfcn(ul, slice(0, 3, 2), ("hello", "goodbye"))
def test08_min_length(self):
- 'Length limits'
+ "Length limits"
pl, ul = self.lists_of_len(5)
ul._minlength = 3
@@ -318,12 +330,13 @@ class ListMixinTest(unittest.TestCase):
def setfcn(x, i):
x[:i] = []
+
for i in range(len(ul) - ul._minlength + 1, len(ul)):
with self.assertRaises(ValueError):
delfcn(ul, i)
with self.assertRaises(ValueError):
setfcn(ul, i)
- del ul[:len(ul) - ul._minlength]
+ del ul[: len(ul) - ul._minlength]
ul._maxlength = 4
for i in range(0, ul._maxlength - len(ul)):
@@ -332,99 +345,102 @@ class ListMixinTest(unittest.TestCase):
ul.append(10)
def test09_iterable_check(self):
- 'Error on assigning non-iterable to slice'
+ "Error on assigning non-iterable to slice"
pl, ul = self.lists_of_len(self.limit + 1)
def setfcn(x, i, v):
x[i] = v
+
with self.assertRaises(TypeError):
setfcn(ul, slice(0, 3, 2), 2)
def test10_checkindex(self):
- 'Index check'
+ "Index check"
pl, ul = self.lists_of_len()
for i in self.limits_plus(0):
if i < 0:
- self.assertEqual(ul._checkindex(i), i + self.limit, '_checkindex(neg index)')
+ self.assertEqual(
+ ul._checkindex(i), i + self.limit, "_checkindex(neg index)"
+ )
else:
- self.assertEqual(ul._checkindex(i), i, '_checkindex(pos index)')
+ self.assertEqual(ul._checkindex(i), i, "_checkindex(pos index)")
for i in (-self.limit - 1, self.limit):
with self.assertRaises(IndexError):
ul._checkindex(i)
def test_11_sorting(self):
- 'Sorting'
+ "Sorting"
pl, ul = self.lists_of_len()
pl.insert(0, pl.pop())
ul.insert(0, ul.pop())
pl.sort()
ul.sort()
- self.assertEqual(pl[:], ul[:], 'sort')
+ self.assertEqual(pl[:], ul[:], "sort")
mid = pl[len(pl) // 2]
pl.sort(key=lambda x: (mid - x) ** 2)
ul.sort(key=lambda x: (mid - x) ** 2)
- self.assertEqual(pl[:], ul[:], 'sort w/ key')
+ self.assertEqual(pl[:], ul[:], "sort w/ key")
pl.insert(0, pl.pop())
ul.insert(0, ul.pop())
pl.sort(reverse=True)
ul.sort(reverse=True)
- self.assertEqual(pl[:], ul[:], 'sort w/ reverse')
+ self.assertEqual(pl[:], ul[:], "sort w/ reverse")
mid = pl[len(pl) // 2]
pl.sort(key=lambda x: (mid - x) ** 2)
ul.sort(key=lambda x: (mid - x) ** 2)
- self.assertEqual(pl[:], ul[:], 'sort w/ key')
+ self.assertEqual(pl[:], ul[:], "sort w/ key")
def test_12_arithmetic(self):
- 'Arithmetic'
+ "Arithmetic"
pl, ul = self.lists_of_len()
al = list(range(10, 14))
- self.assertEqual(list(pl + al), list(ul + al), 'add')
- self.assertEqual(type(ul), type(ul + al), 'type of add result')
- self.assertEqual(list(al + pl), list(al + ul), 'radd')
- self.assertEqual(type(al), type(al + ul), 'type of radd result')
+ self.assertEqual(list(pl + al), list(ul + al), "add")
+ self.assertEqual(type(ul), type(ul + al), "type of add result")
+ self.assertEqual(list(al + pl), list(al + ul), "radd")
+ self.assertEqual(type(al), type(al + ul), "type of radd result")
objid = id(ul)
pl += al
ul += al
- self.assertEqual(pl[:], ul[:], 'in-place add')
- self.assertEqual(objid, id(ul), 'in-place add id')
+ self.assertEqual(pl[:], ul[:], "in-place add")
+ self.assertEqual(objid, id(ul), "in-place add id")
for n in (-1, 0, 1, 3):
pl, ul = self.lists_of_len()
- self.assertEqual(list(pl * n), list(ul * n), 'mul by %d' % n)
- self.assertEqual(type(ul), type(ul * n), 'type of mul by %d result' % n)
- self.assertEqual(list(n * pl), list(n * ul), 'rmul by %d' % n)
- self.assertEqual(type(ul), type(n * ul), 'type of rmul by %d result' % n)
+ self.assertEqual(list(pl * n), list(ul * n), "mul by %d" % n)
+ self.assertEqual(type(ul), type(ul * n), "type of mul by %d result" % n)
+ self.assertEqual(list(n * pl), list(n * ul), "rmul by %d" % n)
+ self.assertEqual(type(ul), type(n * ul), "type of rmul by %d result" % n)
objid = id(ul)
pl *= n
ul *= n
- self.assertEqual(pl[:], ul[:], 'in-place mul by %d' % n)
- self.assertEqual(objid, id(ul), 'in-place mul by %d id' % n)
+ self.assertEqual(pl[:], ul[:], "in-place mul by %d" % n)
+ self.assertEqual(objid, id(ul), "in-place mul by %d id" % n)
pl, ul = self.lists_of_len()
- self.assertEqual(pl, ul, 'cmp for equal')
- self.assertNotEqual(ul, pl + [2], 'cmp for not equal')
- self.assertGreaterEqual(pl, ul, 'cmp for gte self')
- self.assertLessEqual(pl, ul, 'cmp for lte self')
- self.assertGreaterEqual(ul, pl, 'cmp for self gte')
- self.assertLessEqual(ul, pl, 'cmp for self lte')
-
- self.assertGreater(pl + [5], ul, 'cmp')
- self.assertGreaterEqual(pl + [5], ul, 'cmp')
- self.assertLess(pl, ul + [2], 'cmp')
- self.assertLessEqual(pl, ul + [2], 'cmp')
- self.assertGreater(ul + [5], pl, 'cmp')
- self.assertGreaterEqual(ul + [5], pl, 'cmp')
- self.assertLess(ul, pl + [2], 'cmp')
- self.assertLessEqual(ul, pl + [2], 'cmp')
+ self.assertEqual(pl, ul, "cmp for equal")
+ self.assertNotEqual(ul, pl + [2], "cmp for not equal")
+ self.assertGreaterEqual(pl, ul, "cmp for gte self")
+ self.assertLessEqual(pl, ul, "cmp for lte self")
+ self.assertGreaterEqual(ul, pl, "cmp for self gte")
+ self.assertLessEqual(ul, pl, "cmp for self lte")
+
+ self.assertGreater(pl + [5], ul, "cmp")
+ self.assertGreaterEqual(pl + [5], ul, "cmp")
+ self.assertLess(pl, ul + [2], "cmp")
+ self.assertLessEqual(pl, ul + [2], "cmp")
+ self.assertGreater(ul + [5], pl, "cmp")
+ self.assertGreaterEqual(ul + [5], pl, "cmp")
+ self.assertLess(ul, pl + [2], "cmp")
+ self.assertLessEqual(ul, pl + [2], "cmp")
pl[1] = 20
- self.assertGreater(pl, ul, 'cmp for gt self')
- self.assertLess(ul, pl, 'cmp for self lt')
+ self.assertGreater(pl, ul, "cmp for gt self")
+ self.assertLess(ul, pl, "cmp for self lt")
pl[1] = -20
- self.assertLess(pl, ul, 'cmp for lt self')
- self.assertGreater(ul, pl, 'cmp for gt self')
+ self.assertLess(pl, ul, "cmp for lt self")
+ self.assertGreater(ul, pl, "cmp for gt self")
class ListMixinTestSingle(ListMixinTest):
diff --git a/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py b/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py
index 35451b3a1e..227d6b668d 100644
--- a/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py
+++ b/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py
@@ -9,10 +9,12 @@ if connection.features.supports_raster:
# PostGIS 3+ requires postgis_raster extension.
if pg_version[1:] >= (3,):
operations = [
- CreateExtension('postgis_raster'),
+ CreateExtension("postgis_raster"),
]
else:
operations = []
+
else:
+
class Migration(migrations.Migration):
operations = []
diff --git a/tests/gis_tests/gis_migrations/migrations/0002_create_models.py b/tests/gis_tests/gis_migrations/migrations/0002_create_models.py
index ee1191d11e..90bfa87389 100644
--- a/tests/gis_tests/gis_migrations/migrations/0002_create_models.py
+++ b/tests/gis_tests/gis_migrations/migrations/0002_create_models.py
@@ -3,63 +3,96 @@ from django.db import connection, migrations
ops = [
migrations.CreateModel(
- name='Neighborhood',
+ name="Neighborhood",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=100, unique=True)),
- ('geom', models.MultiPolygonField(srid=4326)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("name", models.CharField(max_length=100, unique=True)),
+ ("geom", models.MultiPolygonField(srid=4326)),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
migrations.CreateModel(
- name='Household',
+ name="Household",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('neighborhood', models.ForeignKey(
- 'gis_migrations.Neighborhood',
- models.SET_NULL,
- to_field='id',
- null=True,
- )),
- ('address', models.CharField(max_length=100)),
- ('zip_code', models.IntegerField(null=True, blank=True)),
- ('geom', models.PointField(srid=4326, geography=True)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ (
+ "neighborhood",
+ models.ForeignKey(
+ "gis_migrations.Neighborhood",
+ models.SET_NULL,
+ to_field="id",
+ null=True,
+ ),
+ ),
+ ("address", models.CharField(max_length=100)),
+ ("zip_code", models.IntegerField(null=True, blank=True)),
+ ("geom", models.PointField(srid=4326, geography=True)),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
migrations.CreateModel(
- name='Family',
+ name="Family",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=100, unique=True)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("name", models.CharField(max_length=100, unique=True)),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
migrations.AddField(
- model_name='household',
- name='family',
- field=models.ForeignKey('gis_migrations.Family', models.SET_NULL, blank=True, null=True),
+ model_name="household",
+ name="family",
+ field=models.ForeignKey(
+ "gis_migrations.Family", models.SET_NULL, blank=True, null=True
+ ),
preserve_default=True,
- )
+ ),
]
if connection.features.supports_raster:
ops += [
migrations.CreateModel(
- name='Heatmap',
+ name="Heatmap",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=100, unique=True)),
- ('rast', models.fields.RasterField(srid=4326)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("name", models.CharField(max_length=100, unique=True)),
+ ("rast", models.fields.RasterField(srid=4326)),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
]
@@ -69,7 +102,8 @@ class Migration(migrations.Migration):
"""
Used for gis-specific migration tests.
"""
+
dependencies = [
- ('gis_migrations', '0001_setup_extensions'),
+ ("gis_migrations", "0001_setup_extensions"),
]
operations = ops
diff --git a/tests/gis_tests/gis_migrations/test_commands.py b/tests/gis_tests/gis_migrations/test_commands.py
index 31572b1e00..318cd12278 100644
--- a/tests/gis_tests/gis_migrations/test_commands.py
+++ b/tests/gis_tests/gis_migrations/test_commands.py
@@ -7,6 +7,7 @@ class MigrateTests(TransactionTestCase):
"""
Tests running the migrate command in Geodjango.
"""
+
available_apps = ["gis_tests.gis_migrations"]
def get_table_description(self, table):
@@ -52,7 +53,10 @@ class MigrateTests(TransactionTestCase):
pass
else:
qs = GeoColumn.objects.filter(
- **{'%s__in' % GeoColumn.table_name_col(): ["gis_neighborhood", "gis_household"]}
+ **{
+ "%s__in"
+ % GeoColumn.table_name_col(): ["gis_neighborhood", "gis_household"]
+ }
)
self.assertEqual(qs.count(), 0)
# Revert the "unmigration"
diff --git a/tests/gis_tests/gis_migrations/test_operations.py b/tests/gis_tests/gis_migrations/test_operations.py
index b7823dd983..d2ad67945b 100644
--- a/tests/gis_tests/gis_migrations/test_operations.py
+++ b/tests/gis_tests/gis_migrations/test_operations.py
@@ -6,9 +6,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import connection, migrations, models
from django.db.migrations.migration import Migration
from django.db.migrations.state import ProjectState
-from django.test import (
- TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature,
-)
+from django.test import TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature
try:
GeometryColumns = connection.ops.geometry_columns()
@@ -18,25 +16,29 @@ except NotImplementedError:
class OperationTestCase(TransactionTestCase):
- available_apps = ['gis_tests.gis_migrations']
- get_opclass_query = '''
+ available_apps = ["gis_tests.gis_migrations"]
+ get_opclass_query = """
SELECT opcname, c.relname FROM pg_opclass AS oc
JOIN pg_index as i on oc.oid = ANY(i.indclass)
JOIN pg_class as c on c.oid = i.indexrelid
WHERE c.relname = %s
- '''
+ """
def tearDown(self):
# Delete table after testing
- if hasattr(self, 'current_state'):
- self.apply_operations('gis', self.current_state, [migrations.DeleteModel('Neighborhood')])
+ if hasattr(self, "current_state"):
+ self.apply_operations(
+ "gis", self.current_state, [migrations.DeleteModel("Neighborhood")]
+ )
super().tearDown()
@property
def has_spatial_indexes(self):
if connection.ops.mysql:
with connection.cursor() as cursor:
- return connection.introspection.supports_spatial_index(cursor, 'gis_neighborhood')
+ return connection.introspection.supports_spatial_index(
+ cursor, "gis_neighborhood"
+ )
return True
def get_table_description(self, table):
@@ -50,57 +52,67 @@ class OperationTestCase(TransactionTestCase):
self.assertNotIn(column, [c.name for c in self.get_table_description(table)])
def apply_operations(self, app_label, project_state, operations):
- migration = Migration('name', app_label)
+ migration = Migration("name", app_label)
migration.operations = operations
with connection.schema_editor() as editor:
return migration.apply(project_state, editor)
def set_up_test_model(self, force_raster_creation=False):
test_fields = [
- ('id', models.AutoField(primary_key=True)),
- ('name', models.CharField(max_length=100, unique=True)),
- ('geom', fields.MultiPolygonField(srid=4326))
+ ("id", models.AutoField(primary_key=True)),
+ ("name", models.CharField(max_length=100, unique=True)),
+ ("geom", fields.MultiPolygonField(srid=4326)),
]
if connection.features.supports_raster or force_raster_creation:
- test_fields += [('rast', fields.RasterField(srid=4326, null=True))]
- operations = [migrations.CreateModel('Neighborhood', test_fields)]
- self.current_state = self.apply_operations('gis', ProjectState(), operations)
+ test_fields += [("rast", fields.RasterField(srid=4326, null=True))]
+ operations = [migrations.CreateModel("Neighborhood", test_fields)]
+ self.current_state = self.apply_operations("gis", ProjectState(), operations)
def assertGeometryColumnsCount(self, expected_count):
self.assertEqual(
- GeometryColumns.objects.filter(**{
- '%s__iexact' % GeometryColumns.table_name_col(): 'gis_neighborhood',
- }).count(),
- expected_count
+ GeometryColumns.objects.filter(
+ **{
+ "%s__iexact" % GeometryColumns.table_name_col(): "gis_neighborhood",
+ }
+ ).count(),
+ expected_count,
)
def assertSpatialIndexExists(self, table, column, raster=False):
with connection.cursor() as cursor:
constraints = connection.introspection.get_constraints(cursor, table)
if raster:
- self.assertTrue(any(
- 'st_convexhull(%s)' % column in c['definition']
- for c in constraints.values()
- if c['definition'] is not None
- ))
+ self.assertTrue(
+ any(
+ "st_convexhull(%s)" % column in c["definition"]
+ for c in constraints.values()
+ if c["definition"] is not None
+ )
+ )
else:
- self.assertIn([column], [c['columns'] for c in constraints.values()])
-
- def alter_gis_model(self, migration_class, model_name, field_name,
- blank=False, field_class=None, field_class_kwargs=None):
+ self.assertIn([column], [c["columns"] for c in constraints.values()])
+
+ def alter_gis_model(
+ self,
+ migration_class,
+ model_name,
+ field_name,
+ blank=False,
+ field_class=None,
+ field_class_kwargs=None,
+ ):
args = [model_name, field_name]
if field_class:
- field_class_kwargs = field_class_kwargs or {'srid': 4326, 'blank': blank}
+ field_class_kwargs = field_class_kwargs or {"srid": 4326, "blank": blank}
args.append(field_class(**field_class_kwargs))
operation = migration_class(*args)
old_state = self.current_state.clone()
- operation.state_forwards('gis', self.current_state)
+ operation.state_forwards("gis", self.current_state)
with connection.schema_editor() as editor:
- operation.database_forwards('gis', editor, old_state, self.current_state)
+ operation.database_forwards("gis", editor, old_state, self.current_state)
class OperationTests(OperationTestCase):
-
def setUp(self):
super().setUp()
self.set_up_test_model()
@@ -109,8 +121,10 @@ class OperationTests(OperationTestCase):
"""
Test the AddField operation with a geometry-enabled column.
"""
- self.alter_gis_model(migrations.AddField, 'Neighborhood', 'path', False, fields.LineStringField)
- self.assertColumnExists('gis_neighborhood', 'path')
+ self.alter_gis_model(
+ migrations.AddField, "Neighborhood", "path", False, fields.LineStringField
+ )
+ self.assertColumnExists("gis_neighborhood", "path")
# Test GeometryColumns when available
if HAS_GEOMETRY_COLUMNS:
@@ -118,33 +132,37 @@ class OperationTests(OperationTestCase):
# Test spatial indices when available
if self.has_spatial_indexes:
- self.assertSpatialIndexExists('gis_neighborhood', 'path')
+ self.assertSpatialIndexExists("gis_neighborhood", "path")
@skipUnless(HAS_GEOMETRY_COLUMNS, "Backend doesn't support GeometryColumns.")
def test_geom_col_name(self):
self.assertEqual(
GeometryColumns.geom_col_name(),
- 'column_name' if connection.ops.oracle else 'f_geometry_column',
+ "column_name" if connection.ops.oracle else "f_geometry_column",
)
- @skipUnlessDBFeature('supports_raster')
+ @skipUnlessDBFeature("supports_raster")
def test_add_raster_field(self):
"""
Test the AddField operation with a raster-enabled column.
"""
- self.alter_gis_model(migrations.AddField, 'Neighborhood', 'heatmap', False, fields.RasterField)
- self.assertColumnExists('gis_neighborhood', 'heatmap')
+ self.alter_gis_model(
+ migrations.AddField, "Neighborhood", "heatmap", False, fields.RasterField
+ )
+ self.assertColumnExists("gis_neighborhood", "heatmap")
# Test spatial indices when available
if self.has_spatial_indexes:
- self.assertSpatialIndexExists('gis_neighborhood', 'heatmap', raster=True)
+ self.assertSpatialIndexExists("gis_neighborhood", "heatmap", raster=True)
def test_add_blank_geom_field(self):
"""
Should be able to add a GeometryField with blank=True.
"""
- self.alter_gis_model(migrations.AddField, 'Neighborhood', 'path', True, fields.LineStringField)
- self.assertColumnExists('gis_neighborhood', 'path')
+ self.alter_gis_model(
+ migrations.AddField, "Neighborhood", "path", True, fields.LineStringField
+ )
+ self.assertColumnExists("gis_neighborhood", "path")
# Test GeometryColumns when available
if HAS_GEOMETRY_COLUMNS:
@@ -152,96 +170,108 @@ class OperationTests(OperationTestCase):
# Test spatial indices when available
if self.has_spatial_indexes:
- self.assertSpatialIndexExists('gis_neighborhood', 'path')
+ self.assertSpatialIndexExists("gis_neighborhood", "path")
- @skipUnlessDBFeature('supports_raster')
+ @skipUnlessDBFeature("supports_raster")
def test_add_blank_raster_field(self):
"""
Should be able to add a RasterField with blank=True.
"""
- self.alter_gis_model(migrations.AddField, 'Neighborhood', 'heatmap', True, fields.RasterField)
- self.assertColumnExists('gis_neighborhood', 'heatmap')
+ self.alter_gis_model(
+ migrations.AddField, "Neighborhood", "heatmap", True, fields.RasterField
+ )
+ self.assertColumnExists("gis_neighborhood", "heatmap")
# Test spatial indices when available
if self.has_spatial_indexes:
- self.assertSpatialIndexExists('gis_neighborhood', 'heatmap', raster=True)
+ self.assertSpatialIndexExists("gis_neighborhood", "heatmap", raster=True)
def test_remove_geom_field(self):
"""
Test the RemoveField operation with a geometry-enabled column.
"""
- self.alter_gis_model(migrations.RemoveField, 'Neighborhood', 'geom')
- self.assertColumnNotExists('gis_neighborhood', 'geom')
+ self.alter_gis_model(migrations.RemoveField, "Neighborhood", "geom")
+ self.assertColumnNotExists("gis_neighborhood", "geom")
# Test GeometryColumns when available
if HAS_GEOMETRY_COLUMNS:
self.assertGeometryColumnsCount(0)
- @skipUnlessDBFeature('supports_raster')
+ @skipUnlessDBFeature("supports_raster")
def test_remove_raster_field(self):
"""
Test the RemoveField operation with a raster-enabled column.
"""
- self.alter_gis_model(migrations.RemoveField, 'Neighborhood', 'rast')
- self.assertColumnNotExists('gis_neighborhood', 'rast')
+ self.alter_gis_model(migrations.RemoveField, "Neighborhood", "rast")
+ self.assertColumnNotExists("gis_neighborhood", "rast")
def test_create_model_spatial_index(self):
if not self.has_spatial_indexes:
- self.skipTest('No support for Spatial indexes')
+ self.skipTest("No support for Spatial indexes")
- self.assertSpatialIndexExists('gis_neighborhood', 'geom')
+ self.assertSpatialIndexExists("gis_neighborhood", "geom")
if connection.features.supports_raster:
- self.assertSpatialIndexExists('gis_neighborhood', 'rast', raster=True)
+ self.assertSpatialIndexExists("gis_neighborhood", "rast", raster=True)
- @skipUnlessDBFeature('supports_3d_storage')
+ @skipUnlessDBFeature("supports_3d_storage")
def test_add_3d_field_opclass(self):
if not connection.ops.postgis:
- self.skipTest('PostGIS-specific test.')
+ self.skipTest("PostGIS-specific test.")
self.alter_gis_model(
migrations.AddField,
- 'Neighborhood',
- 'point3d',
+ "Neighborhood",
+ "point3d",
field_class=fields.PointField,
- field_class_kwargs={'dim': 3},
+ field_class_kwargs={"dim": 3},
)
- self.assertColumnExists('gis_neighborhood', 'point3d')
- self.assertSpatialIndexExists('gis_neighborhood', 'point3d')
+ self.assertColumnExists("gis_neighborhood", "point3d")
+ self.assertSpatialIndexExists("gis_neighborhood", "point3d")
with connection.cursor() as cursor:
- index_name = 'gis_neighborhood_point3d_113bc868_id'
+ index_name = "gis_neighborhood_point3d_113bc868_id"
cursor.execute(self.get_opclass_query, [index_name])
self.assertEqual(
cursor.fetchall(),
- [('gist_geometry_ops_nd', index_name)],
+ [("gist_geometry_ops_nd", index_name)],
)
- @skipUnlessDBFeature('can_alter_geometry_field', 'supports_3d_storage')
+ @skipUnlessDBFeature("can_alter_geometry_field", "supports_3d_storage")
def test_alter_geom_field_dim(self):
- Neighborhood = self.current_state.apps.get_model('gis', 'Neighborhood')
+ Neighborhood = self.current_state.apps.get_model("gis", "Neighborhood")
p1 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
- Neighborhood.objects.create(name='TestDim', geom=MultiPolygon(p1, p1))
+ Neighborhood.objects.create(name="TestDim", geom=MultiPolygon(p1, p1))
# Add 3rd dimension.
self.alter_gis_model(
- migrations.AlterField, 'Neighborhood', 'geom', False,
- fields.MultiPolygonField, field_class_kwargs={'srid': 4326, 'dim': 3}
+ migrations.AlterField,
+ "Neighborhood",
+ "geom",
+ False,
+ fields.MultiPolygonField,
+ field_class_kwargs={"srid": 4326, "dim": 3},
)
self.assertTrue(Neighborhood.objects.first().geom.hasz)
# Rewind to 2 dimensions.
self.alter_gis_model(
- migrations.AlterField, 'Neighborhood', 'geom', False,
- fields.MultiPolygonField, field_class_kwargs={'srid': 4326, 'dim': 2}
+ migrations.AlterField,
+ "Neighborhood",
+ "geom",
+ False,
+ fields.MultiPolygonField,
+ field_class_kwargs={"srid": 4326, "dim": 2},
)
self.assertFalse(Neighborhood.objects.first().geom.hasz)
- @skipUnlessDBFeature('supports_column_check_constraints', 'can_introspect_check_constraints')
+ @skipUnlessDBFeature(
+ "supports_column_check_constraints", "can_introspect_check_constraints"
+ )
def test_add_check_constraint(self):
- Neighborhood = self.current_state.apps.get_model('gis', 'Neighborhood')
+ Neighborhood = self.current_state.apps.get_model("gis", "Neighborhood")
poly = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
constraint = models.CheckConstraint(
check=models.Q(geom=poly),
- name='geom_within_constraint',
+ name="geom_within_constraint",
)
Neighborhood._meta.constraints = [constraint]
with connection.schema_editor() as editor:
@@ -251,21 +281,24 @@ class OperationTests(OperationTestCase):
cursor,
Neighborhood._meta.db_table,
)
- self.assertIn('geom_within_constraint', constraints)
+ self.assertIn("geom_within_constraint", constraints)
-@skipIfDBFeature('supports_raster')
+@skipIfDBFeature("supports_raster")
class NoRasterSupportTests(OperationTestCase):
def test_create_raster_model_on_db_without_raster_support(self):
- msg = 'Raster fields require backends with raster support.'
+ msg = "Raster fields require backends with raster support."
with self.assertRaisesMessage(ImproperlyConfigured, msg):
self.set_up_test_model(force_raster_creation=True)
def test_add_raster_field_on_db_without_raster_support(self):
- msg = 'Raster fields require backends with raster support.'
+ msg = "Raster fields require backends with raster support."
with self.assertRaisesMessage(ImproperlyConfigured, msg):
self.set_up_test_model()
self.alter_gis_model(
- migrations.AddField, 'Neighborhood', 'heatmap',
- False, fields.RasterField
+ migrations.AddField,
+ "Neighborhood",
+ "heatmap",
+ False,
+ fields.RasterField,
)
diff --git a/tests/gis_tests/inspectapp/models.py b/tests/gis_tests/inspectapp/models.py
index ca6566844e..da36e8c8b2 100644
--- a/tests/gis_tests/inspectapp/models.py
+++ b/tests/gis_tests/inspectapp/models.py
@@ -21,4 +21,4 @@ class Fields3D(models.Model):
poly = models.PolygonField(dim=3)
class Meta:
- required_db_features = {'supports_3d_storage'}
+ required_db_features = {"supports_3d_storage"}
diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py
index 35337897c0..952124db8c 100644
--- a/tests/gis_tests/inspectapp/tests.py
+++ b/tests/gis_tests/inspectapp/tests.py
@@ -20,94 +20,96 @@ class InspectDbTests(TestCase):
"""
out = StringIO()
call_command(
- 'inspectdb',
- table_name_filter=lambda tn: tn == 'inspectapp_allogrfields',
- stdout=out
+ "inspectdb",
+ table_name_filter=lambda tn: tn == "inspectapp_allogrfields",
+ stdout=out,
)
output = out.getvalue()
if connection.features.supports_geometry_field_introspection:
- self.assertIn('geom = models.PolygonField()', output)
- self.assertIn('point = models.PointField()', output)
+ self.assertIn("geom = models.PolygonField()", output)
+ self.assertIn("point = models.PointField()", output)
else:
- self.assertIn('geom = models.GeometryField(', output)
- self.assertIn('point = models.GeometryField(', output)
+ self.assertIn("geom = models.GeometryField(", output)
+ self.assertIn("point = models.GeometryField(", output)
@skipUnlessDBFeature("supports_3d_storage")
def test_3d_columns(self):
out = StringIO()
call_command(
- 'inspectdb',
- table_name_filter=lambda tn: tn == 'inspectapp_fields3d',
- stdout=out
+ "inspectdb",
+ table_name_filter=lambda tn: tn == "inspectapp_fields3d",
+ stdout=out,
)
output = out.getvalue()
if connection.features.supports_geometry_field_introspection:
- self.assertIn('point = models.PointField(dim=3)', output)
+ self.assertIn("point = models.PointField(dim=3)", output)
if connection.features.supports_geography:
- self.assertIn('pointg = models.PointField(geography=True, dim=3)', output)
+ self.assertIn(
+ "pointg = models.PointField(geography=True, dim=3)", output
+ )
else:
- self.assertIn('pointg = models.PointField(dim=3)', output)
- self.assertIn('line = models.LineStringField(dim=3)', output)
- self.assertIn('poly = models.PolygonField(dim=3)', output)
+ self.assertIn("pointg = models.PointField(dim=3)", output)
+ self.assertIn("line = models.LineStringField(dim=3)", output)
+ self.assertIn("poly = models.PolygonField(dim=3)", output)
else:
- self.assertIn('point = models.GeometryField(', output)
- self.assertIn('pointg = models.GeometryField(', output)
- self.assertIn('line = models.GeometryField(', output)
- self.assertIn('poly = models.GeometryField(', output)
+ self.assertIn("point = models.GeometryField(", output)
+ self.assertIn("pointg = models.GeometryField(", output)
+ self.assertIn("line = models.GeometryField(", output)
+ self.assertIn("poly = models.GeometryField(", output)
@modify_settings(
- INSTALLED_APPS={'append': 'django.contrib.gis'},
+ INSTALLED_APPS={"append": "django.contrib.gis"},
)
class OGRInspectTest(SimpleTestCase):
maxDiff = 1024
def test_poly(self):
- shp_file = os.path.join(TEST_DATA, 'test_poly', 'test_poly.shp')
- model_def = ogrinspect(shp_file, 'MyModel')
+ shp_file = os.path.join(TEST_DATA, "test_poly", "test_poly.shp")
+ model_def = ogrinspect(shp_file, "MyModel")
expected = [
- '# This is an auto-generated Django model module created by ogrinspect.',
- 'from django.contrib.gis.db import models',
- '',
- '',
- 'class MyModel(models.Model):',
- ' float = models.FloatField()',
- ' int = models.BigIntegerField()',
- ' str = models.CharField(max_length=80)',
- ' geom = models.PolygonField()',
+ "# This is an auto-generated Django model module created by ogrinspect.",
+ "from django.contrib.gis.db import models",
+ "",
+ "",
+ "class MyModel(models.Model):",
+ " float = models.FloatField()",
+ " int = models.BigIntegerField()",
+ " str = models.CharField(max_length=80)",
+ " geom = models.PolygonField()",
]
- self.assertEqual(model_def, '\n'.join(expected))
+ self.assertEqual(model_def, "\n".join(expected))
def test_poly_multi(self):
- shp_file = os.path.join(TEST_DATA, 'test_poly', 'test_poly.shp')
- model_def = ogrinspect(shp_file, 'MyModel', multi_geom=True)
- self.assertIn('geom = models.MultiPolygonField()', model_def)
+ shp_file = os.path.join(TEST_DATA, "test_poly", "test_poly.shp")
+ model_def = ogrinspect(shp_file, "MyModel", multi_geom=True)
+ self.assertIn("geom = models.MultiPolygonField()", model_def)
# Same test with a 25D-type geometry field
- shp_file = os.path.join(TEST_DATA, 'gas_lines', 'gas_leitung.shp')
- model_def = ogrinspect(shp_file, 'MyModel', multi_geom=True)
- srid = '-1' if GDAL_VERSION < (2, 3) else '31253'
- self.assertIn('geom = models.MultiLineStringField(srid=%s)' % srid, model_def)
+ shp_file = os.path.join(TEST_DATA, "gas_lines", "gas_leitung.shp")
+ model_def = ogrinspect(shp_file, "MyModel", multi_geom=True)
+ srid = "-1" if GDAL_VERSION < (2, 3) else "31253"
+ self.assertIn("geom = models.MultiLineStringField(srid=%s)" % srid, model_def)
def test_date_field(self):
- shp_file = os.path.join(TEST_DATA, 'cities', 'cities.shp')
- model_def = ogrinspect(shp_file, 'City')
+ shp_file = os.path.join(TEST_DATA, "cities", "cities.shp")
+ model_def = ogrinspect(shp_file, "City")
expected = [
- '# This is an auto-generated Django model module created by ogrinspect.',
- 'from django.contrib.gis.db import models',
- '',
- '',
- 'class City(models.Model):',
- ' name = models.CharField(max_length=80)',
- ' population = models.BigIntegerField()',
- ' density = models.FloatField()',
- ' created = models.DateField()',
- ' geom = models.PointField()',
+ "# This is an auto-generated Django model module created by ogrinspect.",
+ "from django.contrib.gis.db import models",
+ "",
+ "",
+ "class City(models.Model):",
+ " name = models.CharField(max_length=80)",
+ " population = models.BigIntegerField()",
+ " density = models.FloatField()",
+ " created = models.DateField()",
+ " geom = models.PointField()",
]
- self.assertEqual(model_def, '\n'.join(expected))
+ self.assertEqual(model_def, "\n".join(expected))
def test_time_field(self):
# Getting the database identifier used by OGR, if None returned
@@ -119,48 +121,60 @@ class OGRInspectTest(SimpleTestCase):
try:
# Writing shapefiles via GDAL currently does not support writing OGRTime
# fields, so we need to actually use a database
- model_def = ogrinspect(ogr_db, 'Measurement',
- layer_key=AllOGRFields._meta.db_table,
- decimal=['f_decimal'])
+ model_def = ogrinspect(
+ ogr_db,
+ "Measurement",
+ layer_key=AllOGRFields._meta.db_table,
+ decimal=["f_decimal"],
+ )
except GDALException:
self.skipTest("Unable to setup an OGR connection to your database")
- self.assertTrue(model_def.startswith(
- '# This is an auto-generated Django model module created by ogrinspect.\n'
- 'from django.contrib.gis.db import models\n'
- '\n'
- '\n'
- 'class Measurement(models.Model):\n'
- ))
+ self.assertTrue(
+ model_def.startswith(
+ "# This is an auto-generated Django model module created by ogrinspect.\n"
+ "from django.contrib.gis.db import models\n"
+ "\n"
+ "\n"
+ "class Measurement(models.Model):\n"
+ )
+ )
# The ordering of model fields might vary depending on several factors (version of GDAL, etc.)
- if connection.vendor == 'sqlite':
+ if connection.vendor == "sqlite":
# SpatiaLite introspection is somewhat lacking (#29461).
- self.assertIn(' f_decimal = models.CharField(max_length=0)', model_def)
+ self.assertIn(" f_decimal = models.CharField(max_length=0)", model_def)
else:
- self.assertIn(' f_decimal = models.DecimalField(max_digits=0, decimal_places=0)', model_def)
- self.assertIn(' f_int = models.IntegerField()', model_def)
+ self.assertIn(
+ " f_decimal = models.DecimalField(max_digits=0, decimal_places=0)",
+ model_def,
+ )
+ self.assertIn(" f_int = models.IntegerField()", model_def)
if not connection.ops.mariadb:
# Probably a bug between GDAL and MariaDB on time fields.
- self.assertIn(' f_datetime = models.DateTimeField()', model_def)
- self.assertIn(' f_time = models.TimeField()', model_def)
- if connection.vendor == 'sqlite':
- self.assertIn(' f_float = models.CharField(max_length=0)', model_def)
+ self.assertIn(" f_datetime = models.DateTimeField()", model_def)
+ self.assertIn(" f_time = models.TimeField()", model_def)
+ if connection.vendor == "sqlite":
+ self.assertIn(" f_float = models.CharField(max_length=0)", model_def)
else:
- self.assertIn(' f_float = models.FloatField()', model_def)
- max_length = 0 if connection.vendor == 'sqlite' else 10
- self.assertIn(' f_char = models.CharField(max_length=%s)' % max_length, model_def)
- self.assertIn(' f_date = models.DateField()', model_def)
+ self.assertIn(" f_float = models.FloatField()", model_def)
+ max_length = 0 if connection.vendor == "sqlite" else 10
+ self.assertIn(
+ " f_char = models.CharField(max_length=%s)" % max_length, model_def
+ )
+ self.assertIn(" f_date = models.DateField()", model_def)
# Some backends may have srid=-1
- self.assertIsNotNone(re.search(r' geom = models.PolygonField\(([^\)])*\)', model_def))
+ self.assertIsNotNone(
+ re.search(r" geom = models.PolygonField\(([^\)])*\)", model_def)
+ )
def test_management_command(self):
- shp_file = os.path.join(TEST_DATA, 'cities', 'cities.shp')
+ shp_file = os.path.join(TEST_DATA, "cities", "cities.shp")
out = StringIO()
- call_command('ogrinspect', shp_file, 'City', stdout=out)
+ call_command("ogrinspect", shp_file, "City", stdout=out)
output = out.getvalue()
- self.assertIn('class City(models.Model):', output)
+ self.assertIn("class City(models.Model):", output)
def test_mapping_option(self):
expected = (
@@ -174,10 +188,11 @@ class OGRInspectTest(SimpleTestCase):
" 'density': 'Density',\n"
" 'created': 'Created',\n"
" 'geom': 'POINT',\n"
- "}\n")
- shp_file = os.path.join(TEST_DATA, 'cities', 'cities.shp')
+ "}\n"
+ )
+ shp_file = os.path.join(TEST_DATA, "cities", "cities.shp")
out = StringIO()
- call_command('ogrinspect', shp_file, '--mapping', 'City', stdout=out)
+ call_command("ogrinspect", shp_file, "--mapping", "City", stdout=out)
self.assertIn(expected, out.getvalue())
@@ -187,19 +202,23 @@ def get_ogr_db_string():
GDAL will create its own connection to the database, so we re-use the
connection settings from the Django test.
"""
- db = connections.databases['default']
+ db = connections.databases["default"]
# Map from the django backend into the OGR driver name and database identifier
# https://gdal.org/drivers/vector/
#
# TODO: Support Oracle (OCI).
drivers = {
- 'django.contrib.gis.db.backends.postgis': ('PostgreSQL', "PG:dbname='%(db_name)s'", ' '),
- 'django.contrib.gis.db.backends.mysql': ('MySQL', 'MYSQL:"%(db_name)s"', ','),
- 'django.contrib.gis.db.backends.spatialite': ('SQLite', '%(db_name)s', '')
+ "django.contrib.gis.db.backends.postgis": (
+ "PostgreSQL",
+ "PG:dbname='%(db_name)s'",
+ " ",
+ ),
+ "django.contrib.gis.db.backends.mysql": ("MySQL", 'MYSQL:"%(db_name)s"', ","),
+ "django.contrib.gis.db.backends.spatialite": ("SQLite", "%(db_name)s", ""),
}
- db_engine = db['ENGINE']
+ db_engine = db["ENGINE"]
if db_engine not in drivers:
return None
@@ -212,20 +231,21 @@ def get_ogr_db_string():
return None
# SQLite/SpatiaLite in-memory databases
- if db['NAME'] == ":memory:":
+ if db["NAME"] == ":memory:":
return None
# Build the params of the OGR database connection string
- params = [db_str % {'db_name': db['NAME']}]
+ params = [db_str % {"db_name": db["NAME"]}]
def add(key, template):
value = db.get(key, None)
# Don't add the parameter if it is not in django's settings
if value:
params.append(template % value)
- add('HOST', "host='%s'")
- add('PORT', "port='%s'")
- add('USER', "user='%s'")
- add('PASSWORD', "password='%s'")
+
+ add("HOST", "host='%s'")
+ add("PORT", "port='%s'")
+ add("USER", "user='%s'")
+ add("PASSWORD", "password='%s'")
return param_sep.join(params)
diff --git a/tests/gis_tests/layermap/models.py b/tests/gis_tests/layermap/models.py
index b488eedffe..953332539a 100644
--- a/tests/gis_tests/layermap/models.py
+++ b/tests/gis_tests/layermap/models.py
@@ -25,7 +25,7 @@ class CountyFeat(NamedModel):
class City(NamedModel):
- name_txt = models.TextField(default='')
+ name_txt = models.TextField(default="")
name_short = models.CharField(max_length=5)
population = models.IntegerField()
density = models.DecimalField(max_digits=7, decimal_places=1)
@@ -33,7 +33,7 @@ class City(NamedModel):
point = models.PointField()
class Meta:
- app_label = 'layermap'
+ app_label = "layermap"
class Interstate(NamedModel):
@@ -41,7 +41,7 @@ class Interstate(NamedModel):
path = models.LineStringField()
class Meta:
- app_label = 'layermap'
+ app_label = "layermap"
# Same as `City` above, but for testing model inheritance.
@@ -91,37 +91,37 @@ class DoesNotAllowNulls(models.Model):
# Mapping dictionaries for the models above.
co_mapping = {
- 'name': 'Name',
+ "name": "Name",
# ForeignKey's use another mapping dictionary for the _related_ Model (State in this case).
- 'state': {'name': 'State'},
- 'mpoly': 'MULTIPOLYGON', # Will convert POLYGON features into MULTIPOLYGONS.
+ "state": {"name": "State"},
+ "mpoly": "MULTIPOLYGON", # Will convert POLYGON features into MULTIPOLYGONS.
}
cofeat_mapping = {
- 'name': 'Name',
- 'poly': 'POLYGON',
+ "name": "Name",
+ "poly": "POLYGON",
}
city_mapping = {
- 'name': 'Name',
- 'population': 'Population',
- 'density': 'Density',
- 'dt': 'Created',
- 'point': 'POINT',
+ "name": "Name",
+ "population": "Population",
+ "density": "Density",
+ "dt": "Created",
+ "point": "POINT",
}
inter_mapping = {
- 'name': 'Name',
- 'length': 'Length',
- 'path': 'LINESTRING',
+ "name": "Name",
+ "length": "Length",
+ "path": "LINESTRING",
}
has_nulls_mapping = {
- 'geom': 'POLYGON',
- 'uuid': 'uuid',
- 'datetime': 'datetime',
- 'name': 'name',
- 'integer': 'integer',
- 'num': 'num',
- 'boolean': 'boolean',
+ "geom": "POLYGON",
+ "uuid": "uuid",
+ "datetime": "datetime",
+ "name": "name",
+ "integer": "integer",
+ "num": "num",
+ "boolean": "boolean",
}
diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py
index 4e1d0f69ba..a7aafcc60c 100644
--- a/tests/gis_tests/layermap/tests.py
+++ b/tests/gis_tests/layermap/tests.py
@@ -7,47 +7,61 @@ from pathlib import Path
from django.conf import settings
from django.contrib.gis.gdal import DataSource
from django.contrib.gis.utils.layermapping import (
- InvalidDecimal, InvalidString, LayerMapError, LayerMapping,
+ InvalidDecimal,
+ InvalidString,
+ LayerMapError,
+ LayerMapping,
MissingForeignKey,
)
from django.db import connection
from django.test import TestCase, override_settings
from .models import (
- City, County, CountyFeat, DoesNotAllowNulls, HasNulls, ICity1, ICity2,
- Interstate, Invalid, State, city_mapping, co_mapping, cofeat_mapping,
- has_nulls_mapping, inter_mapping,
+ City,
+ County,
+ CountyFeat,
+ DoesNotAllowNulls,
+ HasNulls,
+ ICity1,
+ ICity2,
+ Interstate,
+ Invalid,
+ State,
+ city_mapping,
+ co_mapping,
+ cofeat_mapping,
+ has_nulls_mapping,
+ inter_mapping,
)
-shp_path = Path(__file__).resolve().parent.parent / 'data'
-city_shp = shp_path / 'cities' / 'cities.shp'
-co_shp = shp_path / 'counties' / 'counties.shp'
-inter_shp = shp_path / 'interstates' / 'interstates.shp'
-invalid_shp = shp_path / 'invalid' / 'emptypoints.shp'
-has_nulls_geojson = shp_path / 'has_nulls' / 'has_nulls.geojson'
+shp_path = Path(__file__).resolve().parent.parent / "data"
+city_shp = shp_path / "cities" / "cities.shp"
+co_shp = shp_path / "counties" / "counties.shp"
+inter_shp = shp_path / "interstates" / "interstates.shp"
+invalid_shp = shp_path / "invalid" / "emptypoints.shp"
+has_nulls_geojson = shp_path / "has_nulls" / "has_nulls.geojson"
# Dictionaries to hold what's expected in the county shapefile.
-NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo']
+NAMES = ["Bexar", "Galveston", "Harris", "Honolulu", "Pueblo"]
NUMS = [1, 2, 1, 19, 1] # Number of polygons for each.
-STATES = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado']
+STATES = ["Texas", "Texas", "Texas", "Hawaii", "Colorado"]
class LayerMapTest(TestCase):
-
def test_init(self):
"Testing LayerMapping initialization."
# Model field that does not exist.
bad1 = copy(city_mapping)
- bad1['foobar'] = 'FooField'
+ bad1["foobar"] = "FooField"
# Shapefile field that does not exist.
bad2 = copy(city_mapping)
- bad2['name'] = 'Nombre'
+ bad2["name"] = "Nombre"
# Nonexistent geographic field type.
bad3 = copy(city_mapping)
- bad3['point'] = 'CURVE'
+ bad3["point"] = "CURVE"
# Incrementing through the bad mapping dictionaries and
# ensuring that a LayerMapError is raised.
@@ -57,7 +71,7 @@ class LayerMapTest(TestCase):
# A LookupError should be thrown for bogus encodings.
with self.assertRaises(LookupError):
- LayerMapping(City, city_shp, city_mapping, encoding='foobar')
+ LayerMapping(City, city_shp, city_mapping, encoding="foobar")
def test_simple_layermap(self):
"Test LayerMapping import of a simple point shapefile."
@@ -73,10 +87,10 @@ class LayerMapTest(TestCase):
ds = DataSource(city_shp)
layer = ds[0]
for feat in layer:
- city = City.objects.get(name=feat['Name'].value)
- self.assertEqual(feat['Population'].value, city.population)
- self.assertEqual(Decimal(str(feat['Density'])), city.density)
- self.assertEqual(feat['Created'].value, city.dt)
+ city = City.objects.get(name=feat["Name"].value)
+ self.assertEqual(feat["Population"].value, city.population)
+ self.assertEqual(Decimal(str(feat["Density"])), city.density)
+ self.assertEqual(feat["Created"].value, city.dt)
# Comparing the geometries.
pnt1, pnt2 = feat.geom, city.point
@@ -110,14 +124,14 @@ class LayerMapTest(TestCase):
# Only the first two features of this shapefile are valid.
valid_feats = ds[0][:2]
for feat in valid_feats:
- istate = Interstate.objects.get(name=feat['Name'].value)
+ istate = Interstate.objects.get(name=feat["Name"].value)
if feat.fid == 0:
- self.assertEqual(Decimal(str(feat['Length'])), istate.length)
+ self.assertEqual(Decimal(str(feat["Length"])), istate.length)
elif feat.fid == 1:
# Everything but the first two decimal digits were truncated,
# because the Interstate model's `length` field has decimal_places=2.
- self.assertAlmostEqual(feat.get('Length'), float(istate.length), 2)
+ self.assertAlmostEqual(feat.get("Length"), float(istate.length), 2)
for p1, p2 in zip(feat.geom, istate.path):
self.assertAlmostEqual(p1[0], p2[0], 6)
@@ -145,16 +159,20 @@ class LayerMapTest(TestCase):
# Specifying the source spatial reference system via the `source_srs` keyword.
lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269)
- lm = LayerMapping(County, co_shp, co_mapping, source_srs='NAD83')
+ lm = LayerMapping(County, co_shp, co_mapping, source_srs="NAD83")
# Unique may take tuple or string parameters.
- for arg in ('name', ('name', 'mpoly')):
+ for arg in ("name", ("name", "mpoly")):
lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg)
# Now test for failures
# Testing invalid params for the `unique` keyword.
- for e, arg in ((TypeError, 5.0), (ValueError, 'foobar'), (ValueError, ('name', 'mpolygon'))):
+ for e, arg in (
+ (TypeError, 5.0),
+ (ValueError, "foobar"),
+ (ValueError, ("name", "mpolygon")),
+ ):
with self.assertRaises(e):
LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg)
@@ -166,9 +184,9 @@ class LayerMapTest(TestCase):
# Passing in invalid ForeignKey mapping parameters -- must be a dictionary
# mapping for the model the ForeignKey points to.
bad_fk_map1 = copy(co_mapping)
- bad_fk_map1['state'] = 'name'
+ bad_fk_map1["state"] = "name"
bad_fk_map2 = copy(co_mapping)
- bad_fk_map2['state'] = {'nombre': 'State'}
+ bad_fk_map2["state"] = {"nombre": "State"}
with self.assertRaises(TypeError):
LayerMapping(County, co_shp, bad_fk_map1, transform=False)
with self.assertRaises(LayerMapError):
@@ -177,14 +195,14 @@ class LayerMapTest(TestCase):
# There exist no State models for the ForeignKey mapping to work -- should raise
# a MissingForeignKey exception (this error would be ignored if the `strict`
# keyword is not set).
- lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name')
+ lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique="name")
with self.assertRaises(MissingForeignKey):
lm.save(silent=True, strict=True)
# Now creating the state models so the ForeignKey mapping may work.
- State.objects.bulk_create([
- State(name='Colorado'), State(name='Hawaii'), State(name='Texas')
- ])
+ State.objects.bulk_create(
+ [State(name="Colorado"), State(name="Hawaii"), State(name="Texas")]
+ )
# If a mapping is specified as a collection, all OGR fields that
# are not collections will be converted into them. For example,
@@ -199,7 +217,7 @@ class LayerMapTest(TestCase):
# appended to the geometry collection of the unique model. Thus,
# all of the various islands in Honolulu county will be in in one
# database record with a MULTIPOLYGON type.
- lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name')
+ lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique="name")
lm.save(silent=True, strict=True)
# A reference that doesn't use the unique keyword; a new database record will
@@ -216,15 +234,15 @@ class LayerMapTest(TestCase):
def clear_counties():
County.objects.all().delete()
- State.objects.bulk_create([
- State(name='Colorado'), State(name='Hawaii'), State(name='Texas')
- ])
+ State.objects.bulk_create(
+ [State(name="Colorado"), State(name="Hawaii"), State(name="Texas")]
+ )
# Initializing the LayerMapping object to use in these tests.
- lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name')
+ lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique="name")
# Bad feature id ranges should raise a type error.
- bad_ranges = (5.0, 'foo', co_shp)
+ bad_ranges = (5.0, "foo", co_shp)
for bad in bad_ranges:
with self.assertRaises(TypeError):
lm.save(fid_range=bad)
@@ -239,7 +257,7 @@ class LayerMapTest(TestCase):
# one model is returned because the `unique` keyword was set.
qs = County.objects.all()
self.assertEqual(1, qs.count())
- self.assertEqual('Galveston', qs[0].name)
+ self.assertEqual("Galveston", qs[0].name)
# Features IDs 5 and beyond for Honolulu County, Hawaii, and
# FID 0 is for Pueblo County, Colorado.
@@ -250,13 +268,13 @@ class LayerMapTest(TestCase):
# Only Pueblo & Honolulu counties should be present because of
# the `unique` keyword. Have to set `order_by` on this QuerySet
# or else MySQL will return a different ordering than the other dbs.
- qs = County.objects.order_by('name')
+ qs = County.objects.order_by("name")
self.assertEqual(2, qs.count())
hi, co = tuple(qs)
- hi_idx, co_idx = tuple(map(NAMES.index, ('Honolulu', 'Pueblo')))
- self.assertEqual('Pueblo', co.name)
+ hi_idx, co_idx = tuple(map(NAMES.index, ("Honolulu", "Pueblo")))
+ self.assertEqual("Pueblo", co.name)
self.assertEqual(NUMS[co_idx], len(co.mpoly))
- self.assertEqual('Honolulu', hi.name)
+ self.assertEqual("Honolulu", hi.name)
self.assertEqual(NUMS[hi_idx], len(hi.mpoly))
# Testing the `step` keyword -- should get the same counties
@@ -270,11 +288,11 @@ class LayerMapTest(TestCase):
def test_model_inheritance(self):
"Tests LayerMapping on inherited models. See #12093."
icity_mapping = {
- 'name': 'Name',
- 'population': 'Population',
- 'density': 'Density',
- 'point': 'POINT',
- 'dt': 'Created',
+ "name": "Name",
+ "population": "Population",
+ "density": "Density",
+ "point": "POINT",
+ "dt": "Created",
}
# Parent model has geometry field.
lm1 = LayerMapping(ICity1, city_shp, icity_mapping)
@@ -289,14 +307,13 @@ class LayerMapTest(TestCase):
def test_invalid_layer(self):
"Tests LayerMapping on invalid geometries. See #15378."
- invalid_mapping = {'point': 'POINT'}
- lm = LayerMapping(Invalid, invalid_shp, invalid_mapping,
- source_srs=4326)
+ invalid_mapping = {"point": "POINT"}
+ lm = LayerMapping(Invalid, invalid_shp, invalid_mapping, source_srs=4326)
lm.save(silent=True)
def test_charfield_too_short(self):
mapping = copy(city_mapping)
- mapping['name_short'] = 'Name'
+ mapping["name_short"] = "Name"
lm = LayerMapping(City, city_shp, mapping)
with self.assertRaises(InvalidString):
lm.save(silent=True, strict=True)
@@ -304,15 +321,15 @@ class LayerMapTest(TestCase):
def test_textfield(self):
"String content fits also in a TextField"
mapping = copy(city_mapping)
- mapping['name_txt'] = 'Name'
+ mapping["name_txt"] = "Name"
lm = LayerMapping(City, city_shp, mapping)
lm.save(silent=True, strict=True)
self.assertEqual(City.objects.count(), 3)
- self.assertEqual(City.objects.get(name='Houston').name_txt, "Houston")
+ self.assertEqual(City.objects.get(name="Houston").name_txt, "Houston")
def test_encoded_name(self):
- """ Test a layer containing utf-8-encoded name """
- city_shp = shp_path / 'ch-city' / 'ch-city.shp'
+ """Test a layer containing utf-8-encoded name"""
+ city_shp = shp_path / "ch-city" / "ch-city.shp"
lm = LayerMapping(City, city_shp, city_mapping)
lm.save(silent=True, strict=True)
self.assertEqual(City.objects.count(), 1)
@@ -320,10 +337,12 @@ class LayerMapTest(TestCase):
def test_null_geom_with_unique(self):
"""LayerMapping may be created with a unique and a null geometry."""
- State.objects.bulk_create([State(name='Colorado'), State(name='Hawaii'), State(name='Texas')])
- hw = State.objects.get(name='Hawaii')
- hu = County.objects.create(name='Honolulu', state=hw, mpoly=None)
- lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name')
+ State.objects.bulk_create(
+ [State(name="Colorado"), State(name="Hawaii"), State(name="Texas")]
+ )
+ hw = State.objects.get(name="Hawaii")
+ hu = County.objects.create(name="Honolulu", state=hw, mpoly=None)
+ lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique="name")
lm.save(silent=True, strict=True)
hu.refresh_from_db()
self.assertIsNotNone(hu.mpoly)
@@ -341,9 +360,9 @@ class LayerMapTest(TestCase):
"Test LayerMapping import of GeoJSON with a null string value."
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
- self.assertEqual(HasNulls.objects.filter(name='None').count(), 0)
+ self.assertEqual(HasNulls.objects.filter(name="None").count(), 0)
num_empty = 1 if connection.features.interprets_empty_strings_as_nulls else 0
- self.assertEqual(HasNulls.objects.filter(name='').count(), num_empty)
+ self.assertEqual(HasNulls.objects.filter(name="").count(), num_empty)
self.assertEqual(HasNulls.objects.filter(name__isnull=True).count(), 1)
def test_nullable_boolean_imported(self):
@@ -358,15 +377,24 @@ class LayerMapTest(TestCase):
"""LayerMapping import of GeoJSON with a nullable date/time value."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
- self.assertEqual(HasNulls.objects.filter(datetime__lt=datetime.date(1994, 8, 15)).count(), 1)
- self.assertEqual(HasNulls.objects.filter(datetime='2018-11-29T03:02:52').count(), 1)
+ self.assertEqual(
+ HasNulls.objects.filter(datetime__lt=datetime.date(1994, 8, 15)).count(), 1
+ )
+ self.assertEqual(
+ HasNulls.objects.filter(datetime="2018-11-29T03:02:52").count(), 1
+ )
self.assertEqual(HasNulls.objects.filter(datetime__isnull=True).count(), 1)
def test_uuids_imported(self):
"""LayerMapping import of GeoJSON with UUIDs."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
- self.assertEqual(HasNulls.objects.filter(uuid='1378c26f-cbe6-44b0-929f-eb330d4991f5').count(), 1)
+ self.assertEqual(
+ HasNulls.objects.filter(
+ uuid="1378c26f-cbe6-44b0-929f-eb330d4991f5"
+ ).count(),
+ 1,
+ )
def test_null_number_imported_not_allowed(self):
"""
@@ -385,7 +413,7 @@ class LayerMapTest(TestCase):
class OtherRouter:
def db_for_read(self, model, **hints):
- return 'other'
+ return "other"
def db_for_write(self, model, **hints):
return self.db_for_read(model, **hints)
@@ -402,9 +430,9 @@ class OtherRouter:
@override_settings(DATABASE_ROUTERS=[OtherRouter()])
class LayerMapRouterTest(TestCase):
- databases = {'default', 'other'}
+ databases = {"default", "other"}
- @unittest.skipUnless(len(settings.DATABASES) > 1, 'multiple databases required')
+ @unittest.skipUnless(len(settings.DATABASES) > 1, "multiple databases required")
def test_layermapping_default_db(self):
lm = LayerMapping(City, city_shp, city_mapping)
- self.assertEqual(lm.using, 'other')
+ self.assertEqual(lm.using, "other")
diff --git a/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py b/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py
index 35451b3a1e..227d6b668d 100644
--- a/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py
+++ b/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py
@@ -9,10 +9,12 @@ if connection.features.supports_raster:
# PostGIS 3+ requires postgis_raster extension.
if pg_version[1:] >= (3,):
operations = [
- CreateExtension('postgis_raster'),
+ CreateExtension("postgis_raster"),
]
else:
operations = []
+
else:
+
class Migration(migrations.Migration):
operations = []
diff --git a/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py b/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py
index 58b742c1b2..68b77f1d85 100644
--- a/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py
+++ b/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py
@@ -6,42 +6,67 @@ from django.db.models import deletion
class Migration(migrations.Migration):
dependencies = [
- ('rasterapp', '0001_setup_extensions'),
+ ("rasterapp", "0001_setup_extensions"),
]
operations = [
migrations.CreateModel(
- name='RasterModel',
+ name="RasterModel",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('rast', models.fields.RasterField(
- blank=True,
- null=True,
- srid=4326,
- verbose_name='A Verbose Raster Name',
- )),
- ('rastprojected', models.fields.RasterField(
- null=True,
- srid=3086,
- verbose_name='A Projected Raster Table',
- )),
- ('geom', models.fields.PointField(null=True, srid=4326)),
+ (
+ "id",
+ models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "rast",
+ models.fields.RasterField(
+ blank=True,
+ null=True,
+ srid=4326,
+ verbose_name="A Verbose Raster Name",
+ ),
+ ),
+ (
+ "rastprojected",
+ models.fields.RasterField(
+ null=True,
+ srid=3086,
+ verbose_name="A Projected Raster Table",
+ ),
+ ),
+ ("geom", models.fields.PointField(null=True, srid=4326)),
],
options={
- 'required_db_features': ['supports_raster'],
+ "required_db_features": ["supports_raster"],
},
),
migrations.CreateModel(
- name='RasterRelatedModel',
+ name="RasterRelatedModel",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('rastermodel', models.ForeignKey(
- on_delete=deletion.CASCADE,
- to='rasterapp.rastermodel',
- )),
+ (
+ "id",
+ models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "rastermodel",
+ models.ForeignKey(
+ on_delete=deletion.CASCADE,
+ to="rasterapp.rastermodel",
+ ),
+ ),
],
options={
- 'required_db_features': ['supports_raster'],
+ "required_db_features": ["supports_raster"],
},
),
]
diff --git a/tests/gis_tests/rasterapp/models.py b/tests/gis_tests/rasterapp/models.py
index e7769f19c4..db540bd488 100644
--- a/tests/gis_tests/rasterapp/models.py
+++ b/tests/gis_tests/rasterapp/models.py
@@ -2,12 +2,14 @@ from django.contrib.gis.db import models
class RasterModel(models.Model):
- rast = models.RasterField('A Verbose Raster Name', null=True, srid=4326, spatial_index=True, blank=True)
- rastprojected = models.RasterField('A Projected Raster Table', srid=3086, null=True)
+ rast = models.RasterField(
+ "A Verbose Raster Name", null=True, srid=4326, spatial_index=True, blank=True
+ )
+ rastprojected = models.RasterField("A Projected Raster Table", srid=3086, null=True)
geom = models.PointField(null=True)
class Meta:
- required_db_features = ['supports_raster']
+ required_db_features = ["supports_raster"]
def __str__(self):
return str(self.id)
@@ -17,7 +19,7 @@ class RasterRelatedModel(models.Model):
rastermodel = models.ForeignKey(RasterModel, models.CASCADE)
class Meta:
- required_db_features = ['supports_raster']
+ required_db_features = ["supports_raster"]
def __str__(self):
return str(self.id)
diff --git a/tests/gis_tests/rasterapp/test_rasterfield.py b/tests/gis_tests/rasterapp/test_rasterfield.py
index 6981fcebc4..3f2ce770a9 100644
--- a/tests/gis_tests/rasterapp/test_rasterfield.py
+++ b/tests/gis_tests/rasterapp/test_rasterfield.py
@@ -16,21 +16,23 @@ from ..data.rasters.textrasters import JSON_RASTER
from .models import RasterModel, RasterRelatedModel
-@skipUnlessDBFeature('supports_raster')
+@skipUnlessDBFeature("supports_raster")
class RasterFieldTest(TransactionTestCase):
- available_apps = ['gis_tests.rasterapp']
+ available_apps = ["gis_tests.rasterapp"]
def setUp(self):
- rast = GDALRaster({
- "srid": 4326,
- "origin": [0, 0],
- "scale": [-1, 1],
- "skew": [0, 0],
- "width": 5,
- "height": 5,
- "nr_of_bands": 2,
- "bands": [{"data": range(25)}, {"data": range(25, 50)}],
- })
+ rast = GDALRaster(
+ {
+ "srid": 4326,
+ "origin": [0, 0],
+ "scale": [-1, 1],
+ "skew": [0, 0],
+ "width": 5,
+ "height": 5,
+ "nr_of_bands": 2,
+ "bands": [{"data": range(25)}, {"data": range(25, 50)}],
+ }
+ )
model_instance = RasterModel.objects.create(
rast=rast,
rastprojected=rast,
@@ -53,19 +55,21 @@ class RasterFieldTest(TransactionTestCase):
def test_deserialize_with_pixeltype_flags(self):
no_data = 3
- rast = GDALRaster({
- 'srid': 4326,
- 'origin': [0, 0],
- 'scale': [-1, 1],
- 'skew': [0, 0],
- 'width': 1,
- 'height': 1,
- 'nr_of_bands': 1,
- 'bands': [{'data': [no_data], 'nodata_value': no_data}],
- })
+ rast = GDALRaster(
+ {
+ "srid": 4326,
+ "origin": [0, 0],
+ "scale": [-1, 1],
+ "skew": [0, 0],
+ "width": 1,
+ "height": 1,
+ "nr_of_bands": 1,
+ "bands": [{"data": [no_data], "nodata_value": no_data}],
+ }
+ )
r = RasterModel.objects.create(rast=rast)
RasterModel.objects.filter(pk=r.pk).update(
- rast=Func(F('rast'), function='ST_SetBandIsNoData'),
+ rast=Func(F("rast"), function="ST_SetBandIsNoData"),
)
r.refresh_from_db()
band = r.rast.bands[0].data()
@@ -96,13 +100,33 @@ class RasterFieldTest(TransactionTestCase):
# value is as expected.
self.assertEqual(
[
- 0.0, 1.0, 2.0, 3.0, 4.0,
- 5.0, 6.0, 7.0, 8.0, 9.0,
- 10.0, 11.0, 12.0, 13.0, 14.0,
- 15.0, 16.0, 17.0, 18.0, 19.0,
- 20.0, 21.0, 22.0, 23.0, 24.0
+ 0.0,
+ 1.0,
+ 2.0,
+ 3.0,
+ 4.0,
+ 5.0,
+ 6.0,
+ 7.0,
+ 8.0,
+ 9.0,
+ 10.0,
+ 11.0,
+ 12.0,
+ 13.0,
+ 14.0,
+ 15.0,
+ 16.0,
+ 17.0,
+ 18.0,
+ 19.0,
+ 20.0,
+ 21.0,
+ 22.0,
+ 23.0,
+ 24.0,
],
- band
+ band,
)
def test_implicit_raster_transformation(self):
@@ -113,7 +137,7 @@ class RasterFieldTest(TransactionTestCase):
# Parse json raster
rast = json.loads(JSON_RASTER)
# Update srid to another value
- rast['srid'] = 3086
+ rast["srid"] = 3086
# Save model and get it from db
r = RasterModel.objects.create(rast=rast)
r.refresh_from_db()
@@ -121,8 +145,12 @@ class RasterFieldTest(TransactionTestCase):
self.assertEqual(r.rast.srs.srid, 4326)
# Confirm geotransform is in lat/lon
expected = [
- -87.9298551266551, 9.459646421449934e-06, 0.0, 23.94249275457565,
- 0.0, -9.459646421449934e-06,
+ -87.9298551266551,
+ 9.459646421449934e-06,
+ 0.0,
+ 23.94249275457565,
+ 0.0,
+ -9.459646421449934e-06,
]
for val, exp in zip(r.rast.geotransform, expected):
self.assertAlmostEqual(exp, val)
@@ -132,8 +160,7 @@ class RasterFieldTest(TransactionTestCase):
RasterField should accept a positional verbose name argument.
"""
self.assertEqual(
- RasterModel._meta.get_field('rast').verbose_name,
- 'A Verbose Raster Name'
+ RasterModel._meta.get_field("rast").verbose_name, "A Verbose Raster Name"
)
def test_all_gis_lookups_with_rasters(self):
@@ -143,13 +170,11 @@ class RasterFieldTest(TransactionTestCase):
unprojected coordinate systems. This test just checks that the lookup
can be called, but doesn't check if the result makes logical sense.
"""
- from django.contrib.gis.db.backends.postgis.operations import (
- PostGISOperations,
- )
+ from django.contrib.gis.db.backends.postgis.operations import PostGISOperations
# Create test raster and geom.
rast = GDALRaster(json.loads(JSON_RASTER))
- stx_pnt = GEOSGeometry('POINT (-95.370401017314293 29.704867409475465)', 4326)
+ stx_pnt = GEOSGeometry("POINT (-95.370401017314293 29.704867409475465)", 4326)
stx_pnt.transform(3086)
lookups = [
@@ -157,64 +182,83 @@ class RasterFieldTest(TransactionTestCase):
for name, lookup in BaseSpatialField.get_lookups().items()
if issubclass(lookup, GISLookup)
]
- self.assertNotEqual(lookups, [], 'No lookups found')
+ self.assertNotEqual(lookups, [], "No lookups found")
# Loop through all the GIS lookups.
for name, lookup in lookups:
# Construct lookup filter strings.
combo_keys = [
- field + name for field in [
- 'rast__', 'rast__', 'rastprojected__0__', 'rast__',
- 'rastprojected__', 'geom__', 'rast__',
+ field + name
+ for field in [
+ "rast__",
+ "rast__",
+ "rastprojected__0__",
+ "rast__",
+ "rastprojected__",
+ "geom__",
+ "rast__",
]
]
if issubclass(lookup, DistanceLookupBase):
# Set lookup values for distance lookups.
combo_values = [
- (rast, 50, 'spheroid'),
- (rast, 0, 50, 'spheroid'),
+ (rast, 50, "spheroid"),
+ (rast, 0, 50, "spheroid"),
(rast, 0, D(km=1)),
(stx_pnt, 0, 500),
(stx_pnt, D(km=1000)),
(rast, 500),
(json.loads(JSON_RASTER), 500),
]
- elif name == 'relate':
+ elif name == "relate":
# Set lookup values for the relate lookup.
combo_values = [
- (rast, 'T*T***FF*'),
- (rast, 0, 'T*T***FF*'),
- (rast, 0, 'T*T***FF*'),
- (stx_pnt, 0, 'T*T***FF*'),
- (stx_pnt, 'T*T***FF*'),
- (rast, 'T*T***FF*'),
- (json.loads(JSON_RASTER), 'T*T***FF*'),
+ (rast, "T*T***FF*"),
+ (rast, 0, "T*T***FF*"),
+ (rast, 0, "T*T***FF*"),
+ (stx_pnt, 0, "T*T***FF*"),
+ (stx_pnt, "T*T***FF*"),
+ (rast, "T*T***FF*"),
+ (json.loads(JSON_RASTER), "T*T***FF*"),
]
- elif name == 'isvalid':
+ elif name == "isvalid":
# The isvalid lookup doesn't make sense for rasters.
continue
elif PostGISOperations.gis_operators[name].func:
# Set lookup values for all function based operators.
combo_values = [
- rast, (rast, 0), (rast, 0), (stx_pnt, 0), stx_pnt,
- rast, json.loads(JSON_RASTER)
+ rast,
+ (rast, 0),
+ (rast, 0),
+ (stx_pnt, 0),
+ stx_pnt,
+ rast,
+ json.loads(JSON_RASTER),
]
else:
# Override band lookup for these, as it's not supported.
- combo_keys[2] = 'rastprojected__' + name
+ combo_keys[2] = "rastprojected__" + name
# Set lookup values for all other operators.
- combo_values = [rast, None, rast, stx_pnt, stx_pnt, rast, json.loads(JSON_RASTER)]
+ combo_values = [
+ rast,
+ None,
+ rast,
+ stx_pnt,
+ stx_pnt,
+ rast,
+ json.loads(JSON_RASTER),
+ ]
# Create query filter combinations.
self.assertEqual(
len(combo_keys),
len(combo_values),
- 'Number of lookup names and values should be the same',
+ "Number of lookup names and values should be the same",
)
combos = [x for x in zip(combo_keys, combo_values) if x[1]]
self.assertEqual(
[(n, x) for n, x in enumerate(combos) if x in combos[:n]],
[],
- 'There are repeated test lookups',
+ "There are repeated test lookups",
)
combos = [{k: v} for k, v in combos]
@@ -236,14 +280,16 @@ class RasterFieldTest(TransactionTestCase):
"""
# Create test raster and geom.
rast = GDALRaster(json.loads(JSON_RASTER))
- stx_pnt = GEOSGeometry('POINT (-95.370401017314293 29.704867409475465)', 4326)
+ stx_pnt = GEOSGeometry("POINT (-95.370401017314293 29.704867409475465)", 4326)
stx_pnt.transform(3086)
# Filter raster with different lookup raster formats.
qs = RasterModel.objects.filter(rastprojected__dwithin=(rast, D(km=1)))
self.assertEqual(qs.count(), 1)
- qs = RasterModel.objects.filter(rastprojected__dwithin=(json.loads(JSON_RASTER), D(km=1)))
+ qs = RasterModel.objects.filter(
+ rastprojected__dwithin=(json.loads(JSON_RASTER), D(km=1))
+ )
self.assertEqual(qs.count(), 1)
qs = RasterModel.objects.filter(rastprojected__dwithin=(JSON_RASTER, D(km=1)))
@@ -287,7 +333,10 @@ class RasterFieldTest(TransactionTestCase):
self.assertEqual(qs.count(), 1)
# Filter through conditional statements.
- qs = RasterModel.objects.filter(Q(rast__dwithin=(rast, 40)) & Q(rastprojected__dwithin=(stx_pnt, D(km=10000))))
+ qs = RasterModel.objects.filter(
+ Q(rast__dwithin=(rast, 40))
+ & Q(rastprojected__dwithin=(stx_pnt, D(km=10000)))
+ )
self.assertEqual(qs.count(), 1)
# Filter through different lookup.
@@ -296,35 +345,43 @@ class RasterFieldTest(TransactionTestCase):
def test_lookup_input_tuple_too_long(self):
rast = GDALRaster(json.loads(JSON_RASTER))
- msg = 'Tuple too long for lookup bbcontains.'
+ msg = "Tuple too long for lookup bbcontains."
with self.assertRaisesMessage(ValueError, msg):
RasterModel.objects.filter(rast__bbcontains=(rast, 1, 2))
def test_lookup_input_band_not_allowed(self):
rast = GDALRaster(json.loads(JSON_RASTER))
qs = RasterModel.objects.filter(rast__bbcontains=(rast, 1))
- msg = 'Band indices are not allowed for this operator, it works on bbox only.'
+ msg = "Band indices are not allowed for this operator, it works on bbox only."
with self.assertRaisesMessage(ValueError, msg):
qs.count()
def test_isvalid_lookup_with_raster_error(self):
qs = RasterModel.objects.filter(rast__isvalid=True)
- msg = 'IsValid function requires a GeometryField in position 1, got RasterField.'
+ msg = (
+ "IsValid function requires a GeometryField in position 1, got RasterField."
+ )
with self.assertRaisesMessage(TypeError, msg):
qs.count()
def test_result_of_gis_lookup_with_rasters(self):
# Point is in the interior
- qs = RasterModel.objects.filter(rast__contains=GEOSGeometry('POINT (-0.5 0.5)', 4326))
+ qs = RasterModel.objects.filter(
+ rast__contains=GEOSGeometry("POINT (-0.5 0.5)", 4326)
+ )
self.assertEqual(qs.count(), 1)
# Point is in the exterior
- qs = RasterModel.objects.filter(rast__contains=GEOSGeometry('POINT (0.5 0.5)', 4326))
+ qs = RasterModel.objects.filter(
+ rast__contains=GEOSGeometry("POINT (0.5 0.5)", 4326)
+ )
self.assertEqual(qs.count(), 0)
# A point on the boundary is not contained properly
- qs = RasterModel.objects.filter(rast__contains_properly=GEOSGeometry('POINT (0 0)', 4326))
+ qs = RasterModel.objects.filter(
+ rast__contains_properly=GEOSGeometry("POINT (0 0)", 4326)
+ )
self.assertEqual(qs.count(), 0)
# Raster is located left of the point
- qs = RasterModel.objects.filter(rast__left=GEOSGeometry('POINT (1 0)', 4326))
+ qs = RasterModel.objects.filter(rast__left=GEOSGeometry("POINT (1 0)", 4326))
self.assertEqual(qs.count(), 1)
def test_lookup_with_raster_bbox(self):
@@ -363,7 +420,7 @@ class RasterFieldTest(TransactionTestCase):
with self.assertRaisesMessage(ValueError, msg):
RasterModel.objects.filter(geom__intersects=obj)
# Test with invalid string lookup parameter
- obj = '00000'
+ obj = "00000"
msg = "Couldn't create spatial object from lookup value '%s'." % obj
with self.assertRaisesMessage(ValueError, msg):
RasterModel.objects.filter(geom__intersects=obj)
@@ -378,14 +435,22 @@ class RasterFieldTest(TransactionTestCase):
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 = "Distance function requires a GeometryField in position 1, got RasterField."
+ RasterModel.objects.annotate(
+ distance_from_point=Distance("rastprojected", rast)
+ )
+ 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()
+ RasterModel.objects.annotate(
+ distance_from_point=Distance("rastprojected", point)
+ ).count()
def test_lhs_with_index_rhs_without_index(self):
with CaptureQueriesContext(connection) as queries:
- RasterModel.objects.filter(rast__0__contains=json.loads(JSON_RASTER)).exists()
+ RasterModel.objects.filter(
+ rast__0__contains=json.loads(JSON_RASTER)
+ ).exists()
# It's easier to check the indexes in the generated SQL than to write
# tests that cover all index combinations.
- self.assertRegex(queries[-1]['sql'], r'WHERE ST_Contains\([^)]*, 1, [^)]*, 1\)')
+ self.assertRegex(queries[-1]["sql"], r"WHERE ST_Contains\([^)]*, 1, [^)]*, 1\)")
diff --git a/tests/gis_tests/relatedapp/models.py b/tests/gis_tests/relatedapp/models.py
index 6903617a2a..94a0a28780 100644
--- a/tests/gis_tests/relatedapp/models.py
+++ b/tests/gis_tests/relatedapp/models.py
@@ -36,7 +36,7 @@ class Parcel(SimpleModel):
city = models.ForeignKey(City, models.CASCADE)
center1 = models.PointField()
# Throwing a curveball w/`db_column` here.
- center2 = models.PointField(srid=2276, db_column='mycenter')
+ center2 = models.PointField(srid=2276, db_column="mycenter")
border1 = models.PolygonField()
border2 = models.PolygonField(srid=2276)
@@ -56,7 +56,7 @@ class Article(SimpleModel):
class Book(SimpleModel):
title = models.CharField(max_length=100)
- author = models.ForeignKey(Author, models.SET_NULL, related_name='books', null=True)
+ author = models.ForeignKey(Author, models.SET_NULL, related_name="books", null=True)
class Event(SimpleModel):
diff --git a/tests/gis_tests/relatedapp/tests.py b/tests/gis_tests/relatedapp/tests.py
index b834e13d48..48f9c12b69 100644
--- a/tests/gis_tests/relatedapp/tests.py
+++ b/tests/gis_tests/relatedapp/tests.py
@@ -5,25 +5,23 @@ from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import override_settings
from django.utils import timezone
-from .models import (
- Article, Author, Book, City, DirectoryEntry, Event, Location, Parcel,
-)
+from .models import Article, Author, Book, City, DirectoryEntry, Event, Location, Parcel
class RelatedGeoModelTest(TestCase):
- fixtures = ['initial']
+ fixtures = ["initial"]
def test02_select_related(self):
"Testing `select_related` on geographic models (see #7126)."
- qs1 = City.objects.order_by('id')
- qs2 = City.objects.order_by('id').select_related()
- qs3 = City.objects.order_by('id').select_related('location')
+ qs1 = City.objects.order_by("id")
+ qs2 = City.objects.order_by("id").select_related()
+ qs3 = City.objects.order_by("id").select_related("location")
# Reference data for what's in the fixtures.
cities = (
- ('Aurora', 'TX', -97.516111, 33.058333),
- ('Roswell', 'NM', -104.528056, 33.387222),
- ('Kecksburg', 'PA', -79.460734, 40.18476),
+ ("Aurora", "TX", -97.516111, 33.058333),
+ ("Roswell", "NM", -104.528056, 33.387222),
+ ("Kecksburg", "PA", -79.460734, 40.18476),
)
for qs in (qs1, qs2, qs3):
@@ -38,14 +36,18 @@ class RelatedGeoModelTest(TestCase):
def test_related_extent_aggregate(self):
"Testing the `Extent` aggregate on related geographic models."
# This combines the Extent and Union aggregates into one query
- aggs = City.objects.aggregate(Extent('location__point'))
+ aggs = City.objects.aggregate(Extent("location__point"))
# One for all locations, one that excludes New Mexico (Roswell).
all_extent = (-104.528056, 29.763374, -79.460734, 40.18476)
txpa_extent = (-97.516111, 29.763374, -79.460734, 40.18476)
- e1 = City.objects.aggregate(Extent('location__point'))['location__point__extent']
- e2 = City.objects.exclude(state='NM').aggregate(Extent('location__point'))['location__point__extent']
- e3 = aggs['location__point__extent']
+ e1 = City.objects.aggregate(Extent("location__point"))[
+ "location__point__extent"
+ ]
+ e2 = City.objects.exclude(state="NM").aggregate(Extent("location__point"))[
+ "location__point__extent"
+ ]
+ e3 = aggs["location__point__extent"]
# The tolerance value is to four decimal places because of differences
# between the Oracle and PostGIS spatial backends on the extent calculation.
@@ -59,19 +61,19 @@ class RelatedGeoModelTest(TestCase):
"""
Test annotation with Extent GeoAggregate.
"""
- cities = City.objects.annotate(points_extent=Extent('location__point')).order_by('name')
+ cities = City.objects.annotate(
+ points_extent=Extent("location__point")
+ ).order_by("name")
tol = 4
self.assertAlmostEqual(
- cities[0].points_extent,
- (-97.516111, 33.058333, -97.516111, 33.058333),
- tol
+ cities[0].points_extent, (-97.516111, 33.058333, -97.516111, 33.058333), tol
)
- @skipUnlessDBFeature('supports_union_aggr')
+ @skipUnlessDBFeature("supports_union_aggr")
def test_related_union_aggregate(self):
"Testing the `Union` aggregate on related geographic models."
# This combines the Extent and Union aggregates into one query
- aggs = City.objects.aggregate(Union('location__point'))
+ aggs = City.objects.aggregate(Union("location__point"))
# These are the points that are components of the aggregate geographic
# union that is returned. Each point # corresponds to City PK.
@@ -87,11 +89,11 @@ class RelatedGeoModelTest(TestCase):
ref_u1 = MultiPoint(p1, p2, p4, p5, p3, srid=4326)
ref_u2 = MultiPoint(p2, p3, srid=4326)
- u1 = City.objects.aggregate(Union('location__point'))['location__point__union']
+ u1 = City.objects.aggregate(Union("location__point"))["location__point__union"]
u2 = City.objects.exclude(
- name__in=('Roswell', 'Houston', 'Dallas', 'Fort Worth'),
- ).aggregate(Union('location__point'))['location__point__union']
- u3 = aggs['location__point__union']
+ name__in=("Roswell", "Houston", "Dallas", "Fort Worth"),
+ ).aggregate(Union("location__point"))["location__point__union"]
+ u3 = aggs["location__point__union"]
self.assertEqual(type(u1), MultiPoint)
self.assertEqual(type(u3), MultiPoint)
@@ -111,11 +113,11 @@ class RelatedGeoModelTest(TestCase):
# Constructing a dummy parcel border and getting the City instance for
# assigning the FK.
b1 = GEOSGeometry(
- 'POLYGON((-97.501205 33.052520,-97.501205 33.052576,'
- '-97.501150 33.052576,-97.501150 33.052520,-97.501205 33.052520))',
- srid=4326
+ "POLYGON((-97.501205 33.052520,-97.501205 33.052576,"
+ "-97.501150 33.052576,-97.501150 33.052520,-97.501205 33.052520))",
+ srid=4326,
)
- pcity = City.objects.get(name='Aurora')
+ pcity = City.objects.get(name="Aurora")
# First parcel has incorrect center point that is equal to the City;
# it also has a second border that is different from the first as a
@@ -123,7 +125,9 @@ class RelatedGeoModelTest(TestCase):
c1 = pcity.location.point
c2 = c1.transform(2276, clone=True)
b2 = c2.buffer(100)
- Parcel.objects.create(name='P1', city=pcity, center1=c1, center2=c2, border1=b1, border2=b2)
+ Parcel.objects.create(
+ name="P1", city=pcity, center1=c1, center2=c2, border1=b1, border2=b2
+ )
# Now creating a second Parcel where the borders are the same, just
# in different coordinate systems. The center points are also the
@@ -131,20 +135,26 @@ class RelatedGeoModelTest(TestCase):
# actually correspond to the centroid of the border.
c1 = b1.centroid
c2 = c1.transform(2276, clone=True)
- b2 = b1 if connection.features.supports_transform else b1.transform(2276, clone=True)
- Parcel.objects.create(name='P2', city=pcity, center1=c1, center2=c2, border1=b1, border2=b2)
+ b2 = (
+ b1
+ if connection.features.supports_transform
+ else b1.transform(2276, clone=True)
+ )
+ Parcel.objects.create(
+ name="P2", city=pcity, center1=c1, center2=c2, border1=b1, border2=b2
+ )
# Should return the second Parcel, which has the center within the
# border.
- qs = Parcel.objects.filter(center1__within=F('border1'))
+ qs = Parcel.objects.filter(center1__within=F("border1"))
self.assertEqual(1, len(qs))
- self.assertEqual('P2', qs[0].name)
+ self.assertEqual("P2", qs[0].name)
# This time center2 is in a different coordinate system and needs to be
# wrapped in transformation SQL.
- qs = Parcel.objects.filter(center2__within=F('border1'))
+ qs = Parcel.objects.filter(center2__within=F("border1"))
if connection.features.supports_transform:
- self.assertEqual('P2', qs.get().name)
+ self.assertEqual("P2", qs.get().name)
else:
msg = "This backend doesn't support the Transform function."
with self.assertRaisesMessage(NotSupportedError, msg):
@@ -152,14 +162,14 @@ class RelatedGeoModelTest(TestCase):
# Should return the first Parcel, which has the center point equal
# to the point in the City ForeignKey.
- qs = Parcel.objects.filter(center1=F('city__location__point'))
+ qs = Parcel.objects.filter(center1=F("city__location__point"))
self.assertEqual(1, len(qs))
- self.assertEqual('P1', qs[0].name)
+ self.assertEqual("P1", qs[0].name)
# This time the city column should be wrapped in transformation SQL.
- qs = Parcel.objects.filter(border2__contains=F('city__location__point'))
+ qs = Parcel.objects.filter(border2__contains=F("city__location__point"))
if connection.features.supports_transform:
- self.assertEqual('P1', qs.get().name)
+ self.assertEqual("P1", qs.get().name)
else:
msg = "This backend doesn't support the Transform function."
with self.assertRaisesMessage(NotSupportedError, msg):
@@ -176,21 +186,21 @@ class RelatedGeoModelTest(TestCase):
for m, d, t in zip(gqs, gvqs, gvlqs):
# The values should be Geometry objects and not raw strings returned
# by the spatial database.
- self.assertIsInstance(d['point'], GEOSGeometry)
+ self.assertIsInstance(d["point"], GEOSGeometry)
self.assertIsInstance(t[1], GEOSGeometry)
- self.assertEqual(m.point, d['point'])
+ self.assertEqual(m.point, d["point"])
self.assertEqual(m.point, t[1])
@override_settings(USE_TZ=True)
def test_07b_values(self):
"Testing values() and values_list() with aware datetime. See #21565."
Event.objects.create(name="foo", when=timezone.now())
- list(Event.objects.values_list('when'))
+ list(Event.objects.values_list("when"))
def test08_defer_only(self):
"Testing defer() and only() on Geographic models."
qs = Location.objects.all()
- def_qs = Location.objects.defer('point')
+ def_qs = Location.objects.defer("point")
for loc, def_loc in zip(qs, def_qs):
self.assertEqual(loc.point, def_loc.point)
@@ -202,31 +212,33 @@ class RelatedGeoModelTest(TestCase):
# ID column is selected instead of ID column for the city.
city_ids = (1, 2, 3, 4, 5)
loc_ids = (1, 2, 3, 5, 4)
- ids_qs = City.objects.order_by('id').values('id', 'location__id')
+ ids_qs = City.objects.order_by("id").values("id", "location__id")
for val_dict, c_id, l_id in zip(ids_qs, city_ids, loc_ids):
- self.assertEqual(val_dict['id'], c_id)
- self.assertEqual(val_dict['location__id'], l_id)
+ self.assertEqual(val_dict["id"], c_id)
+ self.assertEqual(val_dict["location__id"], l_id)
def test10_combine(self):
"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)
+ 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)
qs2 = City.objects.filter(location__point__within=buf2)
combined = qs1 | qs2
names = [c.name for c in combined]
self.assertEqual(2, len(names))
- self.assertIn('Aurora', names)
- self.assertIn('Kecksburg', names)
+ self.assertIn("Aurora", names)
+ self.assertIn("Kecksburg", names)
- @skipUnlessDBFeature('allows_group_by_lob')
+ @skipUnlessDBFeature("allows_group_by_lob")
def test12a_count(self):
"Testing `Count` aggregate on geo-fields."
# The City, 'Fort Worth' uses the same location as Dallas.
- dallas = City.objects.get(name='Dallas')
+ dallas = City.objects.get(name="Dallas")
# Count annotation should be 2 for the Dallas location now.
- loc = Location.objects.annotate(num_cities=Count('city')).get(id=dallas.location.id)
+ loc = Location.objects.annotate(num_cities=Count("city")).get(
+ id=dallas.location.id
+ )
self.assertEqual(2, loc.num_cities)
def test12b_count(self):
@@ -234,25 +246,33 @@ class RelatedGeoModelTest(TestCase):
# Should only be one author (Trevor Paglen) returned by this query, and
# the annotation should have 3 for the number of books, see #11087.
# Also testing with a values(), see #11489.
- qs = Author.objects.annotate(num_books=Count('books')).filter(num_books__gt=1)
- vqs = Author.objects.values('name').annotate(num_books=Count('books')).filter(num_books__gt=1)
+ qs = Author.objects.annotate(num_books=Count("books")).filter(num_books__gt=1)
+ vqs = (
+ Author.objects.values("name")
+ .annotate(num_books=Count("books"))
+ .filter(num_books__gt=1)
+ )
self.assertEqual(1, len(qs))
self.assertEqual(3, qs[0].num_books)
self.assertEqual(1, len(vqs))
- self.assertEqual(3, vqs[0]['num_books'])
+ self.assertEqual(3, vqs[0]["num_books"])
- @skipUnlessDBFeature('allows_group_by_lob')
+ @skipUnlessDBFeature("allows_group_by_lob")
def test13c_count(self):
"Testing `Count` aggregate with `.values()`. See #15305."
- qs = Location.objects.filter(id=5).annotate(num_cities=Count('city')).values('id', 'point', 'num_cities')
+ qs = (
+ Location.objects.filter(id=5)
+ .annotate(num_cities=Count("city"))
+ .values("id", "point", "num_cities")
+ )
self.assertEqual(1, len(qs))
- self.assertEqual(2, qs[0]['num_cities'])
- self.assertIsInstance(qs[0]['point'], GEOSGeometry)
+ self.assertEqual(2, qs[0]["num_cities"])
+ self.assertIsInstance(qs[0]["point"], GEOSGeometry)
def test13_select_related_null_fk(self):
"Testing `select_related` on a nullable ForeignKey."
- Book.objects.create(title='Without Author')
- b = Book.objects.select_related('author').get(title='Without Author')
+ Book.objects.create(title="Without Author")
+ b = Book.objects.select_related("author").get(title="Without Author")
# Should be `None`, and not a 'dummy' model.
self.assertIsNone(b.author)
@@ -266,11 +286,13 @@ class RelatedGeoModelTest(TestCase):
# "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
# WHERE "relatedapp_city"."state" = 'TX';
ref_geom = GEOSGeometry(
- 'MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,'
- '-95.363151 29.763374,-96.801611 32.782057)'
+ "MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,"
+ "-95.363151 29.763374,-96.801611 32.782057)"
)
- coll = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
+ coll = City.objects.filter(state="TX").aggregate(Collect("location__point"))[
+ "location__point__collect"
+ ]
# Even though Dallas and Ft. Worth share same point, Collect doesn't
# consolidate -- that's why 4 points in MultiPoint.
self.assertEqual(4, len(coll))
@@ -278,7 +300,7 @@ class RelatedGeoModelTest(TestCase):
def test15_invalid_select_related(self):
"Testing doing select_related on the related name manager of a unique FK. See #13934."
- qs = Article.objects.select_related('author__article')
+ qs = Article.objects.select_related("author__article")
# This triggers TypeError when `get_default_columns` has no `local_only`
# keyword. The TypeError is swallowed if QuerySet is actually
# evaluated as list generation swallows TypeError in CPython.
@@ -286,8 +308,12 @@ class RelatedGeoModelTest(TestCase):
def test16_annotated_date_queryset(self):
"Ensure annotated date querysets work if spatial backend is used. See #14648."
- birth_years = [dt.year for dt in
- list(Author.objects.annotate(num_books=Count('books')).dates('dob', 'year'))]
+ birth_years = [
+ dt.year
+ for dt in list(
+ Author.objects.annotate(num_books=Count("books")).dates("dob", "year")
+ )
+ ]
birth_years.sort()
self.assertEqual([1950, 1974], birth_years)
diff --git a/tests/gis_tests/test_data.py b/tests/gis_tests/test_data.py
index ab6e13f558..0a94907320 100644
--- a/tests/gis_tests/test_data.py
+++ b/tests/gis_tests/test_data.py
@@ -8,7 +8,7 @@ import os
from django.utils.functional import cached_property
# Path where reference test data is located.
-TEST_DATA = os.path.join(os.path.dirname(__file__), 'data')
+TEST_DATA = os.path.join(os.path.dirname(__file__), "data")
def tuplize(seq):
@@ -24,16 +24,14 @@ def strconvert(d):
def get_ds_file(name, ext):
- return os.path.join(TEST_DATA,
- name,
- name + '.%s' % ext
- )
+ return os.path.join(TEST_DATA, name, name + ".%s" % ext)
class TestObj:
"""
Base testing object, turns keyword args into attributes.
"""
+
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
@@ -43,7 +41,8 @@ class TestDS(TestObj):
"""
Object for testing GDAL data sources.
"""
- def __init__(self, name, *, ext='shp', **kwargs):
+
+ def __init__(self, name, *, ext="shp", **kwargs):
# Shapefile is default extension, unless specified otherwise.
self.name = name
self.ds = get_ds_file(name, ext)
@@ -55,6 +54,7 @@ class TestGeom(TestObj):
Testing object used for wrapping reference geometry data
in GEOS/GDAL tests.
"""
+
def __init__(self, *, coords=None, centroid=None, ext_ring_cs=None, **kwargs):
# Converting lists to tuples of certain keyword args
# so coordinate test cases will match (JSON has no
@@ -71,6 +71,7 @@ class TestGeomSet:
"""
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(**strconvert(kw)) for kw in value])
@@ -81,9 +82,10 @@ class TestDataMixin:
Mixin used for GEOS/GDAL test cases that defines a `geometries`
property, which returns and/or loads the reference geometry data.
"""
+
@cached_property
def geometries(self):
# Load up the test geometry data from fixture into global.
- with open(os.path.join(TEST_DATA, 'geometries.json')) as f:
+ with open(os.path.join(TEST_DATA, "geometries.json")) as f:
geometries = json.load(f)
return TestGeomSet(**strconvert(geometries))
diff --git a/tests/gis_tests/test_fields.py b/tests/gis_tests/test_fields.py
index c9e6833767..933514fee7 100644
--- a/tests/gis_tests/test_fields.py
+++ b/tests/gis_tests/test_fields.py
@@ -6,7 +6,6 @@ from django.test import SimpleTestCase
class FieldsTests(SimpleTestCase):
-
def test_area_field_deepcopy(self):
field = AreaField(None)
self.assertEqual(copy.deepcopy(field), field)
@@ -20,21 +19,38 @@ class GeometryFieldTests(SimpleTestCase):
def test_deconstruct_empty(self):
field = GeometryField()
*_, kwargs = field.deconstruct()
- self.assertEqual(kwargs, {'srid': 4326})
+ self.assertEqual(kwargs, {"srid": 4326})
def test_deconstruct_values(self):
field = GeometryField(
srid=4067,
dim=3,
geography=True,
- extent=(50199.4814, 6582464.0358, -50000.0, 761274.6247, 7799839.8902, 50000.0),
+ extent=(
+ 50199.4814,
+ 6582464.0358,
+ -50000.0,
+ 761274.6247,
+ 7799839.8902,
+ 50000.0,
+ ),
tolerance=0.01,
)
*_, kwargs = field.deconstruct()
- self.assertEqual(kwargs, {
- 'srid': 4067,
- 'dim': 3,
- 'geography': True,
- 'extent': (50199.4814, 6582464.0358, -50000.0, 761274.6247, 7799839.8902, 50000.0),
- 'tolerance': 0.01,
- })
+ self.assertEqual(
+ kwargs,
+ {
+ "srid": 4067,
+ "dim": 3,
+ "geography": True,
+ "extent": (
+ 50199.4814,
+ 6582464.0358,
+ -50000.0,
+ 761274.6247,
+ 7799839.8902,
+ 50000.0,
+ ),
+ "tolerance": 0.01,
+ },
+ )
diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py
index a2a3ccae7b..949ad46a41 100644
--- a/tests/gis_tests/test_geoforms.py
+++ b/tests/gis_tests/test_geoforms.py
@@ -9,11 +9,10 @@ from django.utils.html import escape
class GeometryFieldTest(SimpleTestCase):
-
def test_init(self):
"Testing GeometryField initialization with defaults."
fld = forms.GeometryField()
- for bad_default in ('blah', 3, 'FoO', None, 0):
+ for bad_default in ("blah", 3, "FoO", None, 0):
with self.subTest(bad_default=bad_default):
with self.assertRaises(ValidationError):
fld.clean(bad_default)
@@ -23,7 +22,7 @@ class GeometryFieldTest(SimpleTestCase):
# Input that doesn't specify the SRID is assumed to be in the SRID
# of the input field.
fld = forms.GeometryField(srid=4326)
- geom = fld.clean('POINT(5 23)')
+ geom = fld.clean("POINT(5 23)")
self.assertEqual(4326, geom.srid)
# Making the field in a different SRID from that of the geometry, and
# asserting it transforms.
@@ -31,9 +30,13 @@ class GeometryFieldTest(SimpleTestCase):
# Different PROJ versions use different transformations, all are
# correct as having a 1 meter accuracy.
tol = 1
- xform_geom = GEOSGeometry('POINT (951640.547328465 4219369.26171664)', srid=32140)
+ xform_geom = GEOSGeometry(
+ "POINT (951640.547328465 4219369.26171664)", srid=32140
+ )
# The cleaned geometry is transformed to 32140 (the widget map_srid is 3857).
- cleaned_geom = fld.clean('SRID=3857;POINT (-10615777.40976205 3473169.895707852)')
+ cleaned_geom = fld.clean(
+ "SRID=3857;POINT (-10615777.40976205 3473169.895707852)"
+ )
self.assertEqual(cleaned_geom.srid, 32140)
self.assertTrue(xform_geom.equals_exact(cleaned_geom, tol))
@@ -52,22 +55,31 @@ class GeometryFieldTest(SimpleTestCase):
"Testing GeometryField's handling of different geometry types."
# By default, all geometry types are allowed.
fld = forms.GeometryField()
- for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
+ for wkt in (
+ "POINT(5 23)",
+ "MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))",
+ "LINESTRING(0 0, 1 1)",
+ ):
with self.subTest(wkt=wkt):
# to_python() uses the SRID of OpenLayersWidget if the
# converted value doesn't have an SRID.
- self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.clean(wkt))
+ self.assertEqual(
+ GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.clean(wkt)
+ )
- pnt_fld = forms.GeometryField(geom_type='POINT')
- self.assertEqual(GEOSGeometry('POINT(5 23)', srid=pnt_fld.widget.map_srid), pnt_fld.clean('POINT(5 23)'))
+ pnt_fld = forms.GeometryField(geom_type="POINT")
+ self.assertEqual(
+ GEOSGeometry("POINT(5 23)", srid=pnt_fld.widget.map_srid),
+ pnt_fld.clean("POINT(5 23)"),
+ )
# a WKT for any other geom_type will be properly transformed by `to_python`
self.assertEqual(
- GEOSGeometry('LINESTRING(0 0, 1 1)', srid=pnt_fld.widget.map_srid),
- pnt_fld.to_python('LINESTRING(0 0, 1 1)')
+ GEOSGeometry("LINESTRING(0 0, 1 1)", srid=pnt_fld.widget.map_srid),
+ pnt_fld.to_python("LINESTRING(0 0, 1 1)"),
)
# but rejected by `clean`
with self.assertRaises(ValidationError):
- pnt_fld.clean('LINESTRING(0 0, 1 1)')
+ pnt_fld.clean("LINESTRING(0 0, 1 1)")
def test_to_python(self):
"""
@@ -75,14 +87,14 @@ class GeometryFieldTest(SimpleTestCase):
a ValidationError.
"""
good_inputs = [
- 'POINT(5 23)',
- 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))',
- 'LINESTRING(0 0, 1 1)',
+ "POINT(5 23)",
+ "MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))",
+ "LINESTRING(0 0, 1 1)",
]
bad_inputs = [
- 'POINT(5)',
- 'MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))',
- 'BLAH(0 0, 1 1)',
+ "POINT(5)",
+ "MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))",
+ "BLAH(0 0, 1 1)",
'{"type": "FeatureCollection", "features": ['
'{"geometry": {"type": "Point", "coordinates": [508375, 148905]}, "type": "Feature"}]}',
]
@@ -90,7 +102,10 @@ class GeometryFieldTest(SimpleTestCase):
# to_python returns the same GEOSGeometry for a WKT
for geo_input in good_inputs:
with self.subTest(geo_input=geo_input):
- self.assertEqual(GEOSGeometry(geo_input, srid=fld.widget.map_srid), fld.to_python(geo_input))
+ self.assertEqual(
+ GEOSGeometry(geo_input, srid=fld.widget.map_srid),
+ fld.to_python(geo_input),
+ )
# but raises a ValidationError for any other string
for geo_input in bad_inputs:
with self.subTest(geo_input=geo_input):
@@ -100,21 +115,23 @@ class GeometryFieldTest(SimpleTestCase):
def test_to_python_different_map_srid(self):
f = forms.GeometryField(widget=OpenLayersWidget)
json = '{ "type": "Point", "coordinates": [ 5.0, 23.0 ] }'
- self.assertEqual(GEOSGeometry('POINT(5 23)', srid=f.widget.map_srid), f.to_python(json))
+ self.assertEqual(
+ GEOSGeometry("POINT(5 23)", srid=f.widget.map_srid), f.to_python(json)
+ )
def test_field_with_text_widget(self):
class PointForm(forms.Form):
pt = forms.PointField(srid=4326, widget=forms.TextInput)
form = PointForm()
- cleaned_pt = form.fields['pt'].clean('POINT(5 23)')
- self.assertEqual(cleaned_pt, GEOSGeometry('POINT(5 23)', srid=4326))
+ cleaned_pt = form.fields["pt"].clean("POINT(5 23)")
+ self.assertEqual(cleaned_pt, GEOSGeometry("POINT(5 23)", srid=4326))
self.assertEqual(4326, cleaned_pt.srid)
- with self.assertRaisesMessage(ValidationError, 'Invalid geometry value.'):
- form.fields['pt'].clean('POINT(5)')
+ with self.assertRaisesMessage(ValidationError, "Invalid geometry value."):
+ form.fields["pt"].clean("POINT(5)")
- point = GEOSGeometry('SRID=4326;POINT(5 23)')
- form = PointForm(data={'pt': 'POINT(5 23)'}, initial={'pt': point})
+ point = GEOSGeometry("SRID=4326;POINT(5 23)")
+ form = PointForm(data={"pt": "POINT(5 23)"}, initial={"pt": point})
self.assertFalse(form.has_changed())
def test_field_string_value(self):
@@ -122,36 +139,39 @@ class GeometryFieldTest(SimpleTestCase):
Initialization of a geometry field with a valid/empty/invalid string.
Only the invalid string should trigger an error log entry.
"""
+
class PointForm(forms.Form):
pt1 = forms.PointField(srid=4326)
pt2 = forms.PointField(srid=4326)
pt3 = forms.PointField(srid=4326)
- form = PointForm({
- 'pt1': 'SRID=4326;POINT(7.3 44)', # valid
- 'pt2': '', # empty
- 'pt3': 'PNT(0)', # invalid
- })
+ form = PointForm(
+ {
+ "pt1": "SRID=4326;POINT(7.3 44)", # valid
+ "pt2": "", # empty
+ "pt3": "PNT(0)", # invalid
+ }
+ )
- with self.assertLogs('django.contrib.gis', 'ERROR') as logger_calls:
+ with self.assertLogs("django.contrib.gis", "ERROR") as logger_calls:
output = str(form)
# The first point can't use assertInHTML() due to non-deterministic
# ordering of the rendered dictionary.
- pt1_serialized = re.search(r'<textarea [^>]*>({[^<]+})<', output)[1]
- pt1_json = pt1_serialized.replace('&quot;', '"')
- pt1_expected = GEOSGeometry(form.data['pt1']).transform(3857, clone=True)
+ pt1_serialized = re.search(r"<textarea [^>]*>({[^<]+})<", output)[1]
+ pt1_json = pt1_serialized.replace("&quot;", '"')
+ pt1_expected = GEOSGeometry(form.data["pt1"]).transform(3857, clone=True)
self.assertJSONEqual(pt1_json, pt1_expected.json)
self.assertInHTML(
'<textarea id="id_pt2" class="vSerializedField required" cols="150"'
' rows="10" name="pt2"></textarea>',
- output
+ output,
)
self.assertInHTML(
'<textarea id="id_pt3" class="vSerializedField required" cols="150"'
' rows="10" name="pt3"></textarea>',
- output
+ output,
)
# Only the invalid PNT(0) triggers an error log entry.
# Deserialization is called in form clean and in widget rendering.
@@ -159,62 +179,74 @@ class GeometryFieldTest(SimpleTestCase):
self.assertEqual(
logger_calls.records[0].getMessage(),
"Error creating geometry from value 'PNT(0)' (String input "
- "unrecognized as WKT EWKT, and HEXEWKB.)"
+ "unrecognized as WKT EWKT, and HEXEWKB.)",
)
class SpecializedFieldTest(SimpleTestCase):
def setUp(self):
self.geometries = {
- 'point': GEOSGeometry("SRID=4326;POINT(9.052734375 42.451171875)"),
- 'multipoint': GEOSGeometry("SRID=4326;MULTIPOINT("
- "(13.18634033203125 14.504356384277344),"
- "(13.207969665527 14.490966796875),"
- "(13.177070617675 14.454917907714))"),
- 'linestring': GEOSGeometry("SRID=4326;LINESTRING("
- "-8.26171875 -0.52734375,"
- "-7.734375 4.21875,"
- "6.85546875 3.779296875,"
- "5.44921875 -3.515625)"),
- 'multilinestring': GEOSGeometry("SRID=4326;MULTILINESTRING("
- "(-16.435546875 -2.98828125,"
- "-17.2265625 2.98828125,"
- "-0.703125 3.515625,"
- "-1.494140625 -3.33984375),"
- "(-8.0859375 -5.9765625,"
- "8.525390625 -8.7890625,"
- "12.392578125 -0.87890625,"
- "10.01953125 7.646484375))"),
- 'polygon': GEOSGeometry("SRID=4326;POLYGON("
- "(-1.669921875 6.240234375,"
- "-3.8671875 -0.615234375,"
- "5.9765625 -3.955078125,"
- "18.193359375 3.955078125,"
- "9.84375 9.4921875,"
- "-1.669921875 6.240234375))"),
- 'multipolygon': GEOSGeometry("SRID=4326;MULTIPOLYGON("
- "((-17.578125 13.095703125,"
- "-17.2265625 10.8984375,"
- "-13.974609375 10.1953125,"
- "-13.359375 12.744140625,"
- "-15.732421875 13.7109375,"
- "-17.578125 13.095703125)),"
- "((-8.525390625 5.537109375,"
- "-8.876953125 2.548828125,"
- "-5.888671875 1.93359375,"
- "-5.09765625 4.21875,"
- "-6.064453125 6.240234375,"
- "-8.525390625 5.537109375)))"),
- 'geometrycollection': GEOSGeometry("SRID=4326;GEOMETRYCOLLECTION("
- "POINT(5.625 -0.263671875),"
- "POINT(6.767578125 -3.603515625),"
- "POINT(8.525390625 0.087890625),"
- "POINT(8.0859375 -2.13134765625),"
- "LINESTRING("
- "6.273193359375 -1.175537109375,"
- "5.77880859375 -1.812744140625,"
- "7.27294921875 -2.230224609375,"
- "7.657470703125 -1.25244140625))"),
+ "point": GEOSGeometry("SRID=4326;POINT(9.052734375 42.451171875)"),
+ "multipoint": GEOSGeometry(
+ "SRID=4326;MULTIPOINT("
+ "(13.18634033203125 14.504356384277344),"
+ "(13.207969665527 14.490966796875),"
+ "(13.177070617675 14.454917907714))"
+ ),
+ "linestring": GEOSGeometry(
+ "SRID=4326;LINESTRING("
+ "-8.26171875 -0.52734375,"
+ "-7.734375 4.21875,"
+ "6.85546875 3.779296875,"
+ "5.44921875 -3.515625)"
+ ),
+ "multilinestring": GEOSGeometry(
+ "SRID=4326;MULTILINESTRING("
+ "(-16.435546875 -2.98828125,"
+ "-17.2265625 2.98828125,"
+ "-0.703125 3.515625,"
+ "-1.494140625 -3.33984375),"
+ "(-8.0859375 -5.9765625,"
+ "8.525390625 -8.7890625,"
+ "12.392578125 -0.87890625,"
+ "10.01953125 7.646484375))"
+ ),
+ "polygon": GEOSGeometry(
+ "SRID=4326;POLYGON("
+ "(-1.669921875 6.240234375,"
+ "-3.8671875 -0.615234375,"
+ "5.9765625 -3.955078125,"
+ "18.193359375 3.955078125,"
+ "9.84375 9.4921875,"
+ "-1.669921875 6.240234375))"
+ ),
+ "multipolygon": GEOSGeometry(
+ "SRID=4326;MULTIPOLYGON("
+ "((-17.578125 13.095703125,"
+ "-17.2265625 10.8984375,"
+ "-13.974609375 10.1953125,"
+ "-13.359375 12.744140625,"
+ "-15.732421875 13.7109375,"
+ "-17.578125 13.095703125)),"
+ "((-8.525390625 5.537109375,"
+ "-8.876953125 2.548828125,"
+ "-5.888671875 1.93359375,"
+ "-5.09765625 4.21875,"
+ "-6.064453125 6.240234375,"
+ "-8.525390625 5.537109375)))"
+ ),
+ "geometrycollection": GEOSGeometry(
+ "SRID=4326;GEOMETRYCOLLECTION("
+ "POINT(5.625 -0.263671875),"
+ "POINT(6.767578125 -3.603515625),"
+ "POINT(8.525390625 0.087890625),"
+ "POINT(8.0859375 -2.13134765625),"
+ "LINESTRING("
+ "6.273193359375 -1.175537109375,"
+ "5.77880859375 -1.812744140625,"
+ "7.27294921875 -2.230224609375,"
+ "7.657470703125 -1.25244140625))"
+ ),
}
def assertMapWidget(self, form_instance):
@@ -224,15 +256,15 @@ class SpecializedFieldTest(SimpleTestCase):
"""
self.assertTrue(form_instance.is_valid())
rendered = form_instance.as_p()
- self.assertIn('new MapWidget(options);', rendered)
- self.assertIn('map_srid: 3857,', rendered)
- self.assertIn('gis/js/OLMapWidget.js', str(form_instance.media))
+ self.assertIn("new MapWidget(options);", rendered)
+ self.assertIn("map_srid: 3857,", rendered)
+ self.assertIn("gis/js/OLMapWidget.js", str(form_instance.media))
def assertTextarea(self, geom, rendered):
"""Makes sure the wkt and a textarea are in the content"""
- self.assertIn('<textarea ', rendered)
- self.assertIn('required', rendered)
+ self.assertIn("<textarea ", rendered)
+ self.assertIn("required", rendered)
ogr = geom.ogr
ogr.transform(3857)
self.assertIn(escape(ogr.json), rendered)
@@ -243,109 +275,121 @@ class SpecializedFieldTest(SimpleTestCase):
class PointForm(forms.Form):
p = forms.PointField()
- geom = self.geometries['point']
- form = PointForm(data={'p': geom})
+ geom = self.geometries["point"]
+ form = PointForm(data={"p": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(PointForm().is_valid())
- invalid = PointForm(data={'p': 'some invalid geom'})
+ invalid = PointForm(data={"p": "some invalid geom"})
self.assertFalse(invalid.is_valid())
- self.assertIn('Invalid geometry value', str(invalid.errors))
+ self.assertIn("Invalid geometry value", str(invalid.errors))
- for invalid in [geo for key, geo in self.geometries.items() if key != 'point']:
- self.assertFalse(PointForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [geo for key, geo in self.geometries.items() if key != "point"]:
+ self.assertFalse(PointForm(data={"p": invalid.wkt}).is_valid())
def test_multipointfield(self):
class PointForm(forms.Form):
p = forms.MultiPointField()
- geom = self.geometries['multipoint']
- form = PointForm(data={'p': geom})
+ geom = self.geometries["multipoint"]
+ form = PointForm(data={"p": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(PointForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'multipoint']:
- self.assertFalse(PointForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "multipoint"
+ ]:
+ self.assertFalse(PointForm(data={"p": invalid.wkt}).is_valid())
def test_linestringfield(self):
class LineStringForm(forms.Form):
f = forms.LineStringField()
- geom = self.geometries['linestring']
- form = LineStringForm(data={'f': geom})
+ geom = self.geometries["linestring"]
+ form = LineStringForm(data={"f": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(LineStringForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'linestring']:
- self.assertFalse(LineStringForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "linestring"
+ ]:
+ self.assertFalse(LineStringForm(data={"p": invalid.wkt}).is_valid())
def test_multilinestringfield(self):
class LineStringForm(forms.Form):
f = forms.MultiLineStringField()
- geom = self.geometries['multilinestring']
- form = LineStringForm(data={'f': geom})
+ geom = self.geometries["multilinestring"]
+ form = LineStringForm(data={"f": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(LineStringForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'multilinestring']:
- self.assertFalse(LineStringForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "multilinestring"
+ ]:
+ self.assertFalse(LineStringForm(data={"p": invalid.wkt}).is_valid())
def test_polygonfield(self):
class PolygonForm(forms.Form):
p = forms.PolygonField()
- geom = self.geometries['polygon']
- form = PolygonForm(data={'p': geom})
+ geom = self.geometries["polygon"]
+ form = PolygonForm(data={"p": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(PolygonForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'polygon']:
- self.assertFalse(PolygonForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "polygon"
+ ]:
+ self.assertFalse(PolygonForm(data={"p": invalid.wkt}).is_valid())
def test_multipolygonfield(self):
class PolygonForm(forms.Form):
p = forms.MultiPolygonField()
- geom = self.geometries['multipolygon']
- form = PolygonForm(data={'p': geom})
+ geom = self.geometries["multipolygon"]
+ form = PolygonForm(data={"p": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(PolygonForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'multipolygon']:
- self.assertFalse(PolygonForm(data={'p': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "multipolygon"
+ ]:
+ self.assertFalse(PolygonForm(data={"p": invalid.wkt}).is_valid())
def test_geometrycollectionfield(self):
class GeometryForm(forms.Form):
g = forms.GeometryCollectionField()
- geom = self.geometries['geometrycollection']
- form = GeometryForm(data={'g': geom})
+ geom = self.geometries["geometrycollection"]
+ form = GeometryForm(data={"g": geom})
self.assertTextarea(geom, form.as_p())
self.assertMapWidget(form)
self.assertFalse(GeometryForm().is_valid())
- for invalid in [geo for key, geo in self.geometries.items() if key != 'geometrycollection']:
- self.assertFalse(GeometryForm(data={'g': invalid.wkt}).is_valid())
+ for invalid in [
+ geo for key, geo in self.geometries.items() if key != "geometrycollection"
+ ]:
+ self.assertFalse(GeometryForm(data={"g": invalid.wkt}).is_valid())
class OSMWidgetTest(SimpleTestCase):
def setUp(self):
self.geometries = {
- 'point': GEOSGeometry("SRID=4326;POINT(9.052734375 42.451171875)"),
+ "point": GEOSGeometry("SRID=4326;POINT(9.052734375 42.451171875)"),
}
def test_osm_widget(self):
class PointForm(forms.Form):
p = forms.PointField(widget=forms.OSMWidget)
- geom = self.geometries['point']
- form = PointForm(data={'p': geom})
+ geom = self.geometries["point"]
+ form = PointForm(data={"p": geom})
rendered = form.as_p()
self.assertIn("ol.source.OSM()", rendered)
@@ -358,11 +402,13 @@ class OSMWidgetTest(SimpleTestCase):
class PointForm(forms.Form):
p = forms.PointField(
- widget=forms.OSMWidget(attrs={
- 'default_lon': 20,
- 'default_lat': 30,
- 'default_zoom': 17,
- }),
+ widget=forms.OSMWidget(
+ attrs={
+ "default_lon": 20,
+ "default_lat": 30,
+ "default_zoom": 17,
+ }
+ ),
)
form = PointForm()
@@ -374,48 +420,49 @@ class OSMWidgetTest(SimpleTestCase):
class GeometryWidgetTests(SimpleTestCase):
-
def test_get_context_attrs(self):
# The Widget.get_context() attrs argument overrides self.attrs.
- widget = BaseGeometryWidget(attrs={'geom_type': 'POINT'})
- context = widget.get_context('point', None, attrs={'geom_type': 'POINT2'})
- self.assertEqual(context['geom_type'], 'POINT2')
+ widget = BaseGeometryWidget(attrs={"geom_type": "POINT"})
+ context = widget.get_context("point", None, attrs={"geom_type": "POINT2"})
+ self.assertEqual(context["geom_type"], "POINT2")
# Widget.get_context() returns expected name for geom_type.
- widget = BaseGeometryWidget(attrs={'geom_type': 'POLYGON'})
- context = widget.get_context('polygon', None, None)
- self.assertEqual(context['geom_type'], 'Polygon')
+ widget = BaseGeometryWidget(attrs={"geom_type": "POLYGON"})
+ context = widget.get_context("polygon", None, None)
+ self.assertEqual(context["geom_type"], "Polygon")
# Widget.get_context() returns 'Geometry' instead of 'Unknown'.
- widget = BaseGeometryWidget(attrs={'geom_type': 'GEOMETRY'})
- context = widget.get_context('geometry', None, None)
- self.assertEqual(context['geom_type'], 'Geometry')
+ widget = BaseGeometryWidget(attrs={"geom_type": "GEOMETRY"})
+ context = widget.get_context("geometry", None, None)
+ self.assertEqual(context["geom_type"], "Geometry")
def test_subwidgets(self):
widget = forms.BaseGeometryWidget()
self.assertEqual(
- list(widget.subwidgets('name', 'value')),
- [{
- 'is_hidden': False,
- 'attrs': {
- 'map_srid': 4326,
- 'map_width': 600,
- 'geom_type': 'GEOMETRY',
- 'map_height': 400,
- 'display_raw': False,
- },
- 'name': 'name',
- 'template_name': '',
- 'value': 'value',
- 'required': False,
- }]
+ list(widget.subwidgets("name", "value")),
+ [
+ {
+ "is_hidden": False,
+ "attrs": {
+ "map_srid": 4326,
+ "map_width": 600,
+ "geom_type": "GEOMETRY",
+ "map_height": 400,
+ "display_raw": False,
+ },
+ "name": "name",
+ "template_name": "",
+ "value": "value",
+ "required": False,
+ }
+ ],
)
def test_custom_serialization_widget(self):
class CustomGeometryWidget(forms.BaseGeometryWidget):
- template_name = 'gis/openlayers.html'
+ template_name = "gis/openlayers.html"
deserialize_called = 0
def serialize(self, value):
- return value.json if value else ''
+ return value.json if value else ""
def deserialize(self, value):
self.deserialize_called += 1
@@ -425,15 +472,15 @@ class GeometryWidgetTests(SimpleTestCase):
p = forms.PointField(widget=CustomGeometryWidget)
point = GEOSGeometry("SRID=4326;POINT(9.052734375 42.451171875)")
- form = PointForm(data={'p': point})
+ form = PointForm(data={"p": point})
self.assertIn(escape(point.json), form.as_p())
CustomGeometryWidget.called = 0
- widget = form.fields['p'].widget
+ widget = form.fields["p"].widget
# Force deserialize use due to a string value
- self.assertIn(escape(point.json), widget.render('p', point.json))
+ self.assertIn(escape(point.json), widget.render("p", point.json))
self.assertEqual(widget.deserialize_called, 1)
- form = PointForm(data={'p': point.json})
+ form = PointForm(data={"p": point.json})
self.assertTrue(form.is_valid())
- self.assertEqual(form.cleaned_data['p'].srid, 4326)
+ self.assertEqual(form.cleaned_data["p"].srid, 4326)
diff --git a/tests/gis_tests/test_geoip2.py b/tests/gis_tests/test_geoip2.py
index 91bba2e8ff..163ba4887d 100644
--- a/tests/gis_tests/test_geoip2.py
+++ b/tests/gis_tests/test_geoip2.py
@@ -17,11 +17,11 @@ if HAS_GEOIP2:
# 'GeoLite2-City.mmdb'.
@skipUnless(
HAS_GEOIP2 and getattr(settings, "GEOIP_PATH", None),
- "GeoIP is required along with the GEOIP_PATH setting."
+ "GeoIP is required along with the GEOIP_PATH setting.",
)
class GeoIPTest(SimpleTestCase):
- addr = '129.237.192.1'
- fqdn = 'ku.edu'
+ addr = "129.237.192.1"
+ fqdn = "ku.edu"
def test01_init(self):
"GeoIP initialization."
@@ -40,15 +40,15 @@ class GeoIPTest(SimpleTestCase):
self.assertTrue(g._city)
# Only passing in the location of one database.
- city = os.path.join(path, 'GeoLite2-City.mmdb')
- cntry = os.path.join(path, 'GeoLite2-Country.mmdb')
- g4 = GeoIP2(city, country='')
+ city = os.path.join(path, "GeoLite2-City.mmdb")
+ cntry = os.path.join(path, "GeoLite2-Country.mmdb")
+ g4 = GeoIP2(city, country="")
self.assertIsNone(g4._country)
- g5 = GeoIP2(cntry, city='')
+ g5 = GeoIP2(cntry, city="")
self.assertIsNone(g5._city)
# Improper parameters.
- bad_params = (23, 'foo', 15.23)
+ bad_params = (23, "foo", 15.23)
for bad in bad_params:
with self.assertRaises(GeoIP2Exception):
GeoIP2(cache=bad)
@@ -60,19 +60,19 @@ class GeoIPTest(SimpleTestCase):
GeoIP2(bad, 0)
def test_no_database_file(self):
- invalid_path = os.path.join(os.path.dirname(__file__), 'data')
- msg = 'Could not load a database from %s.' % invalid_path
+ invalid_path = os.path.join(os.path.dirname(__file__), "data")
+ msg = "Could not load a database from %s." % invalid_path
with self.assertRaisesMessage(GeoIP2Exception, msg):
GeoIP2(invalid_path)
def test02_bad_query(self):
"GeoIP query parameter checking."
- cntry_g = GeoIP2(city='<foo>')
+ cntry_g = GeoIP2(city="<foo>")
# No city database available, these calls should fail.
with self.assertRaises(GeoIP2Exception):
- cntry_g.city('tmc.edu')
+ cntry_g.city("tmc.edu")
with self.assertRaises(GeoIP2Exception):
- cntry_g.coords('tmc.edu')
+ cntry_g.coords("tmc.edu")
# Non-string query should raise TypeError
with self.assertRaises(TypeError):
@@ -80,92 +80,105 @@ class GeoIPTest(SimpleTestCase):
with self.assertRaises(TypeError):
cntry_g.country_name(GeoIP2)
- @mock.patch('socket.gethostbyname')
+ @mock.patch("socket.gethostbyname")
def test03_country(self, gethostbyname):
"GeoIP country querying methods."
- gethostbyname.return_value = '128.249.1.1'
- g = GeoIP2(city='<foo>')
+ gethostbyname.return_value = "128.249.1.1"
+ g = GeoIP2(city="<foo>")
for query in (self.fqdn, self.addr):
self.assertEqual(
- 'US',
+ "US",
g.country_code(query),
- 'Failed for func country_code and query %s' % query
+ "Failed for func country_code and query %s" % query,
)
self.assertEqual(
- 'United States',
+ "United States",
g.country_name(query),
- 'Failed for func country_name and query %s' % query
+ "Failed for func country_name and query %s" % query,
)
self.assertEqual(
- {'country_code': 'US', 'country_name': 'United States'},
- g.country(query)
+ {"country_code": "US", "country_name": "United States"},
+ g.country(query),
)
- @mock.patch('socket.gethostbyname')
+ @mock.patch("socket.gethostbyname")
def test04_city(self, gethostbyname):
"GeoIP city querying methods."
- gethostbyname.return_value = '129.237.192.1'
- g = GeoIP2(country='<foo>')
+ gethostbyname.return_value = "129.237.192.1"
+ g = GeoIP2(country="<foo>")
for query in (self.fqdn, self.addr):
# Country queries should still work.
self.assertEqual(
- 'US',
+ "US",
g.country_code(query),
- 'Failed for func country_code and query %s' % query
+ "Failed for func country_code and query %s" % query,
)
self.assertEqual(
- 'United States',
+ "United States",
g.country_name(query),
- 'Failed for func country_name and query %s' % query
+ "Failed for func country_name and query %s" % query,
)
self.assertEqual(
- {'country_code': 'US', 'country_name': 'United States'},
- g.country(query)
+ {"country_code": "US", "country_name": "United States"},
+ g.country(query),
)
# City information dictionary.
d = g.city(query)
- self.assertEqual('NA', d['continent_code'])
- self.assertEqual('North America', d['continent_name'])
- self.assertEqual('US', d['country_code'])
- self.assertEqual('Lawrence', d['city'])
- self.assertEqual('KS', d['region'])
- self.assertEqual('America/Chicago', d['time_zone'])
- self.assertFalse(d['is_in_european_union'])
+ self.assertEqual("NA", d["continent_code"])
+ self.assertEqual("North America", d["continent_name"])
+ self.assertEqual("US", d["country_code"])
+ self.assertEqual("Lawrence", d["city"])
+ self.assertEqual("KS", d["region"])
+ self.assertEqual("America/Chicago", d["time_zone"])
+ self.assertFalse(d["is_in_european_union"])
geom = g.geos(query)
self.assertIsInstance(geom, GEOSGeometry)
- for e1, e2 in (geom.tuple, g.coords(query), g.lon_lat(query), g.lat_lon(query)):
+ for e1, e2 in (
+ geom.tuple,
+ g.coords(query),
+ g.lon_lat(query),
+ g.lat_lon(query),
+ ):
self.assertIsInstance(e1, float)
self.assertIsInstance(e2, float)
def test06_ipv6_query(self):
"GeoIP can lookup IPv6 addresses."
g = GeoIP2()
- d = g.city('2002:81ed:c9a5::81ed:c9a5') # IPv6 address for www.nhm.ku.edu
- self.assertEqual('US', d['country_code'])
- self.assertEqual('Lawrence', d['city'])
- self.assertEqual('KS', d['region'])
+ d = g.city("2002:81ed:c9a5::81ed:c9a5") # IPv6 address for www.nhm.ku.edu
+ self.assertEqual("US", d["country_code"])
+ self.assertEqual("Lawrence", d["city"])
+ self.assertEqual("KS", d["region"])
def test_repr(self):
path = settings.GEOIP_PATH
g = GeoIP2(path=path)
meta = g._reader.metadata()
- version = '%s.%s' % (meta.binary_format_major_version, meta.binary_format_minor_version)
+ version = "%s.%s" % (
+ meta.binary_format_major_version,
+ meta.binary_format_minor_version,
+ )
country_path = g._country_file
city_path = g._city_file
- expected = '<GeoIP2 [v%(version)s] _country_file="%(country)s", _city_file="%(city)s">' % {
- 'version': version,
- 'country': country_path,
- 'city': city_path,
- }
+ expected = (
+ '<GeoIP2 [v%(version)s] _country_file="%(country)s", _city_file="%(city)s">'
+ % {
+ "version": version,
+ "country": country_path,
+ "city": city_path,
+ }
+ )
self.assertEqual(repr(g), expected)
- @mock.patch('socket.gethostbyname', return_value='expected')
+ @mock.patch("socket.gethostbyname", return_value="expected")
def test_check_query(self, gethostbyname):
g = GeoIP2()
- self.assertEqual(g._check_query('127.0.0.1'), '127.0.0.1')
- self.assertEqual(g._check_query('2002:81ed:c9a5::81ed:c9a5'), '2002:81ed:c9a5::81ed:c9a5')
- self.assertEqual(g._check_query('invalid-ip-address'), 'expected')
+ self.assertEqual(g._check_query("127.0.0.1"), "127.0.0.1")
+ self.assertEqual(
+ g._check_query("2002:81ed:c9a5::81ed:c9a5"), "2002:81ed:c9a5::81ed:c9a5"
+ )
+ self.assertEqual(g._check_query("invalid-ip-address"), "expected")
diff --git a/tests/gis_tests/test_gis_tests_utils.py b/tests/gis_tests/test_gis_tests_utils.py
index 96eea8a9c2..31b2210805 100644
--- a/tests/gis_tests/test_gis_tests_utils.py
+++ b/tests/gis_tests/test_gis_tests_utils.py
@@ -11,28 +11,29 @@ def test_mutation(raises=True):
output_field = models.IntegerField()
def __init__(self):
- self.attribute = 'initial'
- super().__init__('initial', ['initial'])
+ self.attribute = "initial"
+ super().__init__("initial", ["initial"])
def as_sql(self, *args, **kwargs):
mutation_func(self)
- return '', ()
+ return "", ()
if raises:
- msg = 'TestFunc Func was mutated during compilation.'
+ msg = "TestFunc Func was mutated during compilation."
with test_case_instance.assertRaisesMessage(AssertionError, msg):
- getattr(TestFunc(), 'as_' + connection.vendor)(None, None)
+ getattr(TestFunc(), "as_" + connection.vendor)(None, None)
else:
- getattr(TestFunc(), 'as_' + connection.vendor)(None, None)
+ getattr(TestFunc(), "as_" + connection.vendor)(None, None)
return test
+
return wrapper
class FuncTestMixinTests(FuncTestMixin, SimpleTestCase):
@test_mutation()
def test_mutated_attribute(func):
- func.attribute = 'mutated'
+ func.attribute = "mutated"
@test_mutation()
def test_mutated_expressions(func):
@@ -40,11 +41,11 @@ class FuncTestMixinTests(FuncTestMixin, SimpleTestCase):
@test_mutation()
def test_mutated_expression(func):
- func.source_expressions[0].name = 'mutated'
+ func.source_expressions[0].name = "mutated"
@test_mutation()
def test_mutated_expression_deep(func):
- func.source_expressions[1].value[0] = 'mutated'
+ func.source_expressions[1].value[0] = "mutated"
@test_mutation(raises=False)
def test_not_mutated(func):
diff --git a/tests/gis_tests/test_measure.py b/tests/gis_tests/test_measure.py
index bc2249a816..12c7924b11 100644
--- a/tests/gis_tests/test_measure.py
+++ b/tests/gis_tests/test_measure.py
@@ -46,7 +46,7 @@ class DistanceTest(unittest.TestCase):
def test_access_invalid(self):
"Testing access in invalid units"
d = D(m=100)
- self.assertFalse(hasattr(d, 'banana'))
+ self.assertFalse(hasattr(d, "banana"))
def test_addition(self):
"Test addition & subtraction"
@@ -109,13 +109,13 @@ class DistanceTest(unittest.TestCase):
d2 = D(km=1)
d3 = d1 + d2
- self.assertEqual(d3._default_unit, 'm')
+ self.assertEqual(d3._default_unit, "m")
d4 = d2 + d1
- self.assertEqual(d4._default_unit, 'km')
+ self.assertEqual(d4._default_unit, "km")
d5 = d1 * 2
- self.assertEqual(d5._default_unit, 'm')
+ self.assertEqual(d5._default_unit, "m")
d6 = d1 / 2
- self.assertEqual(d6._default_unit, 'm')
+ self.assertEqual(d6._default_unit, "m")
def test_comparisons(self):
"Testing comparisons"
@@ -133,10 +133,10 @@ class DistanceTest(unittest.TestCase):
d1 = D(m=100)
d2 = D(km=3.5)
- self.assertEqual(str(d1), '100.0 m')
- self.assertEqual(str(d2), '3.5 km')
- self.assertEqual(repr(d1), 'Distance(m=100.0)')
- self.assertEqual(repr(d2), 'Distance(km=3.5)')
+ self.assertEqual(str(d1), "100.0 m")
+ self.assertEqual(str(d2), "3.5 km")
+ self.assertEqual(repr(d1), "Distance(m=100.0)")
+ self.assertEqual(repr(d2), "Distance(km=3.5)")
def test_furlong(self):
d = D(m=201.168)
@@ -144,9 +144,15 @@ class DistanceTest(unittest.TestCase):
def test_unit_att_name(self):
"Testing the `unit_attname` class method"
- unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'),
- ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain'),
- ('Furrow Long', 'furlong')]
+ unit_tuple = [
+ ("Yard", "yd"),
+ ("Nautical Mile", "nm"),
+ ("German legal metre", "german_m"),
+ ("Indian yard", "indian_yd"),
+ ("Chain (Sears)", "chain_sears"),
+ ("Chain", "chain"),
+ ("Furrow Long", "furlong"),
+ ]
for nm, att in unit_tuple:
with self.subTest(nm=nm):
self.assertEqual(att, D.unit_attname(nm))
@@ -188,7 +194,7 @@ class AreaTest(unittest.TestCase):
def test_access_invalid_a(self):
"Testing access in invalid units"
a = A(sq_m=100)
- self.assertFalse(hasattr(a, 'banana'))
+ self.assertFalse(hasattr(a, "banana"))
def test_addition(self):
"Test addition & subtraction"
@@ -251,13 +257,13 @@ class AreaTest(unittest.TestCase):
a2 = A(sq_km=1)
a3 = a1 + a2
- self.assertEqual(a3._default_unit, 'sq_m')
+ self.assertEqual(a3._default_unit, "sq_m")
a4 = a2 + a1
- self.assertEqual(a4._default_unit, 'sq_km')
+ self.assertEqual(a4._default_unit, "sq_km")
a5 = a1 * 2
- self.assertEqual(a5._default_unit, 'sq_m')
+ self.assertEqual(a5._default_unit, "sq_m")
a6 = a1 / 2
- self.assertEqual(a6._default_unit, 'sq_m')
+ self.assertEqual(a6._default_unit, "sq_m")
def test_comparisons(self):
"Testing comparisons"
@@ -275,10 +281,10 @@ class AreaTest(unittest.TestCase):
a1 = A(sq_m=100)
a2 = A(sq_km=3.5)
- self.assertEqual(str(a1), '100.0 sq_m')
- self.assertEqual(str(a2), '3.5 sq_km')
- self.assertEqual(repr(a1), 'Area(sq_m=100.0)')
- self.assertEqual(repr(a2), 'Area(sq_km=3.5)')
+ self.assertEqual(str(a1), "100.0 sq_m")
+ self.assertEqual(str(a2), "3.5 sq_km")
+ self.assertEqual(repr(a1), "Area(sq_m=100.0)")
+ self.assertEqual(repr(a2), "Area(sq_km=3.5)")
def test_hash(self):
a1 = A(sq_m=100)
diff --git a/tests/gis_tests/test_ptr.py b/tests/gis_tests/test_ptr.py
index 1d80e24f92..a09679f5b9 100644
--- a/tests/gis_tests/test_ptr.py
+++ b/tests/gis_tests/test_ptr.py
@@ -6,7 +6,6 @@ from django.test import SimpleTestCase
class CPointerBaseTests(SimpleTestCase):
-
def test(self):
destructor_mock = mock.Mock()
@@ -41,10 +40,10 @@ class CPointerBaseTests(SimpleTestCase):
# results in a TypeError when trying to assign it to the `ptr` property.
# Thus, memory addresses (integers) and pointers of the incorrect type
# (in `bad_ptrs`) aren't allowed.
- bad_ptrs = (5, ctypes.c_char_p(b'foobar'))
+ bad_ptrs = (5, ctypes.c_char_p(b"foobar"))
for bad_ptr in bad_ptrs:
for fg in (fg1, fg2):
- with self.assertRaisesMessage(TypeError, 'Incompatible pointer type'):
+ with self.assertRaisesMessage(TypeError, "Incompatible pointer type"):
fg.ptr = bad_ptr
# Object can be deleted without a destructor set.
@@ -60,7 +59,7 @@ class CPointerBaseTests(SimpleTestCase):
# The destructor is called if set.
fg = FakeGeom2()
- ptr = fg.ptr_type(ctypes.c_float(1.))
+ ptr = fg.ptr_type(ctypes.c_float(1.0))
fg.ptr = ptr
del fg
destructor_mock.assert_called_with(ptr)
diff --git a/tests/gis_tests/test_spatialrefsys.py b/tests/gis_tests/test_spatialrefsys.py
index 548be7f54c..e23ea2ba2a 100644
--- a/tests/gis_tests/test_spatialrefsys.py
+++ b/tests/gis_tests/test_spatialrefsys.py
@@ -4,20 +4,27 @@ from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
from django.utils.functional import cached_property
-test_srs = ({
- 'srid': 4326,
- 'auth_name': ('EPSG', True),
- 'auth_srid': 4326,
- # Only the beginning, because there are differences depending on installed libs
- 'srtext': 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"',
- # +ellps=WGS84 has been removed in the 4326 proj string in proj-4.8
- 'proj_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?',
- 'spheroid': 'WGS 84', 'name': 'WGS 84',
- 'geographic': True, 'projected': False, 'spatialite': True,
- # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
- 'ellipsoid': (6378137.0, 6356752.3, 298.257223563),
- 'eprec': (1, 1, 9),
- 'wkt': re.sub(r'[\s+]', '', """
+test_srs = (
+ {
+ "srid": 4326,
+ "auth_name": ("EPSG", True),
+ "auth_srid": 4326,
+ # Only the beginning, because there are differences depending on installed libs
+ "srtext": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"',
+ # +ellps=WGS84 has been removed in the 4326 proj string in proj-4.8
+ "proj_re": r"\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?",
+ "spheroid": "WGS 84",
+ "name": "WGS 84",
+ "geographic": True,
+ "projected": False,
+ "spatialite": True,
+ # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
+ "ellipsoid": (6378137.0, 6356752.3, 298.257223563),
+ "eprec": (1, 1, 9),
+ "wkt": re.sub(
+ r"[\s+]",
+ "",
+ """
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
@@ -28,37 +35,42 @@ test_srs = ({
UNIT["degree",0.01745329251994328,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]
- """)
-}, {
- 'srid': 32140,
- 'auth_name': ('EPSG', False),
- 'auth_srid': 32140,
- 'srtext': (
- 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",'
- 'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"'
- ),
- 'proj_re': r'\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |'
- r'\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?'
- r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?',
- 'spheroid': 'GRS 1980', 'name': 'NAD83 / Texas South Central',
- 'geographic': False, 'projected': True, 'spatialite': False,
- # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
- 'ellipsoid': (6378137.0, 6356752.31414, 298.257222101),
- 'eprec': (1, 5, 10),
-})
+ """,
+ ),
+ },
+ {
+ "srid": 32140,
+ "auth_name": ("EPSG", False),
+ "auth_srid": 32140,
+ "srtext": (
+ 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",'
+ 'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"'
+ ),
+ "proj_re": r"\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |"
+ r"\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?"
+ r"(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?",
+ "spheroid": "GRS 1980",
+ "name": "NAD83 / Texas South Central",
+ "geographic": False,
+ "projected": True,
+ "spatialite": False,
+ # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
+ "ellipsoid": (6378137.0, 6356752.31414, 298.257222101),
+ "eprec": (1, 5, 10),
+ },
+)
@skipUnlessDBFeature("has_spatialrefsys_table")
class SpatialRefSysTest(TestCase):
-
@cached_property
def SpatialRefSys(self):
return connection.ops.connection.ops.spatial_ref_sys()
def test_get_units(self):
- epsg_4326 = next(f for f in test_srs if f['srid'] == 4326)
- unit, unit_name = self.SpatialRefSys().get_units(epsg_4326['wkt'])
- self.assertEqual(unit_name, 'degree')
+ epsg_4326 = next(f for f in test_srs if f["srid"] == 4326)
+ unit, unit_name = self.SpatialRefSys().get_units(epsg_4326["wkt"])
+ self.assertEqual(unit_name, "degree")
self.assertAlmostEqual(unit, 0.01745329251994328)
def test_retrieve(self):
@@ -66,40 +78,40 @@ class SpatialRefSysTest(TestCase):
Test retrieval of SpatialRefSys model objects.
"""
for sd in test_srs:
- srs = self.SpatialRefSys.objects.get(srid=sd['srid'])
- self.assertEqual(sd['srid'], srs.srid)
+ srs = self.SpatialRefSys.objects.get(srid=sd["srid"])
+ self.assertEqual(sd["srid"], srs.srid)
# Some of the authority names are borked on Oracle, e.g., SRID=32140.
# also, Oracle Spatial seems to add extraneous info to fields, hence the
# the testing with the 'startswith' flag.
- auth_name, oracle_flag = sd['auth_name']
+ auth_name, oracle_flag = sd["auth_name"]
# Compare case-insensitively because srs.auth_name is lowercase
# ("epsg") on Spatialite.
if not connection.ops.oracle or oracle_flag:
self.assertIs(srs.auth_name.upper().startswith(auth_name), True)
- self.assertEqual(sd['auth_srid'], srs.auth_srid)
+ self.assertEqual(sd["auth_srid"], srs.auth_srid)
# No PROJ and different srtext on Oracle.
if not connection.ops.oracle:
- self.assertTrue(srs.wkt.startswith(sd['srtext']))
- self.assertRegex(srs.proj4text, sd['proj_re'])
+ self.assertTrue(srs.wkt.startswith(sd["srtext"]))
+ self.assertRegex(srs.proj4text, sd["proj_re"])
def test_osr(self):
"""
Test getting OSR objects from SpatialRefSys model objects.
"""
for sd in test_srs:
- sr = self.SpatialRefSys.objects.get(srid=sd['srid'])
- self.assertTrue(sr.spheroid.startswith(sd['spheroid']))
- self.assertEqual(sd['geographic'], sr.geographic)
- self.assertEqual(sd['projected'], sr.projected)
- self.assertIs(sr.name.startswith(sd['name']), True)
+ sr = self.SpatialRefSys.objects.get(srid=sd["srid"])
+ self.assertTrue(sr.spheroid.startswith(sd["spheroid"]))
+ self.assertEqual(sd["geographic"], sr.geographic)
+ self.assertEqual(sd["projected"], sr.projected)
+ self.assertIs(sr.name.startswith(sd["name"]), True)
# Testing the SpatialReference object directly.
if not connection.ops.oracle:
srs = sr.srs
- self.assertRegex(srs.proj, sd['proj_re'])
- self.assertTrue(srs.wkt.startswith(sd['srtext']))
+ self.assertRegex(srs.proj, sd["proj_re"])
+ self.assertTrue(srs.wkt.startswith(sd["srtext"]))
def test_ellipsoid(self):
"""
@@ -107,17 +119,17 @@ class SpatialRefSysTest(TestCase):
"""
for sd in test_srs:
# Getting the ellipsoid and precision parameters.
- ellps1 = sd['ellipsoid']
- prec = sd['eprec']
+ ellps1 = sd["ellipsoid"]
+ prec = sd["eprec"]
# Getting our spatial reference and its ellipsoid
- srs = self.SpatialRefSys.objects.get(srid=sd['srid'])
+ srs = self.SpatialRefSys.objects.get(srid=sd["srid"])
ellps2 = srs.ellipsoid
for i in range(3):
self.assertAlmostEqual(ellps1[i], ellps2[i], prec[i])
- @skipUnlessDBFeature('supports_add_srs_entry')
+ @skipUnlessDBFeature("supports_add_srs_entry")
def test_add_entry(self):
"""
Test adding a new entry in the SpatialRefSys model using the
@@ -126,10 +138,8 @@ class SpatialRefSysTest(TestCase):
from django.contrib.gis.utils import add_srs_entry
add_srs_entry(3857)
- self.assertTrue(
- self.SpatialRefSys.objects.filter(srid=3857).exists()
- )
+ self.assertTrue(self.SpatialRefSys.objects.filter(srid=3857).exists())
srs = self.SpatialRefSys.objects.get(srid=3857)
self.assertTrue(
- self.SpatialRefSys.get_spheroid(srs.wkt).startswith('SPHEROID[')
+ self.SpatialRefSys.get_spheroid(srs.wkt).startswith("SPHEROID[")
)
diff --git a/tests/gis_tests/tests.py b/tests/gis_tests/tests.py
index 2bb95ec3d4..d1c93592a8 100644
--- a/tests/gis_tests/tests.py
+++ b/tests/gis_tests/tests.py
@@ -4,19 +4,19 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import ProgrammingError
try:
- from django.contrib.gis.db.backends.postgis.operations import (
- PostGISOperations,
- )
+ from django.contrib.gis.db.backends.postgis.operations import PostGISOperations
+
HAS_POSTGRES = True
except ImportError:
HAS_POSTGRES = False
if HAS_POSTGRES:
+
class FakeConnection:
def __init__(self):
self.settings_dict = {
- 'NAME': 'test',
+ "NAME": "test",
}
class FakePostGISOperations(PostGISOperations):
@@ -25,15 +25,15 @@ if HAS_POSTGRES:
self.connection = FakeConnection()
def _get_postgis_func(self, func):
- if func == 'postgis_lib_version':
+ if func == "postgis_lib_version":
if self.version is None:
raise ProgrammingError
else:
return self.version
- elif func == 'version':
+ elif func == "version":
pass
else:
- raise NotImplementedError('This function was not expected to be called')
+ raise NotImplementedError("This function was not expected to be called")
@unittest.skipUnless(HAS_POSTGRES, "The psycopg2 driver is needed for these tests")
@@ -43,34 +43,34 @@ class TestPostGISVersionCheck(unittest.TestCase):
"""
def test_get_version(self):
- expect = '1.0.0'
+ expect = "1.0.0"
ops = FakePostGISOperations(expect)
actual = ops.postgis_lib_version()
self.assertEqual(expect, actual)
def test_version_classic_tuple(self):
- expect = ('1.2.3', 1, 2, 3)
+ expect = ("1.2.3", 1, 2, 3)
ops = FakePostGISOperations(expect[0])
actual = ops.postgis_version_tuple()
self.assertEqual(expect, actual)
def test_version_dev_tuple(self):
- expect = ('1.2.3dev', 1, 2, 3)
+ expect = ("1.2.3dev", 1, 2, 3)
ops = FakePostGISOperations(expect[0])
actual = ops.postgis_version_tuple()
self.assertEqual(expect, actual)
def test_version_loose_tuple(self):
- expect = ('1.2.3b1.dev0', 1, 2, 3)
+ expect = ("1.2.3b1.dev0", 1, 2, 3)
ops = FakePostGISOperations(expect[0])
actual = ops.postgis_version_tuple()
self.assertEqual(expect, actual)
def test_valid_version_numbers(self):
versions = [
- ('1.3.0', 1, 3, 0),
- ('2.1.1', 2, 1, 1),
- ('2.2.0dev', 2, 2, 0),
+ ("1.3.0", 1, 3, 0),
+ ("2.1.1", 2, 1, 1),
+ ("2.2.0dev", 2, 2, 0),
]
for version in versions:
diff --git a/tests/gis_tests/utils.py b/tests/gis_tests/utils.py
index 35c7d366ee..2fbfd438eb 100644
--- a/tests/gis_tests/utils.py
+++ b/tests/gis_tests/utils.py
@@ -12,25 +12,30 @@ def skipUnlessGISLookup(*gis_lookups):
"""
Skip a test unless a database supports all of gis_lookups.
"""
+
def decorator(test_func):
@wraps(test_func)
def skip_wrapper(*args, **kwargs):
if any(key not in connection.ops.gis_operators for key in gis_lookups):
raise unittest.SkipTest(
- "Database doesn't support all the lookups: %s" % ", ".join(gis_lookups)
+ "Database doesn't support all the lookups: %s"
+ % ", ".join(gis_lookups)
)
return test_func(*args, **kwargs)
+
return skip_wrapper
+
return decorator
-_default_db = settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].rsplit('.')[-1]
+_default_db = settings.DATABASES[DEFAULT_DB_ALIAS]["ENGINE"].rsplit(".")[-1]
# MySQL spatial indices can't handle NULL geometries.
-gisfield_may_be_null = _default_db != 'mysql'
+gisfield_may_be_null = _default_db != "mysql"
class FuncTestMixin:
"""Assert that Func expressions aren't mutated during their as_sql()."""
+
def setUp(self):
def as_sql_wrapper(original_as_sql):
def inner(*args, **kwargs):
@@ -40,9 +45,12 @@ class FuncTestMixin:
func.output_field
__dict__original = copy.deepcopy(func.__dict__)
result = original_as_sql(*args, **kwargs)
- msg = '%s Func was mutated during compilation.' % func.__class__.__name__
+ msg = (
+ "%s Func was mutated during compilation." % func.__class__.__name__
+ )
self.assertEqual(func.__dict__, __dict__original, msg)
return result
+
return inner
def __getattribute__(self, name):
@@ -51,12 +59,14 @@ class FuncTestMixin:
try:
as_sql = __getattribute__original(self, vendor_impl)
except AttributeError:
- as_sql = __getattribute__original(self, 'as_sql')
+ as_sql = __getattribute__original(self, "as_sql")
return as_sql_wrapper(as_sql)
- vendor_impl = 'as_' + connection.vendor
+ vendor_impl = "as_" + connection.vendor
__getattribute__original = Func.__getattribute__
- self.func_patcher = mock.patch.object(Func, '__getattribute__', __getattribute__)
+ self.func_patcher = mock.patch.object(
+ Func, "__getattribute__", __getattribute__
+ )
self.func_patcher.start()
super().setUp()