Fixed #23108 -- Dropped support for PostgreSQL 8.4 & PostGIS 1.3, 1.4.
Thanks Claude Paroz for the review.
This commit is contained in:
parent
7ce4ef58c9
commit
a9bdce7e55
|
@ -25,12 +25,13 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
identification integers for the PostGIS geometry and/or
|
identification integers for the PostGIS geometry and/or
|
||||||
geography types (if supported).
|
geography types (if supported).
|
||||||
"""
|
"""
|
||||||
field_types = [('geometry', 'GeometryField')]
|
field_types = [
|
||||||
if self.connection.ops.geography:
|
('geometry', 'GeometryField'),
|
||||||
# The value for the geography type is actually a tuple
|
# The value for the geography type is actually a tuple
|
||||||
# to pass in the `geography=True` keyword to the field
|
# to pass in the `geography=True` keyword to the field
|
||||||
# definition.
|
# definition.
|
||||||
field_types.append(('geography', ('GeometryField', {'geography': True})))
|
('geography', ('GeometryField', {'geography': True})),
|
||||||
|
]
|
||||||
postgis_types = {}
|
postgis_types = {}
|
||||||
|
|
||||||
# The OID integers associated with the geometry type may
|
# The OID integers associated with the geometry type may
|
||||||
|
@ -79,7 +80,6 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
if not row:
|
if not row:
|
||||||
raise GeoIntrospectionError
|
raise GeoIntrospectionError
|
||||||
except GeoIntrospectionError:
|
except GeoIntrospectionError:
|
||||||
if self.connection.ops.geography:
|
|
||||||
cursor.execute('SELECT "coord_dimension", "srid", "type" '
|
cursor.execute('SELECT "coord_dimension", "srid", "type" '
|
||||||
'FROM "geography_columns" '
|
'FROM "geography_columns" '
|
||||||
'WHERE "f_table_name"=%s AND "f_geography_column"=%s',
|
'WHERE "f_table_name"=%s AND "f_geography_column"=%s',
|
||||||
|
|
|
@ -74,6 +74,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
compiler_module = 'django.contrib.gis.db.models.sql.compiler'
|
compiler_module = 'django.contrib.gis.db.models.sql.compiler'
|
||||||
name = 'postgis'
|
name = 'postgis'
|
||||||
postgis = True
|
postgis = True
|
||||||
|
geography = True
|
||||||
geom_func_prefix = 'ST_'
|
geom_func_prefix = 'ST_'
|
||||||
version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
|
version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
|
||||||
valid_aggregates = {'Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'}
|
valid_aggregates = {'Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'}
|
||||||
|
@ -140,6 +141,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
'relate': (PostGISRelate, six.string_types),
|
'relate': (PostGISRelate, six.string_types),
|
||||||
'coveredby': PostGISFunction(prefix, 'CoveredBy'),
|
'coveredby': PostGISFunction(prefix, 'CoveredBy'),
|
||||||
'covers': PostGISFunction(prefix, 'Covers'),
|
'covers': PostGISFunction(prefix, 'Covers'),
|
||||||
|
'contains_properly': PostGISFunction(prefix, 'ContainsProperly'),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Valid distance types and substitutions
|
# Valid distance types and substitutions
|
||||||
|
@ -162,23 +164,6 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
# Adding the distance functions to the geometries lookup.
|
# Adding the distance functions to the geometries lookup.
|
||||||
self.geometry_functions.update(self.distance_functions)
|
self.geometry_functions.update(self.distance_functions)
|
||||||
|
|
||||||
# Only PostGIS versions 1.3.4+ have GeoJSON serialization support.
|
|
||||||
if self.spatial_version < (1, 3, 4):
|
|
||||||
GEOJSON = False
|
|
||||||
else:
|
|
||||||
GEOJSON = prefix + 'AsGeoJson'
|
|
||||||
|
|
||||||
# ST_ContainsProperly ST_MakeLine, and ST_GeoHash added in 1.4.
|
|
||||||
if self.spatial_version >= (1, 4, 0):
|
|
||||||
GEOHASH = 'ST_GeoHash'
|
|
||||||
BOUNDINGCIRCLE = 'ST_MinimumBoundingCircle'
|
|
||||||
self.geometry_functions['contains_properly'] = PostGISFunction(prefix, 'ContainsProperly')
|
|
||||||
else:
|
|
||||||
GEOHASH, BOUNDINGCIRCLE = False, False
|
|
||||||
|
|
||||||
# Geography type support added in 1.5.
|
|
||||||
if self.spatial_version >= (1, 5, 0):
|
|
||||||
self.geography = True
|
|
||||||
# Only a subset of the operators and functions are available
|
# Only a subset of the operators and functions are available
|
||||||
# for the geography type.
|
# for the geography type.
|
||||||
self.geography_functions = self.distance_functions.copy()
|
self.geography_functions = self.distance_functions.copy()
|
||||||
|
@ -201,7 +186,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.gis_terms.update(self.geometry_functions)
|
self.gis_terms.update(self.geometry_functions)
|
||||||
|
|
||||||
self.area = prefix + 'Area'
|
self.area = prefix + 'Area'
|
||||||
self.bounding_circle = BOUNDINGCIRCLE
|
self.bounding_circle = prefix + 'MinimumBoundingCircle'
|
||||||
self.centroid = prefix + 'Centroid'
|
self.centroid = prefix + 'Centroid'
|
||||||
self.collect = prefix + 'Collect'
|
self.collect = prefix + 'Collect'
|
||||||
self.difference = prefix + 'Difference'
|
self.difference = prefix + 'Difference'
|
||||||
|
@ -211,8 +196,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.envelope = prefix + 'Envelope'
|
self.envelope = prefix + 'Envelope'
|
||||||
self.extent = prefix + 'Extent'
|
self.extent = prefix + 'Extent'
|
||||||
self.force_rhr = prefix + 'ForceRHR'
|
self.force_rhr = prefix + 'ForceRHR'
|
||||||
self.geohash = GEOHASH
|
self.geohash = prefix + 'GeoHash'
|
||||||
self.geojson = GEOJSON
|
self.geojson = prefix + 'AsGeoJson'
|
||||||
self.gml = prefix + 'AsGML'
|
self.gml = prefix + 'AsGML'
|
||||||
self.intersection = prefix + 'Intersection'
|
self.intersection = prefix + 'Intersection'
|
||||||
self.kml = prefix + 'AsKML'
|
self.kml = prefix + 'AsKML'
|
||||||
|
@ -261,7 +246,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
except ProgrammingError:
|
except ProgrammingError:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
'Cannot determine PostGIS version for database "%s". '
|
'Cannot determine PostGIS version for database "%s". '
|
||||||
'GeoDjango requires at least PostGIS version 1.3. '
|
'GeoDjango requires at least PostGIS version 1.5. '
|
||||||
'Was the database created from a spatial database '
|
'Was the database created from a spatial database '
|
||||||
'template?' % self.connection.settings_dict['NAME']
|
'template?' % self.connection.settings_dict['NAME']
|
||||||
)
|
)
|
||||||
|
@ -315,12 +300,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
has been specified to be of geography type instead.
|
has been specified to be of geography type instead.
|
||||||
"""
|
"""
|
||||||
if f.geography:
|
if f.geography:
|
||||||
if not self.geography:
|
|
||||||
raise NotImplementedError('PostGIS 1.5 required for geography column support.')
|
|
||||||
|
|
||||||
if f.srid != 4326:
|
if f.srid != 4326:
|
||||||
raise NotImplementedError('PostGIS 1.5 supports geography columns '
|
raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')
|
||||||
'only with an SRID of 4326.')
|
|
||||||
|
|
||||||
return 'geography(%s,%d)' % (f.geom_type, f.srid)
|
return 'geography(%s,%d)' % (f.geom_type, f.srid)
|
||||||
elif self.geometry:
|
elif self.geometry:
|
||||||
|
@ -352,7 +333,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
|
|
||||||
# Shorthand boolean flags.
|
# Shorthand boolean flags.
|
||||||
geodetic = f.geodetic(self.connection)
|
geodetic = f.geodetic(self.connection)
|
||||||
geography = f.geography and self.geography
|
geography = f.geography
|
||||||
|
|
||||||
if isinstance(value, Distance):
|
if isinstance(value, Distance):
|
||||||
if geography:
|
if geography:
|
||||||
|
@ -525,15 +506,6 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
op = op(self.geom_func_prefix, value[1])
|
op = op(self.geom_func_prefix, value[1])
|
||||||
elif lookup_type in self.distance_functions and lookup_type != 'dwithin':
|
elif lookup_type in self.distance_functions and lookup_type != 'dwithin':
|
||||||
if not field.geography and field.geodetic(self.connection):
|
if not field.geography and field.geodetic(self.connection):
|
||||||
# Geodetic distances are only available from Points to
|
|
||||||
# PointFields on PostGIS 1.4 and below.
|
|
||||||
if not self.connection.ops.geography:
|
|
||||||
if field.geom_type != 'POINT':
|
|
||||||
raise ValueError('PostGIS spherical operations are only valid on PointFields.')
|
|
||||||
|
|
||||||
if str(geom.geom_type) != 'Point':
|
|
||||||
raise ValueError('PostGIS geometry distance parameter is required to be of type Point.')
|
|
||||||
|
|
||||||
# Setting up the geodetic operation appropriately.
|
# Setting up the geodetic operation appropriately.
|
||||||
if nparams == 3 and value[2] == 'spheroid':
|
if nparams == 3 and value[2] == 'spheroid':
|
||||||
op = op['spheroid']
|
op = op['spheroid']
|
||||||
|
|
|
@ -151,9 +151,6 @@ class GeoQuerySet(QuerySet):
|
||||||
if not isinstance(precision, six.integer_types):
|
if not isinstance(precision, six.integer_types):
|
||||||
raise TypeError('Precision keyword must be set with an integer.')
|
raise TypeError('Precision keyword must be set with an integer.')
|
||||||
|
|
||||||
# Setting the options flag -- which depends on which version of
|
|
||||||
# PostGIS we're using. SpatiaLite only uses the first group of options.
|
|
||||||
if backend.spatial_version >= (1, 4, 0):
|
|
||||||
options = 0
|
options = 0
|
||||||
if crs and bbox:
|
if crs and bbox:
|
||||||
options = 3
|
options = 3
|
||||||
|
@ -161,14 +158,6 @@ class GeoQuerySet(QuerySet):
|
||||||
options = 1
|
options = 1
|
||||||
elif crs:
|
elif crs:
|
||||||
options = 2
|
options = 2
|
||||||
else:
|
|
||||||
options = 0
|
|
||||||
if crs and bbox:
|
|
||||||
options = 3
|
|
||||||
elif crs:
|
|
||||||
options = 1
|
|
||||||
elif bbox:
|
|
||||||
options = 2
|
|
||||||
s = {'desc': 'GeoJSON',
|
s = {'desc': 'GeoJSON',
|
||||||
'procedure_args': {'precision': precision, 'options': options},
|
'procedure_args': {'precision': precision, 'options': options},
|
||||||
'procedure_fmt': '%(geo_col)s,%(precision)s,%(options)s',
|
'procedure_fmt': '%(geo_col)s,%(precision)s,%(options)s',
|
||||||
|
@ -197,12 +186,7 @@ class GeoQuerySet(QuerySet):
|
||||||
backend = connections[self.db].ops
|
backend = connections[self.db].ops
|
||||||
s = {'desc': 'GML', 'procedure_args': {'precision': precision}}
|
s = {'desc': 'GML', 'procedure_args': {'precision': precision}}
|
||||||
if backend.postgis:
|
if backend.postgis:
|
||||||
# PostGIS AsGML() aggregate function parameter order depends on the
|
|
||||||
# version -- uggh.
|
|
||||||
if backend.spatial_version > (1, 3, 1):
|
|
||||||
s['procedure_fmt'] = '%(version)s,%(geo_col)s,%(precision)s'
|
s['procedure_fmt'] = '%(version)s,%(geo_col)s,%(precision)s'
|
||||||
else:
|
|
||||||
s['procedure_fmt'] = '%(geo_col)s,%(precision)s,%(version)s'
|
|
||||||
s['procedure_args'] = {'precision': precision, 'version': version}
|
s['procedure_args'] = {'precision': precision, 'version': version}
|
||||||
|
|
||||||
return self._spatial_attribute('gml', s, **kwargs)
|
return self._spatial_attribute('gml', s, **kwargs)
|
||||||
|
|
|
@ -147,7 +147,7 @@ class DistanceTest(TestCase):
|
||||||
# Testing geodetic distance calculation with a non-point geometry
|
# Testing geodetic distance calculation with a non-point geometry
|
||||||
# (a LineString of Wollongong and Shellharbour coords).
|
# (a LineString of Wollongong and Shellharbour coords).
|
||||||
ls = LineString(((150.902, -34.4245), (150.87, -34.5789)))
|
ls = LineString(((150.902, -34.4245), (150.87, -34.5789)))
|
||||||
if oracle or connection.ops.geography:
|
if oracle or postgis:
|
||||||
# Reference query:
|
# 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;
|
# 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,
|
distances = [1120954.92533513, 140575.720018241, 640396.662906304,
|
||||||
|
@ -157,11 +157,6 @@ class DistanceTest(TestCase):
|
||||||
for city, distance in zip(qs, distances):
|
for city, distance in zip(qs, distances):
|
||||||
# Testing equivalence to within a meter.
|
# Testing equivalence to within a meter.
|
||||||
self.assertAlmostEqual(distance, city.distance.m, 0)
|
self.assertAlmostEqual(distance, city.distance.m, 0)
|
||||||
else:
|
|
||||||
# PostGIS 1.4 and below is limited to disance queries only
|
|
||||||
# to/from point geometries, check for raising of ValueError.
|
|
||||||
self.assertRaises(ValueError, AustraliaCity.objects.distance, ls)
|
|
||||||
self.assertRaises(ValueError, AustraliaCity.objects.distance, ls.wkt)
|
|
||||||
|
|
||||||
# Got the reference distances using the raw SQL statements:
|
# Got the reference distances using the raw SQL statements:
|
||||||
# SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11));
|
# SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11));
|
||||||
|
@ -204,11 +199,6 @@ class DistanceTest(TestCase):
|
||||||
"""
|
"""
|
||||||
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
|
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
|
||||||
"""
|
"""
|
||||||
# Normally you can't compute distances from a geometry field
|
|
||||||
# that is not a PointField (on PostGIS 1.4 and below).
|
|
||||||
if not connection.ops.geography:
|
|
||||||
self.assertRaises(ValueError, CensusZipcode.objects.distance, self.stx_pnt)
|
|
||||||
|
|
||||||
# We'll be using a Polygon (created by buffering the centroid
|
# We'll be using a Polygon (created by buffering the centroid
|
||||||
# of 77005 to 100m) -- which aren't allowed in geographic distance
|
# of 77005 to 100m) -- which aren't allowed in geographic distance
|
||||||
# queries normally, however our field has been transformed to
|
# queries normally, however our field has been transformed to
|
||||||
|
@ -272,15 +262,15 @@ class DistanceTest(TestCase):
|
||||||
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)))
|
dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100)))
|
||||||
|
|
||||||
if oracle or connection.ops.geography:
|
if oracle or postgis:
|
||||||
# Oracle and PostGIS 1.5 can do distance lookups on arbitrary geometries.
|
# Oracle and PostGIS can do distance lookups on arbitrary geometries.
|
||||||
self.assertEqual(9, dist_qs.count())
|
self.assertEqual(9, dist_qs.count())
|
||||||
self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
|
self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
|
||||||
'Melbourne', 'Mittagong', 'Shellharbour',
|
'Melbourne', 'Mittagong', 'Shellharbour',
|
||||||
'Sydney', 'Thirroul', 'Wollongong'],
|
'Sydney', 'Thirroul', 'Wollongong'],
|
||||||
self.get_names(dist_qs))
|
self.get_names(dist_qs))
|
||||||
else:
|
else:
|
||||||
# PostGIS 1.4 and below only allows geodetic distance queries (utilizing
|
# spatialite only allow geodetic distance queries (utilizing
|
||||||
# ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields
|
# ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields
|
||||||
# on geometry columns.
|
# on geometry columns.
|
||||||
self.assertRaises(ValueError, dist_qs.count)
|
self.assertRaises(ValueError, dist_qs.count)
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Geo3DTest(TestCase):
|
||||||
available within GeoDjango. For more information, see the PostGIS docs
|
available within GeoDjango. For more information, see the PostGIS docs
|
||||||
on the routines that support 3D:
|
on the routines that support 3D:
|
||||||
|
|
||||||
http://postgis.refractions.net/documentation/manual-1.4/ch08.html#PostGIS_3D_Functions
|
http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_3D_Functions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _load_interstate_data(self):
|
def _load_interstate_data(self):
|
||||||
|
|
|
@ -507,11 +507,7 @@ class GeoQuerySetTest(TestCase):
|
||||||
houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}'
|
houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}'
|
||||||
victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}'
|
victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}'
|
||||||
chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
|
chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
|
||||||
if postgis and connection.ops.spatial_version < (1, 4, 0):
|
if spatialite:
|
||||||
pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}'
|
|
||||||
houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}'
|
|
||||||
victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}'
|
|
||||||
elif spatialite:
|
|
||||||
victoria_json = '{"type":"Point","bbox":[-123.305196,48.462611,-123.305196,48.462611],"coordinates":[-123.305196,48.462611]}'
|
victoria_json = '{"type":"Point","bbox":[-123.305196,48.462611,-123.305196,48.462611],"coordinates":[-123.305196,48.462611]}'
|
||||||
|
|
||||||
# Precision argument should only be an integer
|
# Precision argument should only be an integer
|
||||||
|
@ -560,10 +556,8 @@ class GeoQuerySetTest(TestCase):
|
||||||
for ptown in [ptown1, ptown2]:
|
for ptown in [ptown1, ptown2]:
|
||||||
self.assertTrue(gml_regex.match(ptown.gml))
|
self.assertTrue(gml_regex.match(ptown.gml))
|
||||||
|
|
||||||
# PostGIS < 1.5 doesn't include dimension im GMLv3 output.
|
if postgis:
|
||||||
if postgis and connection.ops.spatial_version >= (1, 5, 0):
|
self.assertIn('<gml:pos srsDimension="2">', City.objects.gml(version=3).get(name='Pueblo').gml)
|
||||||
self.assertIn('<gml:pos srsDimension="2">',
|
|
||||||
City.objects.gml(version=3).get(name='Pueblo').gml)
|
|
||||||
|
|
||||||
def test_kml(self):
|
def test_kml(self):
|
||||||
"Testing KML output from the database using GeoQuerySet.kml()."
|
"Testing KML output from the database using GeoQuerySet.kml()."
|
||||||
|
@ -577,18 +571,11 @@ class GeoQuerySetTest(TestCase):
|
||||||
qs = City.objects.all()
|
qs = City.objects.all()
|
||||||
self.assertRaises(TypeError, qs.kml, 'name')
|
self.assertRaises(TypeError, qs.kml, 'name')
|
||||||
|
|
||||||
# The reference KML depends on the version of PostGIS used
|
|
||||||
# (the output stopped including altitude in 1.3.3).
|
|
||||||
if connection.ops.spatial_version >= (1, 3, 3):
|
|
||||||
ref_kml = '<Point><coordinates>-104.609252,38.255001</coordinates></Point>'
|
|
||||||
else:
|
|
||||||
ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>'
|
|
||||||
|
|
||||||
# Ensuring the KML is as expected.
|
# Ensuring the KML is as expected.
|
||||||
ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo')
|
ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo')
|
||||||
ptown2 = City.objects.kml(precision=9).get(name='Pueblo')
|
ptown2 = City.objects.kml(precision=9).get(name='Pueblo')
|
||||||
for ptown in [ptown1, ptown2]:
|
for ptown in [ptown1, ptown2]:
|
||||||
self.assertEqual(ref_kml, ptown.kml)
|
self.assertEqual('<Point><coordinates>-104.609252,38.255001</coordinates></Point>', ptown.kml)
|
||||||
|
|
||||||
# Only PostGIS has support for the MakeLine aggregate.
|
# Only PostGIS has support for the MakeLine aggregate.
|
||||||
@no_mysql
|
@no_mysql
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
Tests for geography support in PostGIS 1.5+
|
Tests for geography support in PostGIS
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ import re
|
||||||
|
|
||||||
# This reg-exp is intentionally fairly flexible here.
|
# This reg-exp is intentionally fairly flexible here.
|
||||||
# Needs to be able to handle stuff like:
|
# Needs to be able to handle stuff like:
|
||||||
# PostgreSQL 8.3.6
|
# PostgreSQL #.#.#
|
||||||
# EnterpriseDB 8.3
|
# EnterpriseDB #.#
|
||||||
# PostgreSQL 8.3 beta4
|
# PostgreSQL #.# beta#
|
||||||
# PostgreSQL 8.4beta1
|
# PostgreSQL #.#beta#
|
||||||
VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?')
|
VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?')
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ def get_version(connection):
|
||||||
PQServerVersion()/``server_version`` connection attribute (available in
|
PQServerVersion()/``server_version`` connection attribute (available in
|
||||||
newer psycopg2 versions.)
|
newer psycopg2 versions.)
|
||||||
|
|
||||||
For example, 80304 for 8.3.4. The last two digits will be 00 in the case of
|
For example, 90304 for 9.3.4. The last two digits will be 00 in the case of
|
||||||
releases (e.g., 80400 for 'PostgreSQL 8.4') or in the case of beta and
|
releases (e.g., 90400 for 'PostgreSQL 9.4') or in the case of beta and
|
||||||
prereleases (e.g. 90100 for 'PostgreSQL 9.1beta2').
|
prereleases (e.g. 90100 for 'PostgreSQL 9.1beta2').
|
||||||
|
|
||||||
PQServerVersion()/``server_version`` doesn't execute a query so try that
|
PQServerVersion()/``server_version`` doesn't execute a query so try that
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
POSTGIS_SQL_PATH=`pg_config --sharedir`
|
|
||||||
createdb -E UTF8 template_postgis # Create the template spatial database.
|
|
||||||
createlang -d template_postgis plpgsql # Adding PLPGSQL language support.
|
|
||||||
psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';"
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/lwpostgis.sql # Loading the PostGIS SQL routines
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables.
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib
|
|
||||||
createdb -E UTF8 template_postgis # Create the template spatial database.
|
|
||||||
createlang -d template_postgis plpgsql # Adding PLPGSQL language support.
|
|
||||||
psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';"
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/postgis.sql # Loading the PostGIS SQL routines
|
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables.
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
|
|
@ -1,26 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
GEOGRAPHY=0
|
|
||||||
POSTGIS_SQL=postgis.sql
|
POSTGIS_SQL=postgis.sql
|
||||||
|
|
||||||
# For Ubuntu 10.04
|
# For Ubuntu 11.10, 12.04 / Linux Mint 12 (with PostGIS 1.5)
|
||||||
if [ -d "/usr/share/postgresql/8.4/contrib" ]
|
|
||||||
then
|
|
||||||
POSTGIS_SQL_PATH=/usr/share/postgresql/8.4/contrib
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Ubuntu 10.10 (with PostGIS 1.5)
|
|
||||||
if [ -d "/usr/share/postgresql/8.4/contrib/postgis-1.5" ]
|
|
||||||
then
|
|
||||||
POSTGIS_SQL_PATH=/usr/share/postgresql/8.4/contrib/postgis-1.5
|
|
||||||
GEOGRAPHY=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Ubuntu 11.10 / Linux Mint 12 (with PostGIS 1.5)
|
|
||||||
if [ -d "/usr/share/postgresql/9.1/contrib/postgis-1.5" ]
|
if [ -d "/usr/share/postgresql/9.1/contrib/postgis-1.5" ]
|
||||||
then
|
then
|
||||||
POSTGIS_SQL_PATH=/usr/share/postgresql/9.1/contrib/postgis-1.5
|
POSTGIS_SQL_PATH=/usr/share/postgresql/9.1/contrib/postgis-1.5
|
||||||
GEOGRAPHY=1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
createdb -E UTF8 template_postgis && \
|
createdb -E UTF8 template_postgis && \
|
||||||
|
@ -30,8 +15,4 @@ psql -d template_postgis -f $POSTGIS_SQL_PATH/$POSTGIS_SQL && \
|
||||||
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql && \
|
psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql && \
|
||||||
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" && \
|
psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" && \
|
||||||
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
|
||||||
|
|
||||||
if [ $GEOGRAPHY -eq 1 ]
|
|
||||||
then
|
|
||||||
psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"
|
psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"
|
||||||
fi
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ Program Description Required
|
||||||
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.8, 4.7, 4.6, 4.5, 4.4
|
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.8, 4.7, 4.6, 4.5, 4.4
|
||||||
:ref:`GDAL <ref-gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 1.10, 1.9, 1.8, 1.7
|
:ref:`GDAL <ref-gdal>` Geospatial Data Abstraction Library Yes (SQLite only) 1.10, 1.9, 1.8, 1.7
|
||||||
:ref:`GeoIP <ref-geoip>` IP-based geolocation library No 1.4
|
:ref:`GeoIP <ref-geoip>` IP-based geolocation library No 1.4
|
||||||
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.1, 2.0, 1.5, 1.4, 1.3
|
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.1, 2.0, 1.5
|
||||||
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.1, 4.0, 3.0, 2.4
|
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.1, 4.0, 3.0, 2.4
|
||||||
======================== ==================================== ================================ ==========================
|
======================== ==================================== ================================ ==========================
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@ totally fine with GeoDjango. Your mileage may vary.
|
||||||
GDAL 1.9.0 2012-01-03
|
GDAL 1.9.0 2012-01-03
|
||||||
GDAL 1.10.0 2013-04-29
|
GDAL 1.10.0 2013-04-29
|
||||||
GDAL 1.11.0 2014-04-25 # To be tested!
|
GDAL 1.11.0 2014-04-25 # To be tested!
|
||||||
PostGIS 1.3.0 2007-08-09
|
|
||||||
PostGIS 1.4.0 2009-07-24
|
|
||||||
PostGIS 1.5.0 2010-02-04
|
PostGIS 1.5.0 2010-02-04
|
||||||
PostGIS 2.0.0 2012-04-03
|
PostGIS 2.0.0 2012-04-03
|
||||||
PostGIS 2.1.0 2013-08-17
|
PostGIS 2.1.0 2013-08-17
|
||||||
|
|
|
@ -61,7 +61,7 @@ supported versions, and any notes for each of the supported database backends:
|
||||||
================== ============================== ================== =========================================
|
================== ============================== ================== =========================================
|
||||||
Database Library Requirements Supported Versions Notes
|
Database Library Requirements Supported Versions Notes
|
||||||
================== ============================== ================== =========================================
|
================== ============================== ================== =========================================
|
||||||
PostgreSQL GEOS, PROJ.4, PostGIS 8.4+ Requires PostGIS.
|
PostgreSQL GEOS, PROJ.4, PostGIS 9.0+ Requires PostGIS.
|
||||||
MySQL GEOS 5.x Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`.
|
MySQL GEOS 5.x Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`.
|
||||||
Oracle GEOS 10.2, 11 XE not supported; not tested with 9.
|
Oracle GEOS 10.2, 11 XE not supported; not tested with 9.
|
||||||
SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 2.3+, pysqlite2 2.5+
|
SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 2.3+, pysqlite2 2.5+
|
||||||
|
@ -107,8 +107,7 @@ Add Google projection to ``spatial_ref_sys`` table
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
If you're running PostGIS 1.4 or above, you can skip this step. The entry
|
If you're running GDAL 1.7 or above (most users), you can skip this step.
|
||||||
is already included in the default ``spatial_ref_sys`` table.
|
|
||||||
|
|
||||||
In order to conduct database transformations to the so-called "Google"
|
In order to conduct database transformations to the so-called "Google"
|
||||||
projection (a spherical mercator projection used by Google Maps),
|
projection (a spherical mercator projection used by Google Maps),
|
||||||
|
@ -361,7 +360,7 @@ the `Apple Developer Tools`_ are required.
|
||||||
|
|
||||||
Summary::
|
Summary::
|
||||||
|
|
||||||
$ sudo port install postgresql83-server
|
$ sudo port install postgresql93-server
|
||||||
$ sudo port install geos
|
$ sudo port install geos
|
||||||
$ sudo port install proj
|
$ sudo port install proj
|
||||||
$ sudo port install postgis
|
$ sudo port install postgis
|
||||||
|
@ -373,12 +372,12 @@ Summary::
|
||||||
You will also have to modify the ``PATH`` in your ``.profile`` so
|
You will also have to modify the ``PATH`` in your ``.profile`` so
|
||||||
that the MacPorts programs are accessible from the command-line::
|
that the MacPorts programs are accessible from the command-line::
|
||||||
|
|
||||||
export PATH=/opt/local/bin:/opt/local/lib/postgresql83/bin
|
export PATH=/opt/local/bin:/opt/local/lib/postgresql93/bin
|
||||||
|
|
||||||
In addition, add the ``DYLD_FALLBACK_LIBRARY_PATH`` setting so that
|
In addition, add the ``DYLD_FALLBACK_LIBRARY_PATH`` setting so that
|
||||||
the libraries can be found by Python::
|
the libraries can be found by Python::
|
||||||
|
|
||||||
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql83
|
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql93
|
||||||
|
|
||||||
__ http://www.macports.org/
|
__ http://www.macports.org/
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,7 @@ user. For example, you can use the following to become the ``postgres`` user::
|
||||||
|
|
||||||
The location *and* name of the PostGIS SQL files (e.g., from
|
The location *and* name of the PostGIS SQL files (e.g., from
|
||||||
``POSTGIS_SQL_PATH`` below) depends on the version of PostGIS.
|
``POSTGIS_SQL_PATH`` below) depends on the version of PostGIS.
|
||||||
PostGIS versions 1.3 and below use ``<pg_sharedir>/contrib/lwpostgis.sql``;
|
Version 1.5 uses ``<sharedir>/contrib/postgis-1.5/postgis.sql``.
|
||||||
whereas version 1.4 uses ``<sharedir>/contrib/postgis.sql`` and
|
|
||||||
version 1.5 uses ``<sharedir>/contrib/postgis-1.5/postgis.sql``.
|
|
||||||
|
|
||||||
To complicate matters, Debian/Ubuntu distributions have their own separate
|
To complicate matters, Debian/Ubuntu distributions have their own separate
|
||||||
directory naming system that might change with time. In this case, use the
|
directory naming system that might change with time. In this case, use the
|
||||||
|
@ -128,8 +126,6 @@ the following scripts are available:
|
||||||
=============== =============================================
|
=============== =============================================
|
||||||
PostGIS version Bash shell script
|
PostGIS version Bash shell script
|
||||||
=============== =============================================
|
=============== =============================================
|
||||||
1.3 :download:`create_template_postgis-1.3.sh`
|
|
||||||
1.4 :download:`create_template_postgis-1.4.sh`
|
|
||||||
1.5 :download:`create_template_postgis-1.5.sh`
|
1.5 :download:`create_template_postgis-1.5.sh`
|
||||||
Debian/Ubuntu :download:`create_template_postgis-debian.sh`
|
Debian/Ubuntu :download:`create_template_postgis-debian.sh`
|
||||||
=============== =============================================
|
=============== =============================================
|
||||||
|
|
|
@ -784,13 +784,15 @@ available with the :class:`~django.contrib.gis.admin.GeoModelAdmin`
|
||||||
|
|
||||||
First, there are some important requirements:
|
First, there are some important requirements:
|
||||||
|
|
||||||
* :class:`~django.contrib.gis.admin.OSMGeoAdmin` requires that the
|
* :class:`~django.contrib.gis.admin.OSMGeoAdmin` requires that
|
||||||
:ref:`spherical mercator projection be added <addgoogleprojection>`
|
:ref:`GDAL <ref-gdal>` is installed. If you are running GDAL 1.6 (uncommon)
|
||||||
to the ``spatial_ref_sys`` table (PostGIS 1.3 and below, only).
|
you will also need to add the :ref:`spherical mercator projection
|
||||||
|
<addgoogleprojection>` to the ``spatial_ref_sys`` table.
|
||||||
|
|
||||||
* The PROJ.4 datum shifting files must be installed (see the
|
* The PROJ.4 datum shifting files must be installed (see the
|
||||||
:ref:`PROJ.4 installation instructions <proj4>` for more details).
|
:ref:`PROJ.4 installation instructions <proj4>` for more details).
|
||||||
|
|
||||||
If you meet these requirements, then just substitute the ``OSMGeoAdmin``
|
If you meet this requirement, then just substitute the ``OSMGeoAdmin``
|
||||||
option class in your ``admin.py`` file::
|
option class in your ``admin.py`` file::
|
||||||
|
|
||||||
admin.site.register(WorldBorder, admin.OSMGeoAdmin)
|
admin.site.register(WorldBorder, admin.OSMGeoAdmin)
|
||||||
|
|
|
@ -92,7 +92,7 @@ below for information on how to set up your database correctly.
|
||||||
PostgreSQL notes
|
PostgreSQL notes
|
||||||
================
|
================
|
||||||
|
|
||||||
Django supports PostgreSQL 8.4 and higher.
|
Django supports PostgreSQL 9.0 and higher.
|
||||||
|
|
||||||
PostgreSQL connection settings
|
PostgreSQL connection settings
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
|
@ -397,6 +397,16 @@ affected models (or add ``max_length=75`` if you wish to keep the length on
|
||||||
your current fields). A migration for
|
your current fields). A migration for
|
||||||
:attr:`django.contrib.auth.models.User.email` is included.
|
:attr:`django.contrib.auth.models.User.email` is included.
|
||||||
|
|
||||||
|
Support for PostgreSQL versions older than 9.0
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The end of upstream support periods was reached in July 2014 for PostgreSQL 8.4.
|
||||||
|
As a consequence, Django 1.8 sets 9.0 as the minimum PostgreSQL version it
|
||||||
|
officially supports.
|
||||||
|
|
||||||
|
This also includes dropping support for PostGIS 1.3 and 1.4 as these versions
|
||||||
|
are not supported on versions of PostgreSQL later than 8.4.
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -152,12 +152,12 @@ class PostgreSQLTests(TestCase):
|
||||||
|
|
||||||
def test_parsing(self):
|
def test_parsing(self):
|
||||||
"""Test PostgreSQL version parsing from `SELECT version()` output"""
|
"""Test PostgreSQL version parsing from `SELECT version()` output"""
|
||||||
self.assert_parses("PostgreSQL 8.3 beta4", 80300)
|
self.assert_parses("PostgreSQL 9.3 beta4", 90300)
|
||||||
self.assert_parses("PostgreSQL 8.3", 80300)
|
self.assert_parses("PostgreSQL 9.3", 90300)
|
||||||
self.assert_parses("EnterpriseDB 8.3", 80300)
|
self.assert_parses("EnterpriseDB 9.3", 90300)
|
||||||
self.assert_parses("PostgreSQL 8.3.6", 80306)
|
self.assert_parses("PostgreSQL 9.3.6", 90306)
|
||||||
self.assert_parses("PostgreSQL 8.4beta1", 80400)
|
self.assert_parses("PostgreSQL 9.4beta1", 90400)
|
||||||
self.assert_parses("PostgreSQL 8.3.1 on i386-apple-darwin9.2.2, compiled by GCC i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5478)", 80301)
|
self.assert_parses("PostgreSQL 9.3.1 on i386-apple-darwin9.2.2, compiled by GCC i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5478)", 90301)
|
||||||
|
|
||||||
def test_version_detection(self):
|
def test_version_detection(self):
|
||||||
"""Test PostgreSQL version detection"""
|
"""Test PostgreSQL version detection"""
|
||||||
|
@ -169,7 +169,7 @@ class PostgreSQLTests(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
return ["PostgreSQL 8.3"]
|
return ["PostgreSQL 9.3"]
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
@ -184,7 +184,7 @@ class PostgreSQLTests(TestCase):
|
||||||
|
|
||||||
# psycopg2 < 2.0.12 code path
|
# psycopg2 < 2.0.12 code path
|
||||||
conn = OlderConnectionMock()
|
conn = OlderConnectionMock()
|
||||||
self.assertEqual(pg_version.get_version(conn), 80300)
|
self.assertEqual(pg_version.get_version(conn), 90300)
|
||||||
|
|
||||||
def test_connect_and_rollback(self):
|
def test_connect_and_rollback(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue