Commit 7127eb28 authored by Sergey Fedoseev's avatar Sergey Fedoseev Committed by Claude Paroz
Browse files

Fixed #25659 -- Added missing support for MySQL 5.6.1 GIS functions

Added support for ST_Difference/ST_Intersection/ST_SymDifference.
parent b78226cd
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -34,8 +34,11 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
    }

    function_names = {
        'Difference': 'ST_Difference',
        'Distance': 'ST_Distance',
        'Intersection': 'ST_Intersection',
        'Length': 'GLength',
        'SymDifference': 'ST_SymDifference',
        'Union': 'ST_Union',
    }

@@ -48,12 +51,12 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
    def unsupported_functions(self):
        unsupported = {
            'AsGeoJSON', 'AsGML', 'AsKML', 'AsSVG', 'BoundingCircle',
            'Difference', 'ForceRHR', 'GeoHash', 'Intersection', 'MemSize',
            'ForceRHR', 'GeoHash', 'MemSize',
            'Perimeter', 'PointOnSurface', 'Reverse', 'Scale', 'SnapToGrid',
            'SymDifference', 'Transform', 'Translate',
            'Transform', 'Translate',
        }
        if self.connection.mysql_version < (5, 6, 1):
            unsupported.update({'Distance', 'Union'})
            unsupported.update({'Difference', 'Distance', 'Intersection', 'SymDifference', 'Union'})
        return unsupported

    def geo_db_type(self, f):
+3 −3
Original line number Diff line number Diff line
@@ -312,12 +312,12 @@ Function PostGIS Oracle MySQL SpatiaLite
:class:`AsSVG`                        X                             X
:class:`BoundingCircle`               X
:class:`Centroid`                     X        X       X            X
:class:`Difference`                   X        X                    X
:class:`Difference`                   X        X       X (≥ 5.6.1)  X
:class:`Distance`                     X        X       X (≥ 5.6.1)  X
:class:`Envelope`                     X                X            X
:class:`ForceRHR`                     X
:class:`GeoHash`                      X
:class:`Intersection`                 X        X                    X
:class:`Intersection`                 X        X       X (≥ 5.6.1)  X
:class:`Length`                       X        X       X            X
:class:`MemSize`                      X
:class:`NumGeometries`                X        X       X            X
@@ -327,7 +327,7 @@ Function PostGIS Oracle MySQL SpatiaLite
:class:`Reverse`                      X        X                    X (≥ 4.0)
:class:`Scale`                        X                             X
:class:`SnapToGrid`                   X                             X (≥ 3.1)
:class:`SymDifference`                X        X                    X
:class:`SymDifference`                X        X       X (≥ 5.6.1)  X
:class:`Transform`                    X        X                    X
:class:`Translate`                    X                             X
:class:`Union`                        X        X       X (≥ 5.6.1)  X
+10 −15
Original line number Diff line number Diff line
@@ -169,9 +169,9 @@ class GISFunctionsTests(TestCase):
            qs = qs.exclude(name='Texas')

        for c in qs:
            self.assertEqual(c.mpoly.difference(geom), c.diff)
            self.assertTrue(c.mpoly.difference(geom).equals(c.diff))

    @skipUnlessDBFeature("has_Difference_function")
    @skipUnlessDBFeature("has_Difference_function", "has_Transform_function")
    def test_difference_mixed_srid(self):
        """Testing with mixed SRID (Country has default 4326)."""
        geom = Point(556597.4, 2632018.6, srid=3857)  # Spherical mercator
@@ -180,7 +180,7 @@ class GISFunctionsTests(TestCase):
        if spatialite:
            qs = qs.exclude(name='Texas')
        for c in qs:
            self.assertEqual(c.mpoly.difference(geom), c.difference)
            self.assertTrue(c.mpoly.difference(geom).equals(c.difference))

    @skipUnlessDBFeature("has_Envelope_function")
    def test_envelope(self):
@@ -218,8 +218,8 @@ class GISFunctionsTests(TestCase):
        geom = Point(5, 23, srid=4326)
        qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom))
        for c in qs:
            if spatialite:
                # When the intersection is empty, Spatialite returns None
            if spatialite or mysql:
                # When the intersection is empty, Spatialite and MySQL return None
                expected = None
            else:
                expected = c.mpoly.intersection(geom)
@@ -376,9 +376,7 @@ class GISFunctionsTests(TestCase):
        geom = Point(5, 23, srid=4326)
        qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom))
        for country in qs:
            # Ordering might differ in collections
            self.assertSetEqual(set(g.wkt for g in country.mpoly.sym_difference(geom)),
                                set(g.wkt for g in country.sym_difference))
            self.assertTrue(country.mpoly.sym_difference(geom).equals(country.sym_difference))

    @skipUnlessDBFeature("has_Transform_function")
    def test_transform(self):
@@ -431,14 +429,11 @@ class GISFunctionsTests(TestCase):
            # SpatiaLite).
            return
        for c in qs:
            self.assertEqual(c.mpoly.difference(geom), c.difference)
            if not spatialite:
            self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
            if not (spatialite or mysql):
                self.assertEqual(c.mpoly.intersection(geom), c.intersection)
            # Ordering might differ in collections
            self.assertSetEqual(set(g.wkt for g in c.mpoly.sym_difference(geom)),
                                set(g.wkt for g in c.sym_difference))
            self.assertSetEqual(set(g.wkt for g in c.mpoly.union(geom)),
                                set(g.wkt for g in c.union))
            self.assertTrue(c.mpoly.sym_difference(geom).equals(c.sym_difference))
            self.assertTrue(c.mpoly.union(geom).equals(c.union))

    @skipUnlessDBFeature("has_Union_function")
    def test_union(self):