Fixed #30890 -- Added MariaDB support for the relate lookup.

This commit is contained in:
Mariusz Felisiak 2019-10-17 14:02:37 +02:00
parent bebf61de11
commit 3a8af298b9
5 changed files with 26 additions and 10 deletions

View File

@ -29,7 +29,7 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
@cached_property
def gis_operators(self):
return {
operators = {
'bbcontains': SpatialOperator(func='MBRContains'), # For consistency w/PostGIS API
'bboverlaps': SpatialOperator(func='MBROverlaps'), # ...
'contained': SpatialOperator(func='MBRWithin'), # ...
@ -44,6 +44,9 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
'touches': SpatialOperator(func='ST_Touches'),
'within': SpatialOperator(func='ST_Within'),
}
if self.connection.mysql_is_mariadb:
operators['relate'] = SpatialOperator(func='ST_Relate')
return operators
disallowed_aggregates = (
aggregates.Collect, aggregates.Extent, aggregates.Extent3D,

View File

@ -332,7 +332,7 @@ Lookup Type PostGIS Oracle MariaDB MySQL [#]_ Sp
:lookup:`intersects` X X X X X B
:lookup:`isvalid` X X X (≥ 5.7.5) X (LWGEOM)
:lookup:`overlaps` X X X X X B
:lookup:`relate` X X X C
:lookup:`relate` X X X X C
:lookup:`same_as` X X X X X B
:lookup:`touches` X X X X X B
:lookup:`within` X X X X X B

View File

@ -426,14 +426,15 @@ SpatiaLite ``Overlaps(poly, geom)``
----------
*Availability*: `PostGIS <https://postgis.net/docs/ST_Relate.html>`__,
Oracle, SpatiaLite, PGRaster (Conversion)
MariaDB, Oracle, SpatiaLite, PGRaster (Conversion)
Tests if the geometry field is spatially related to the lookup geometry by
the values given in the given pattern. This lookup requires a tuple parameter,
``(geom, pattern)``; the form of ``pattern`` will depend on the spatial backend:
PostGIS & SpatiaLite
~~~~~~~~~~~~~~~~~~~~
MariaDB, PostGIS, and SpatiaLite
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On these spatial backends the intersection pattern is a string comprising
nine characters, which define intersections between the interior, boundary,
and exterior of the geometry field and the lookup geometry.
@ -447,7 +448,7 @@ Geometry example::
# the intersection pattern (the pattern here is for 'contains').
Zipcode.objects.filter(poly__relate=(geom, 'T*T***FF*'))
PostGIS SQL equivalent:
PostGIS and MariaDB SQL equivalent:
.. code-block:: sql
@ -471,6 +472,10 @@ PostGIS SQL equivalent:
SELECT ... WHERE ST_Relate(poly, ST_Polygon(rast, 1), 'T*T***FF*')
SELECT ... WHERE ST_Relate(ST_Polygon(rast, 2), ST_Polygon(rast, 1), 'T*T***FF*')
.. versionchanged:: 3.1
MariaDB support was added.
Oracle
~~~~~~

View File

@ -59,7 +59,7 @@ Minor features
:mod:`django.contrib.gis`
~~~~~~~~~~~~~~~~~~~~~~~~~
* ...
* :lookup:`relate` lookup is now supported on MariaDB.
:mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -450,7 +450,7 @@ class GeoLookupTest(TestCase):
qs.count()
# Relate works differently for the different backends.
if postgis or spatialite:
if postgis or spatialite or mariadb:
contains_mask = 'T*T***FF*'
within_mask = 'T*F**F***'
intersects_mask = 'T********'
@ -461,7 +461,11 @@ class GeoLookupTest(TestCase):
intersects_mask = 'overlapbdyintersect'
# Testing contains relation mask.
self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name)
if connection.features.supports_transform:
self.assertEqual(
Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name,
'Texas',
)
self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name)
# Testing within relation mask.
@ -470,7 +474,11 @@ class GeoLookupTest(TestCase):
# Testing intersection relation mask.
if not oracle:
self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name)
if connection.features.supports_transform:
self.assertEqual(
Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name,
'Texas',
)
self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name)
self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name)