Browse files

Removed some more hardcoded backends in GIS tests

Refs #22632. Thanks Tim Graham for the review.
  • Loading branch information...
1 parent 5675eb3 commit 60428ed5db76f509f4a0eb737d96b4f0ae6b0ad5 @claudep claudep committed Aug 21, 2014
View
27 django/contrib/gis/db/backends/base.py
@@ -16,6 +16,9 @@ class BaseSpatialFeatures(object):
# Does the database contain a SpatialRefSys model to store SRID information?
has_spatialrefsys_table = True
+ # Reference implementation of 3D functions is:
+ # http://postgis.net/docs/PostGIS_Special_Functions_Index.html#PostGIS_3D_Functions
+ supports_3d_functions = False
# Does the database support SRID transform operations?
supports_transform = True
# Do geometric relationship operations operate on real shapes (or only on bounding boxes)?
@@ -29,24 +32,34 @@ class BaseSpatialFeatures(object):
# The following properties indicate if the database backend support
# certain lookups (dwithin, left and right, relate, ...)
+ supports_distances_lookups = True
supports_left_right_lookups = False
@property
- def supports_relate_lookup(self):
- return 'relate' in self.connection.ops.geometry_functions
+ def supports_bbcontains_lookup(self):
+ return 'bbcontains' in self.connection.ops.gis_terms
+
+ @property
+ def supports_contained_lookup(self):
+ return 'contained' in self.connection.ops.gis_terms
@property
- def has_dwithin_lookup(self):
+ def supports_dwithin_lookup(self):
return 'dwithin' in self.connection.ops.distance_functions
+ @property
+ def supports_relate_lookup(self):
+ return 'relate' in self.connection.ops.gis_terms
+
# For each of those methods, the class will have a property named
# `has_<name>_method` (defined in __init__) which accesses connection.ops
# to determine GIS method availability.
geoqueryset_methods = (
- 'centroid', 'difference', 'envelope', 'force_rhr', 'geohash', 'gml',
- 'intersection', 'kml', 'num_geom', 'perimeter', 'point_on_surface',
- 'reverse', 'scale', 'snap_to_grid', 'svg', 'sym_difference',
- 'transform', 'translate', 'union', 'unionagg',
+ 'area', 'centroid', 'difference', 'distance', 'distance_spheroid',
+ 'envelope', 'force_rhr', 'geohash', 'gml', 'intersection', 'kml',
+ 'length', 'num_geom', 'perimeter', 'point_on_surface', 'reverse',
+ 'scale', 'snap_to_grid', 'svg', 'sym_difference', 'transform',
+ 'translate', 'union', 'unionagg',
)
# Specifies whether the Collect and Extent aggregates are supported by the database
View
1 django/contrib/gis/db/backends/mysql/base.py
@@ -10,6 +10,7 @@
class DatabaseFeatures(BaseSpatialFeatures, MySQLDatabaseFeatures):
has_spatialrefsys_table = False
+ supports_distances_lookups = False
supports_transform = False
supports_real_shape_operations = False
supports_null_geometries = False
View
1 django/contrib/gis/db/backends/postgis/base.py
@@ -11,6 +11,7 @@
class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
+ supports_3d_functions = True
supports_left_right_lookups = True
View
8 django/contrib/gis/db/models/query.py
@@ -631,8 +631,8 @@ def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, *
u, unit_name, s = get_srid_info(self.query.transformed_srid, connection)
geodetic = unit_name.lower() in geo_field.geodetic_units
- if backend.spatialite and geodetic:
- raise ValueError('SQLite does not support linear distance calculations on geodetic coordinate systems.')
+ if geodetic and not connection.features.supports_distance_geodetic:
+ raise ValueError('This database does not support linear distance calculations on geodetic coordinate systems.')
if distance:
if self.query.transformed_srid:
@@ -690,8 +690,8 @@ def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, *
# works on 3D geometries.
procedure_fmt += ",'%(spheroid)s'"
procedure_args.update({'function': backend.length_spheroid, 'spheroid': params[1]})
- elif geom_3d and backend.postgis:
- # Use 3D variants of perimeter and length routines on PostGIS.
+ elif geom_3d and connection.features.supports_3d_functions:
+ # Use 3D variants of perimeter and length routines on supported backends.
if perimeter:
procedure_args.update({'function': backend.perimeter3d})
elif length:
View
3 django/contrib/gis/tests/distapp/models.py
@@ -1,4 +1,5 @@
from django.contrib.gis.db import models
+from django.contrib.gis.tests.utils import gisfield_may_be_null
from django.utils.encoding import python_2_unicode_compatible
@@ -38,7 +39,7 @@ class CensusZipcode(NamedModel):
class SouthTexasZipcode(NamedModel):
"Model for a few South Texas ZIP codes."
- poly = models.PolygonField(srid=32140, null=True)
+ poly = models.PolygonField(srid=32140, null=gisfield_may_be_null)
class Interstate(NamedModel):
View
74 django/contrib/gis/tests/distapp/tests.py
@@ -6,9 +6,7 @@
from django.db.models import Q
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.measure import D # alias for Distance
-from django.contrib.gis.tests.utils import (
- mysql, oracle, postgis, spatialite, no_oracle
-)
+from django.contrib.gis.tests.utils import oracle, postgis, spatialite, no_oracle
from django.test import TestCase, skipUnlessDBFeature
if HAS_GEOS:
@@ -18,8 +16,6 @@
SouthTexasCity, SouthTexasCityFt, CensusZipcode, SouthTexasZipcode)
-@skipUnless(HAS_GEOS and not mysql,
- "GEOS and spatial db (not mysql) are required.")
@skipUnlessDBFeature("gis_enabled")
class DistanceTest(TestCase):
fixtures = ['initial']
@@ -50,7 +46,7 @@ def test_init(self):
self.assertEqual(1, Interstate.objects.count())
self.assertEqual(1, SouthTexasInterstate.objects.count())
- @skipUnlessDBFeature("has_dwithin_lookup")
+ @skipUnlessDBFeature("supports_dwithin_lookup")
def test_dwithin(self):
"""
Test the `dwithin` lookup type.
@@ -99,6 +95,7 @@ def test_dwithin(self):
else:
self.assertListEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))))
+ @skipUnlessDBFeature("has_distance_method")
def test_distance_projected(self):
"""
Test the `distance` GeoQuerySet method on projected coordinate systems.
@@ -139,7 +136,7 @@ def test_distance_projected(self):
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
- @skipUnlessDBFeature("supports_distance_geodetic")
+ @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
def test_distance_geodetic(self):
"""
Test the `distance` GeoQuerySet method on geodetic coordinate systems.
@@ -149,16 +146,16 @@ def test_distance_geodetic(self):
# Testing geodetic distance calculation with a non-point geometry
# (a LineString of Wollongong and Shellharbour coords).
ls = LineString(((150.902, -34.4245), (150.87, -34.5789)))
- if oracle or postgis:
- # Reference query:
- # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name;
- distances = [1120954.92533513, 140575.720018241, 640396.662906304,
- 60580.9693849269, 972807.955955075, 568451.8357838,
- 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
- qs = AustraliaCity.objects.distance(ls).order_by('name')
- for city, distance in zip(qs, distances):
- # Testing equivalence to within a meter.
- self.assertAlmostEqual(distance, city.distance.m, 0)
+
+ # Reference query:
+ # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name;
+ distances = [1120954.92533513, 140575.720018241, 640396.662906304,
+ 60580.9693849269, 972807.955955075, 568451.8357838,
+ 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
+ qs = AustraliaCity.objects.distance(ls).order_by('name')
+ for city, distance in zip(qs, distances):
+ # Testing equivalence to within a meter.
+ self.assertAlmostEqual(distance, city.distance.m, 0)
# Got the reference distances using the raw SQL statements:
# SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11));
@@ -197,6 +194,7 @@ def test_distance_geodetic(self):
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
@no_oracle # Oracle already handles geographic distance calculation.
+ @skipUnlessDBFeature("has_distance_method")
def test_distance_transform(self):
"""
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
@@ -226,6 +224,7 @@ def test_distance_transform(self):
for i, z in enumerate(qs):
self.assertAlmostEqual(z.distance.m, dists_m[i], 5)
+ @skipUnlessDBFeature("supports_distances_lookups")
def test_distance_lookups(self):
"""
Test the `distance_lt`, `distance_gt`, `distance_lte`, and `distance_gte` lookup types.
@@ -255,6 +254,7 @@ def test_distance_lookups(self):
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):
"""
Test distance lookups on geodetic coordinate systems.
@@ -264,23 +264,11 @@ def test_geodetic_distance_lookups(self):
line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)', 4326)
dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100)))
- if oracle or postgis:
- # Oracle and PostGIS can do distance lookups on arbitrary geometries.
- self.assertEqual(9, dist_qs.count())
- self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
- 'Melbourne', 'Mittagong', 'Shellharbour',
- 'Sydney', 'Thirroul', 'Wollongong'],
- self.get_names(dist_qs))
- else:
- # spatialite only allow geodetic distance queries (utilizing
- # ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields
- # on geometry columns.
- self.assertRaises(ValueError, dist_qs.count)
-
- # Ensured that a ValueError was raised, none of the rest of the test is
- # support on this backend, so bail now.
- if spatialite:
- return
+ self.assertEqual(9, dist_qs.count())
+ self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
+ 'Melbourne', 'Mittagong', 'Shellharbour',
+ 'Sydney', 'Thirroul', 'Wollongong'],
+ self.get_names(dist_qs))
# Too many params (4 in this case) should raise a ValueError.
self.assertRaises(ValueError, len,
@@ -309,18 +297,18 @@ def test_geodetic_distance_lookups(self):
# 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).
- if postgis:
+ querysets = [qs1]
+ if connection.features.has_distance_spheroid_method:
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 = [qs1, qs2]
- else:
- querysets = [qs1]
+ querysets.append(qs2)
for qs in querysets:
cities = self.get_names(qs)
self.assertEqual(cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
+ @skipUnlessDBFeature("has_area_method")
def test_area(self):
"""
Test the `area` GeoQuerySet method.
@@ -333,6 +321,7 @@ def test_area(self):
for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').area()):
self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
+ @skipUnlessDBFeature("has_length_method")
def test_length(self):
"""
Test the `length` GeoQuerySet method.
@@ -342,13 +331,13 @@ def test_length(self):
len_m1 = 473504.769553813
len_m2 = 4617.668
- if spatialite:
- # Does not support geodetic coordinate systems.
- self.assertRaises(ValueError, Interstate.objects.length)
- else:
+ if connection.features.supports_distance_geodetic:
qs = Interstate.objects.length()
tol = 2 if oracle else 3
self.assertAlmostEqual(len_m1, qs[0].length.m, tol)
+ else:
+ # Does not support geodetic coordinate systems.
+ self.assertRaises(ValueError, Interstate.objects.length)
# Now doing length on a projected coordinate system.
i10 = SouthTexasInterstate.objects.length().get(name='I-10')
@@ -370,6 +359,7 @@ def test_perimeter(self):
for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')):
self.assertEqual(0, c.perim.m)
+ @skipUnlessDBFeature("has_area_method", "has_distance_method")
def test_measurement_null_fields(self):
"""
Test the measurement GeoQuerySet methods on fields with NULL values.
View
8 django/contrib/gis/tests/geo3d/tests.py
@@ -6,8 +6,7 @@
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import postgis
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
if HAS_GEOS:
@@ -62,15 +61,16 @@
)
-@skipUnless(HAS_GEOS and HAS_GDAL and postgis, "Geos, GDAL and postgis are required.")
+@skipUnless(HAS_GDAL, "GDAL is required for Geo3DTest.")
+@skipUnlessDBFeature("gis_enabled", "supports_3d_functions")
class Geo3DTest(TestCase):
"""
Only a subset of the PostGIS routines are 3D-enabled, and this TestCase
tries to test the features that can handle 3D and that are also
available within GeoDjango. For more information, see the PostGIS docs
on the routines that support 3D:
- http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_3D_Functions
+ http://postgis.net/docs/PostGIS_Special_Functions_Index.html#PostGIS_3D_Functions
"""
def _load_interstate_data(self):
View
7 django/contrib/gis/tests/geoapp/models.py
@@ -1,10 +1,7 @@
from django.contrib.gis.db import models
-from django.contrib.gis.tests.utils import mysql
+from django.contrib.gis.tests.utils import gisfield_may_be_null
from django.utils.encoding import python_2_unicode_compatible
-# MySQL spatial indices can't handle NULL geometries.
-null_flag = not mysql
-
@python_2_unicode_compatible
class NamedModel(models.Model):
@@ -42,7 +39,7 @@ class Meta:
class State(NamedModel):
- poly = models.PolygonField(null=null_flag) # Allowing NULL geometries here.
+ poly = models.PolygonField(null=gisfield_may_be_null) # Allowing NULL geometries here.
class Track(NamedModel):
View
36 django/contrib/gis/tests/geoapp/tests.py
@@ -2,12 +2,11 @@
import re
import unittest
-from unittest import skipUnless
from django.db import connection
from django.contrib.gis import gdal
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import mysql, oracle, postgis, spatialite
+from django.contrib.gis.tests.utils import oracle, postgis, spatialite
from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
@@ -142,11 +141,12 @@ def test_lookup_insert_transform(self):
# If the GeometryField SRID is -1, then we shouldn't perform any
# transformation if the SRID of the input geometry is different.
- # SpatiaLite does not support missing SRID values.
- if not spatialite:
- m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
- m1.save()
- self.assertEqual(-1, m1.geom.srid)
+ if spatialite and connection.ops.spatial_version < 3:
+ # SpatiaLite < 3 does not support missing SRID values.
+ return
+ m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
+ m1.save()
+ self.assertEqual(-1, m1.geom.srid)
def test_createnull(self):
"Testing creating a model instance and the geometry being None"
@@ -223,7 +223,7 @@ def test_contains_contained_lookups(self):
# Seeing what cities are in Texas, should get Houston and Dallas,
# and Oklahoma City because 'contained' only checks on the
# _bounding box_ of the Geometries.
- if not oracle:
+ if connection.features.supports_contained_lookup:
qs = City.objects.filter(point__contained=texas.mpoly)
self.assertEqual(3, qs.count())
cities = ['Houston', 'Dallas', 'Oklahoma City']
@@ -245,23 +245,22 @@ def test_contains_contained_lookups(self):
self.assertEqual('New Zealand', nz.name)
# Spatialite 2.3 thinks that Lawrence is in Puerto Rico (a NULL geometry).
- if not spatialite:
+ if not (spatialite and connection.ops.spatial_version < 3):
ks = State.objects.get(poly__contains=lawrence.point)
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(0, len(Country.objects.filter(mpoly__contains=pueblo.point))) # Query w/GEOSGeometry object
- self.assertEqual((mysql and 1) or 0,
- len(Country.objects.filter(mpoly__contains=okcity.point.wkt))) # Qeury 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 if connection.features.supports_real_shape_operations else 1) # Query w/WKT
# OK City is contained w/in bounding box of Texas.
- if not oracle:
+ 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)
- # Only PostGIS has `left` and `right` lookup types.
@skipUnlessDBFeature("supports_left_right_lookups")
def test_left_right_lookups(self):
"Testing the 'left' and 'right' lookup types."
@@ -409,10 +408,9 @@ def test_centroid(self):
for s in qs:
self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol))
- @skipUnlessDBFeature("has_difference_method")
- @skipUnlessDBFeature("has_intersection_method")
- @skipUnlessDBFeature("has_sym_difference_method")
- @skipUnlessDBFeature("has_union_method")
+ @skipUnlessDBFeature(
+ "has_difference_method", "has_intersection_method",
+ "has_sym_difference_method", "has_union_method")
def test_diff_intersection_union(self):
"Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
geom = Point(5, 23)
@@ -610,7 +608,7 @@ def test_point_on_surface(self):
'Texas': fromstr('POINT (-103.002434 36.500397)', srid=4326),
}
- elif postgis or spatialite:
+ else:
# Using GEOSGeometry to compute the reference point on surface values
# -- since PostGIS also uses GEOS these should be the same.
ref = {'New Zealand': Country.objects.get(name='New Zealand').mpoly.point_on_surface,
View
8 django/contrib/gis/tests/geogapp/tests.py
@@ -10,21 +10,22 @@
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.measure import D
from django.contrib.gis.tests.utils import postgis
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
if HAS_GEOS:
from .models import City, County, Zipcode
-@skipUnless(HAS_GEOS and postgis, "Geos and postgis are required.")
+@skipUnlessDBFeature("gis_enabled")
class GeographyTest(TestCase):
fixtures = ['initial']
def test01_fixture_load(self):
"Ensure geography features loaded properly."
self.assertEqual(8, City.objects.count())
+ @skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
def test02_distance_lookup(self):
"Testing GeoQuerySet distance lookup support on non-point geography fields."
z = Zipcode.objects.get(code='77002')
@@ -39,12 +40,14 @@ def test02_distance_lookup(self):
for cities in [cities1, cities2]:
self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
+ @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
def test03_distance_method(self):
"Testing GeoQuerySet.distance() support on non-point geography fields."
# `GeoQuerySet.distance` is not allowed geometry fields.
htown = City.objects.get(name='Houston')
Zipcode.objects.distance(htown.point)
+ @skipUnless(postgis, "This is a PostGIS-specific test")
def test04_invalid_operators_functions(self):
"Ensuring exceptions are raised for operators & functions invalid on geography fields."
# Only a subset of the geometry functions & operator are available
@@ -89,6 +92,7 @@ def test05_geography_layermapping(self):
self.assertEqual(name, c.name)
self.assertEqual(state, c.state)
+ @skipUnlessDBFeature("has_area_method", "supports_distance_geodetic")
def test06_geography_area(self):
"Testing that Area calculations work on geography columns."
# SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
View
33 django/contrib/gis/tests/inspectapp/tests.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
import os
+import re
from unittest import skipUnless
from django.core.management import call_command
@@ -11,7 +12,7 @@
from django.utils.six import StringIO
if HAS_GDAL:
- from django.contrib.gis.gdal import Driver
+ from django.contrib.gis.gdal import Driver, OGRException
from django.contrib.gis.utils.ogrinspect import ogrinspect
from .models import AllOGRFields
@@ -77,23 +78,20 @@ def test_date_field(self):
self.assertEqual(model_def, '\n'.join(expected))
def test_time_field(self):
- # Only possible to test this on PostGIS at the moment. MySQL
- # complains about permissions, and SpatiaLite/Oracle are
- # insanely difficult to get support compiled in for in GDAL.
- if not connections['default'].ops.postgis:
- self.skipTest("This database does not support 'ogrinspect'ion")
-
# Getting the database identifier used by OGR, if None returned
# GDAL does not have the support compiled in.
ogr_db = get_ogr_db_string()
if not ogr_db:
- self.skipTest("Your GDAL installation does not support PostGIS databases")
+ self.skipTest("Unable to setup an OGR connection to your database")
- # 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'])
+ 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'])
+ except OGRException:
+ 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'
@@ -111,10 +109,9 @@ def test_time_field(self):
self.assertIn(' f_char = models.CharField(max_length=10)', model_def)
self.assertIn(' f_date = models.DateField()', model_def)
- self.assertTrue(model_def.endswith(
- ' geom = models.PolygonField()\n'
- ' objects = models.GeoManager()'
- ))
+ self.assertIsNotNone(re.search(
+ r' geom = models.PolygonField\(([^\)])*\)\n' # Some backends may have srid=-1
+ r' objects = models.GeoManager\(\)', model_def))
def test_management_command(self):
shp_file = os.path.join(TEST_DATA, 'cities', 'cities.shp')
@@ -142,7 +139,7 @@ def get_ogr_db_string():
'django.contrib.gis.db.backends.spatialite': ('SQLite', '%(db_name)s', '')
}
- drv_name, db_str, param_sep = drivers[db['ENGINE']]
+ drv_name, db_str, param_sep = drivers.get(db['ENGINE'])
# Ensure that GDAL library has driver support for the database.
try:
View
7 django/contrib/gis/tests/layermap/tests.py
@@ -8,8 +8,7 @@
from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
-from django.contrib.gis.tests.utils import mysql
-from django.db import router
+from django.db import connection, router
from django.conf import settings
from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
@@ -151,15 +150,15 @@ def test_layermap_unique_multigeometry_fk(self):
# Unique may take tuple or string parameters.
for arg in ('name', ('name', 'mpoly')):
lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg)
- except:
+ except Exception:
self.fail('No exception should be raised for proper use of keywords.')
# Testing invalid params for the `unique` keyword.
for e, arg in ((TypeError, 5.0), (ValueError, 'foobar'), (ValueError, ('name', 'mpolygon'))):
self.assertRaises(e, LayerMapping, County, co_shp, co_mapping, transform=False, unique=arg)
# No source reference system defined in the shapefile, should raise an error.
- if not mysql:
+ if connection.features.supports_transform:
self.assertRaises(LayerMapError, LayerMapping, County, co_shp, co_mapping)
# Passing in invalid ForeignKey mapping parameters -- must be a dictionary
View
7 django/contrib/gis/tests/relatedapp/tests.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import mysql, no_oracle
+from django.contrib.gis.tests.utils import no_oracle
+from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
if HAS_GEOS:
@@ -146,7 +147,7 @@ def test06_f_expressions(self):
self.assertEqual(1, len(qs))
self.assertEqual('P2', qs[0].name)
- if not mysql:
+ if connection.features.supports_transform:
# 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'))
@@ -159,7 +160,7 @@ def test06_f_expressions(self):
self.assertEqual(1, len(qs))
self.assertEqual('P1', qs[0].name)
- if not mysql:
+ if connection.features.supports_transform:
# This time the city column should be wrapped in transformation SQL.
qs = Parcel.objects.filter(border2__contains=F('city__location__point'))
self.assertEqual(1, len(qs))
View
3 django/contrib/gis/tests/utils.py
@@ -28,6 +28,9 @@ def no_oracle(func):
mysql = _default_db == 'mysql'
spatialite = _default_db == 'spatialite'
+# MySQL spatial indices can't handle NULL geometries.
+gisfield_may_be_null = not mysql
+
if oracle and 'gis' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE']:
from django.contrib.gis.db.backends.oracle.models import OracleSpatialRefSys as SpatialRefSys
elif postgis:
View
6 django/contrib/gis/utils/layermapping.py
@@ -103,10 +103,10 @@ def __init__(self, model, data, mapping, layer=0,
# Getting the geometry column associated with the model (an
# exception will be raised if there is no geometry column).
- if self.spatial_backend.mysql:
- transform = False
- else:
+ if connections[self.using].features.supports_transform:
self.geo_field = self.geometry_field()
+ else:
+ transform = False
# Checking the source spatial reference system, and getting
# the coordinate transformation object (unless the `transform`

0 comments on commit 60428ed

Please sign in to comment.