Commit a7d964ab authored by Claude Paroz's avatar Claude Paroz
Browse files

Replaced no_spatialite by connection features

Refs #22632. Thanks Tim Graham for the review.
parent 46c7707e
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -11,8 +11,56 @@ from django.utils.encoding import python_2_unicode_compatible

class BaseSpatialFeatures(object):
    gis_enabled = True

    # Does the database contain a SpatialRefSys model to store SRID information?
    has_spatialrefsys_table = True

    # Can the `distance` GeoQuerySet method be applied on geodetic coordinate systems?
    supports_distance_geodetic = True
    # Does the database supports `left` and `right` lookups?
    supports_left_right_lookups = False
    # Is the database able to count vertices on polygons (with `num_points`)?
    supports_num_points_poly = True

    # The following properties indicate if the database GIS extensions support
    # certain methods (dwithin, force_rhr, geohash, ...)
    @property
    def has_dwithin_lookup(self):
        return 'dwithin' in self.connection.ops.distance_functions

    @property
    def has_force_rhr_method(self):
        return bool(self.connection.ops.force_rhr)

    @property
    def has_geohash_method(self):
        return bool(self.connection.ops.geohash)

    @property
    def has_make_line_method(self):
        return bool(self.connection.ops.make_line)

    @property
    def has_perimeter_method(self):
        return bool(self.connection.ops.perimeter)

    @property
    def has_reverse_method(self):
        return bool(self.connection.ops.reverse)

    @property
    def has_snap_to_grid_method(self):
        return bool(self.connection.ops.snap_to_grid)

    # Specifies whether the Collect and Extent aggregates are supported by the database
    @property
    def supports_collect_aggr(self):
        return 'Collect' in self.connection.ops.valid_aggregates

    @property
    def supports_extent_aggr(self):
        return 'Extent' in self.connection.ops.valid_aggregates


class BaseSpatialOperations(object):
    """
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ from django.contrib.gis.db.backends.mysql.operations import MySQLOperations

class DatabaseFeatures(BaseSpatialFeatures, MySQLDatabaseFeatures):
    has_spatialrefsys_table = False
    supports_num_points_poly = False


class DatabaseWrapper(MySQLDatabaseWrapper):
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ from django.contrib.gis.db.backends.postgis.schema import PostGISSchemaEditor


class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
    pass
    supports_left_right_lookups = True


class DatabaseWrapper(Psycopg2DatabaseWrapper):
+3 −1
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@ from django.utils import six


class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures):
    pass
    supports_distance_geodetic = False
    # SpatiaLite can only count vertices in LineStrings
    supports_num_points_poly = False


class DatabaseWrapper(SQLiteDatabaseWrapper):
+18 −1
Original line number Diff line number Diff line
@@ -65,17 +65,25 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
    name = 'spatialite'
    spatialite = True
    version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
    valid_aggregates = {'Extent', 'Union'}

    @property
    def valid_aggregates(self):
        if self.spatial_version >= 3:
            return {'Collect', 'Extent', 'Union'}
        else:
            return {'Union'}

    Adapter = SpatiaLiteAdapter
    Adaptor = Adapter  # Backwards-compatibility alias.

    area = 'Area'
    centroid = 'Centroid'
    collect = 'Collect'
    contained = 'MbrWithin'
    difference = 'Difference'
    distance = 'Distance'
    envelope = 'Envelope'
    extent = 'Extent'
    intersection = 'Intersection'
    length = 'GLength'  # OpenGis defines Length, but this conflicts with an SQLite reserved keyword
    num_geom = 'NumGeometries'
@@ -180,6 +188,15 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
        agg_name = aggregate.__class__.__name__
        return agg_name in self.valid_aggregates

    def convert_extent(self, box):
        """
        Convert the polygon data received from Spatialite to min/max values.
        """
        shell = Geometry(box).shell
        xmin, ymin = shell[0][:2]
        xmax, ymax = shell[2][:2]
        return (xmin, ymin, xmax, ymax)

    def convert_geom(self, wkt, geo_field):
        """
        Converts geometry WKT returned from a SpatiaLite aggregate.
Loading