1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug #24563: MBROverlaps does not seem to function propertly.

Fix is to rewrite the MBR::overlaps() function, to compute the dimension of both
arguments, and the dimension of the intersection; test that all three dimensions are the
same (e.g., all are Polygons).

Add tests for all MBR* functions for various combinations of shapes, lines and points.


mysql-test/include/gis_generic.inc:
  Add tests & checks for bug #24563 and bug #24588 - some GIS functions missing in
  5.1; many GIS functions not tested; Overlaps() function was incorrect when MBR shifted
  only along one axis; Overlaps() needs to take dimension of shape into account.
mysql-test/r/archive_gis.result:
  Update test results.
mysql-test/r/bdb_gis.result:
  Update test results.
mysql-test/r/gis.result:
  Update test results.
mysql-test/r/innodb_gis.result:
  Update test results.
mysql-test/r/ndb_gis.result:
  Update test results.
mysql-test/t/gis.test:
  Add tests & checks for bug #24563 and bug #24588 - some GIS functions missing in
  5.1; many GIS functions not tested; Overlaps() function was incorrect when MBR shifted
  only along one axis; Overlaps() needs to take dimension of shape into account.
sql/spatial.h:
  Add MBR::dimension() (map MBR to integral dimension: point -> 0, line -> 1,
  polygon -> 2, invalid -> -1)
  
  Fix MBR::overlaps() to handle MBRs which are shifted on one dimension only, and to
  take MBR dimension into account.  Also, test both within() and contains() predicates (so
  that overlaps(a, b) == overlaps(b, a)).
This commit is contained in:
unknown
2007-03-23 16:28:07 -06:00
parent 2b52bc2a8e
commit eee28a267d
8 changed files with 671 additions and 13 deletions

View File

@ -392,7 +392,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
first second w c o e d t i r
120 120 1 1 0 1 0 0 1 0
120 121 0 0 0 0 0 0 1 0
120 121 0 0 1 0 0 0 1 0
121 120 0 0 1 0 0 0 1 0
121 121 1 1 0 1 0 0 1 0
explain extended SELECT g1.fid as first, g2.fid as second,
@ -456,6 +456,92 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 values (pointfromtext('point(1,1)'));
ERROR 23000: Column 'fl' cannot be null
drop table t1;
End of 4.1 tests
create table t1 (name VARCHAR(100), square GEOMETRY);
INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))'));
INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))'));
INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))'));
INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))'));
INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))'));
INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))'));
INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))'));
INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))'));
INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))'));
INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))'));
INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))'));
INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))'));
INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))'));
INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))'));
INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))'));
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrcontains
center,small
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrdisjoint
down3,left3,right3,up3
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrequal
center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrintersect
big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
contains
center,small
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
disjoint
down3,left3,right3,up3
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
equals
center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
intersect
big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))');
SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))');
SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))');
SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))');
SET @point1 = GeomFromText('POLYGON ((0 0))');
SET @point2 = GeomFromText('POLYGON ((-2 0))');
SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name;
overlaps
SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name;
overlaps
SELECT Overlaps(@horiz1, @vert1) FROM DUAL;
Overlaps(@horiz1, @vert1)
0
SELECT Overlaps(@horiz1, @horiz2) FROM DUAL;
Overlaps(@horiz1, @horiz2)
1
SELECT Overlaps(@horiz1, @horiz3) FROM DUAL;
Overlaps(@horiz1, @horiz3)
0
SELECT Overlaps(@horiz1, @point1) FROM DUAL;
Overlaps(@horiz1, @point1)
0
SELECT Overlaps(@horiz1, @point2) FROM DUAL;
Overlaps(@horiz1, @point2)
0
DROP TABLE t1;
End of 5.0 tests
set engine_condition_pushdown = on;
DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
CREATE TABLE gis_point (fid INTEGER, g POINT);
@ -850,7 +936,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
first second w c o e d t i r
120 120 1 1 0 1 0 0 1 0
120 121 0 0 0 0 0 0 1 0
120 121 0 0 1 0 0 0 1 0
121 120 0 0 1 0 0 0 1 0
121 121 1 1 0 1 0 0 1 0
explain extended SELECT g1.fid as first, g2.fid as second,
@ -914,3 +1000,89 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 values (pointfromtext('point(1,1)'));
ERROR 23000: Column 'fl' cannot be null
drop table t1;
End of 4.1 tests
create table t1 (name VARCHAR(100), square GEOMETRY);
INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))'));
INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))'));
INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))'));
INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))'));
INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))'));
INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))'));
INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))'));
INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))'));
INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))'));
INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))'));
INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))'));
INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))'));
INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))'));
INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))'));
INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))'));
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrcontains
center,small
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrdisjoint
down3,left3,right3,up3
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrequal
center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrintersect
big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
contains
center,small
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
disjoint
down3,left3,right3,up3
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
equals
center
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
intersect
big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))');
SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))');
SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))');
SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))');
SET @point1 = GeomFromText('POLYGON ((0 0))');
SET @point2 = GeomFromText('POLYGON ((-2 0))');
SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name;
overlaps
SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name;
overlaps
SELECT Overlaps(@horiz1, @vert1) FROM DUAL;
Overlaps(@horiz1, @vert1)
0
SELECT Overlaps(@horiz1, @horiz2) FROM DUAL;
Overlaps(@horiz1, @horiz2)
1
SELECT Overlaps(@horiz1, @horiz3) FROM DUAL;
Overlaps(@horiz1, @horiz3)
0
SELECT Overlaps(@horiz1, @point1) FROM DUAL;
Overlaps(@horiz1, @point1)
0
SELECT Overlaps(@horiz1, @point2) FROM DUAL;
Overlaps(@horiz1, @point2)
0
DROP TABLE t1;
End of 5.0 tests