Commit a9bdce7e authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #23108 -- Dropped support for PostgreSQL 8.4 & PostGIS 1.3, 1.4.

Thanks Claude Paroz for the review.
parent 7ce4ef58
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -25,12 +25,13 @@ class PostGISIntrospection(DatabaseIntrospection):
        identification integers for the PostGIS geometry and/or
        geography types (if supported).
        """
        field_types = [('geometry', 'GeometryField')]
        if self.connection.ops.geography:
        field_types = [
            ('geometry', 'GeometryField'),
            # The value for the geography type is actually a tuple
            # to pass in the `geography=True` keyword to the field
            # definition.
            field_types.append(('geography', ('GeometryField', {'geography': True})))
            ('geography', ('GeometryField', {'geography': True})),
        ]
        postgis_types = {}

        # The OID integers associated with the geometry type may
@@ -79,7 +80,6 @@ class PostGISIntrospection(DatabaseIntrospection):
                if not row:
                    raise GeoIntrospectionError
            except GeoIntrospectionError:
                if self.connection.ops.geography:
                cursor.execute('SELECT "coord_dimension", "srid", "type" '
                               'FROM "geography_columns" '
                               'WHERE "f_table_name"=%s AND "f_geography_column"=%s',
+19 −47
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
    compiler_module = 'django.contrib.gis.db.models.sql.compiler'
    name = 'postgis'
    postgis = True
    geography = True
    geom_func_prefix = 'ST_'
    version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
    valid_aggregates = {'Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'}
@@ -140,6 +141,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
            'relate': (PostGISRelate, six.string_types),
            'coveredby': PostGISFunction(prefix, 'CoveredBy'),
            'covers': PostGISFunction(prefix, 'Covers'),
            'contains_properly': PostGISFunction(prefix, 'ContainsProperly'),
        }

        # Valid distance types and substitutions
@@ -162,23 +164,6 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
        # Adding the distance functions to the geometries lookup.
        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
        # for the geography type.
        self.geography_functions = self.distance_functions.copy()
@@ -201,7 +186,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
        self.gis_terms.update(self.geometry_functions)

        self.area = prefix + 'Area'
        self.bounding_circle = BOUNDINGCIRCLE
        self.bounding_circle = prefix + 'MinimumBoundingCircle'
        self.centroid = prefix + 'Centroid'
        self.collect = prefix + 'Collect'
        self.difference = prefix + 'Difference'
@@ -211,8 +196,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
        self.envelope = prefix + 'Envelope'
        self.extent = prefix + 'Extent'
        self.force_rhr = prefix + 'ForceRHR'
        self.geohash = GEOHASH
        self.geojson = GEOJSON
        self.geohash = prefix + 'GeoHash'
        self.geojson = prefix + 'AsGeoJson'
        self.gml = prefix + 'AsGML'
        self.intersection = prefix + 'Intersection'
        self.kml = prefix + 'AsKML'
@@ -261,7 +246,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
            except ProgrammingError:
                raise ImproperlyConfigured(
                    '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 '
                    'template?' % self.connection.settings_dict['NAME']
                )
@@ -315,12 +300,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
        has been specified to be of geography type instead.
        """
        if f.geography:
            if not self.geography:
                raise NotImplementedError('PostGIS 1.5 required for geography column support.')

            if f.srid != 4326:
                raise NotImplementedError('PostGIS 1.5 supports geography columns '
                                          'only with an SRID of 4326.')
                raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')

            return 'geography(%s,%d)' % (f.geom_type, f.srid)
        elif self.geometry:
@@ -352,7 +333,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):

        # Shorthand boolean flags.
        geodetic = f.geodetic(self.connection)
        geography = f.geography and self.geography
        geography = f.geography

        if isinstance(value, Distance):
            if geography:
@@ -525,15 +506,6 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
                    op = op(self.geom_func_prefix, value[1])
                elif lookup_type in self.distance_functions and lookup_type != 'dwithin':
                    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.
                        if nparams == 3 and value[2] == 'spheroid':
                            op = op['spheroid']
+8 −24
Original line number Diff line number Diff line
@@ -151,9 +151,6 @@ class GeoQuerySet(QuerySet):
        if not isinstance(precision, six.integer_types):
            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
        if crs and bbox:
            options = 3
@@ -161,14 +158,6 @@ class GeoQuerySet(QuerySet):
            options = 1
        elif crs:
            options = 2
        else:
            options = 0
            if crs and bbox:
                options = 3
            elif crs:
                options = 1
            elif bbox:
                options = 2
        s = {'desc': 'GeoJSON',
             'procedure_args': {'precision': precision, 'options': options},
             'procedure_fmt': '%(geo_col)s,%(precision)s,%(options)s',
@@ -197,12 +186,7 @@ class GeoQuerySet(QuerySet):
        backend = connections[self.db].ops
        s = {'desc': 'GML', 'procedure_args': {'precision': precision}}
        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'
            else:
                s['procedure_fmt'] = '%(geo_col)s,%(precision)s,%(version)s'
            s['procedure_args'] = {'precision': precision, 'version': version}

        return self._spatial_attribute('gml', s, **kwargs)
+4 −14
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ class DistanceTest(TestCase):
        # 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 connection.ops.geography:
        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,
@@ -157,11 +157,6 @@ class DistanceTest(TestCase):
            for city, distance in zip(qs, distances):
                # Testing equivalence to within a meter.
                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:
        #  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.
        """
        # 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
        # of 77005 to 100m) -- which aren't allowed in geographic distance
        # 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)
        dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100)))

        if oracle or connection.ops.geography:
            # Oracle and PostGIS 1.5 can do distance lookups on arbitrary geometries.
        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:
            # 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
            # on geometry columns.
            self.assertRaises(ValueError, dist_qs.count)
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ class Geo3DTest(TestCase):
    available within GeoDjango.  For more information, see the PostGIS docs
    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):
Loading