Fixed #27448 -- Switched use of functions deprecated in PostGIS 2.2.
Thanks Claude Paroz and Tim Graham for reviews, and Mjumbe Wawatu Poe for the initial regression test.
This commit is contained in:
parent
df3e92a41c
commit
cbae4d3184
|
@ -91,13 +91,16 @@ class PostGISDistanceOperator(PostGISOperator):
|
||||||
template_params = self.check_raster(lookup, template_params)
|
template_params = self.check_raster(lookup, template_params)
|
||||||
sql_template = self.sql_template
|
sql_template = self.sql_template
|
||||||
if len(lookup.rhs) == 3 and lookup.rhs[-1] == 'spheroid':
|
if len(lookup.rhs) == 3 and lookup.rhs[-1] == 'spheroid':
|
||||||
template_params.update({'op': self.op, 'func': 'ST_Distance_Spheroid'})
|
template_params.update({
|
||||||
|
'op': self.op,
|
||||||
|
'func': connection.ops.spatial_function_name('DistanceSpheroid'),
|
||||||
|
})
|
||||||
sql_template = '%(func)s(%(lhs)s, %(rhs)s, %%s) %(op)s %(value)s'
|
sql_template = '%(func)s(%(lhs)s, %(rhs)s, %%s) %(op)s %(value)s'
|
||||||
# Using distance_spheroid requires the spheroid of the field as
|
# Using DistanceSpheroid requires the spheroid of the field as
|
||||||
# a parameter.
|
# a parameter.
|
||||||
sql_params.insert(1, lookup.lhs.output_field._spheroid)
|
sql_params.insert(1, lookup.lhs.output_field._spheroid)
|
||||||
else:
|
else:
|
||||||
template_params.update({'op': self.op, 'func': 'ST_Distance_Sphere'})
|
template_params.update({'op': self.op, 'func': connection.ops.spatial_function_name('DistanceSphere')})
|
||||||
return sql_template % template_params, sql_params
|
return sql_template % template_params, sql_params
|
||||||
return super(PostGISDistanceOperator, self).as_sql(connection, lookup, template_params, sql_params)
|
return super(PostGISDistanceOperator, self).as_sql(connection, lookup, template_params, sql_params)
|
||||||
|
|
||||||
|
@ -146,11 +149,6 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
}
|
}
|
||||||
|
|
||||||
unsupported_functions = set()
|
unsupported_functions = set()
|
||||||
function_names = {
|
|
||||||
'BoundingCircle': 'ST_MinimumBoundingCircle',
|
|
||||||
'MemSize': 'ST_Mem_Size',
|
|
||||||
'NumPoints': 'ST_NPoints',
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, connection):
|
def __init__(self, connection):
|
||||||
super(PostGISOperations, self).__init__(connection)
|
super(PostGISOperations, self).__init__(connection)
|
||||||
|
@ -197,6 +195,21 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
self.union = prefix + 'Union'
|
self.union = prefix + 'Union'
|
||||||
self.unionagg = prefix + 'Union'
|
self.unionagg = prefix + 'Union'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def function_names(self):
|
||||||
|
function_names = {
|
||||||
|
'BoundingCircle': 'ST_MinimumBoundingCircle',
|
||||||
|
'NumPoints': 'ST_NPoints',
|
||||||
|
}
|
||||||
|
if self.spatial_version < (2, 2, 0):
|
||||||
|
function_names.update({
|
||||||
|
'DistanceSphere': 'ST_distance_sphere',
|
||||||
|
'DistanceSpheroid': 'ST_distance_spheroid',
|
||||||
|
'LengthSpheroid': 'ST_length_spheroid',
|
||||||
|
'MemSize': 'ST_mem_size',
|
||||||
|
})
|
||||||
|
return function_names
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def spatial_version(self):
|
def spatial_version(self):
|
||||||
"""Determine the version of the PostGIS library."""
|
"""Determine the version of the PostGIS library."""
|
||||||
|
|
|
@ -249,11 +249,12 @@ class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFuncWithGeoParam):
|
||||||
elif geo_field.geodetic(connection):
|
elif geo_field.geodetic(connection):
|
||||||
# Geometry fields with geodetic (lon/lat) coordinates need special distance functions
|
# Geometry fields with geodetic (lon/lat) coordinates need special distance functions
|
||||||
if self.spheroid:
|
if self.spheroid:
|
||||||
self.function = 'ST_Distance_Spheroid' # More accurate, resource intensive
|
# DistanceSpheroid is more accurate and resource intensive than DistanceSphere
|
||||||
|
self.function = connection.ops.spatial_function_name('DistanceSpheroid')
|
||||||
# Replace boolean param by the real spheroid of the base field
|
# Replace boolean param by the real spheroid of the base field
|
||||||
self.source_expressions[2] = Value(geo_field._spheroid)
|
self.source_expressions[2] = Value(geo_field._spheroid)
|
||||||
else:
|
else:
|
||||||
self.function = 'ST_Distance_Sphere'
|
self.function = connection.ops.spatial_function_name('DistanceSphere')
|
||||||
return super(Distance, self).as_sql(compiler, connection)
|
return super(Distance, self).as_sql(compiler, connection)
|
||||||
|
|
||||||
def as_oracle(self, compiler, connection):
|
def as_oracle(self, compiler, connection):
|
||||||
|
@ -307,7 +308,7 @@ class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc):
|
||||||
self.source_expressions.append(Value(self.spheroid))
|
self.source_expressions.append(Value(self.spheroid))
|
||||||
elif geo_field.geodetic(connection):
|
elif geo_field.geodetic(connection):
|
||||||
# Geometry fields with geodetic (lon/lat) coordinates need length_spheroid
|
# Geometry fields with geodetic (lon/lat) coordinates need length_spheroid
|
||||||
self.function = 'ST_Length_Spheroid'
|
self.function = connection.ops.spatial_function_name('LengthSpheroid')
|
||||||
self.source_expressions.append(Value(geo_field._spheroid))
|
self.source_expressions.append(Value(geo_field._spheroid))
|
||||||
else:
|
else:
|
||||||
dim = min(f.dim for f in self.get_source_fields() if f)
|
dim = min(f.dim for f in self.get_source_fields() if f)
|
||||||
|
|
|
@ -94,3 +94,21 @@ class TestPostGISVersionCheck(unittest.TestCase):
|
||||||
ops = FakePostGISOperations()
|
ops = FakePostGISOperations()
|
||||||
with self.assertRaises(ImproperlyConfigured):
|
with self.assertRaises(ImproperlyConfigured):
|
||||||
ops.spatial_version
|
ops.spatial_version
|
||||||
|
|
||||||
|
def test_version_dependent_funcs(self):
|
||||||
|
"""
|
||||||
|
Resolve names of functions renamed and deprecated in PostGIS 2.2.0
|
||||||
|
depending on PostGIS version.
|
||||||
|
Remove when dropping support for PostGIS 2.1.
|
||||||
|
"""
|
||||||
|
ops = FakePostGISOperations('2.2.0')
|
||||||
|
self.assertEqual(ops.spatial_function_name('DistanceSphere'), 'ST_DistanceSphere')
|
||||||
|
self.assertEqual(ops.spatial_function_name('DistanceSpheroid'), 'ST_DistanceSpheroid')
|
||||||
|
self.assertEqual(ops.spatial_function_name('LengthSpheroid'), 'ST_LengthSpheroid')
|
||||||
|
self.assertEqual(ops.spatial_function_name('MemSize'), 'ST_MemSize')
|
||||||
|
|
||||||
|
ops = FakePostGISOperations('2.1.0')
|
||||||
|
self.assertEqual(ops.spatial_function_name('DistanceSphere'), 'ST_distance_sphere')
|
||||||
|
self.assertEqual(ops.spatial_function_name('DistanceSpheroid'), 'ST_distance_spheroid')
|
||||||
|
self.assertEqual(ops.spatial_function_name('LengthSpheroid'), 'ST_length_spheroid')
|
||||||
|
self.assertEqual(ops.spatial_function_name('MemSize'), 'ST_mem_size')
|
||||||
|
|
Loading…
Reference in New Issue