Skip to content

Commit 82e191c

Browse files
linrrzqqqkoarz
authored andcommitted
[fix](geo) Fix ST_Contains behavior (apache#50115)
1. According to the OGC standard, a point lying exactly on the boundary of a polygon no longer returns `true` for `ST_Contains`. This behavior has been changed to return `false`. 2. Fix the inconsistency in `polygon Contains linestring` caused by differing linestring directions. 3. Fixed a logical error in `multipolygon Contains multipolygon`
1 parent e39b32d commit 82e191c

File tree

4 files changed

+262
-5
lines changed

4 files changed

+262
-5
lines changed

be/src/geo/geo_types.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,10 +1033,45 @@ bool GeoPolygon::contains(const GeoShape* rhs) const {
10331033
switch (rhs->type()) {
10341034
case GEO_SHAPE_POINT: {
10351035
const GeoPoint* point = (const GeoPoint*)rhs;
1036-
return _polygon->Contains(*point->point());
1036+
if (!_polygon->Contains(*point->point())) {
1037+
return false;
1038+
}
1039+
1040+
// Point on the edge of polygon doesn't count as "Contians"
1041+
for (int i = 0; i < _polygon->num_loops(); ++i) {
1042+
const S2Loop* loop = _polygon->loop(i);
1043+
for (int j = 0; j < loop->num_vertices(); ++j) {
1044+
const S2Point& p1 = loop->vertex(j);
1045+
const S2Point& p2 = loop->vertex((j + 1) % loop->num_vertices());
1046+
if (compute_distance_to_line(*point->point(), p1, p2) < TOLERANCE) {
1047+
return false;
1048+
}
1049+
}
1050+
}
1051+
return true;
10371052
}
10381053
case GEO_SHAPE_LINE_STRING: {
10391054
const GeoLine* line = (const GeoLine*)rhs;
1055+
1056+
// solve the problem caused by the `Contains(const S2Polyline)` in the S2 library
1057+
// due to the direction of the line segment
1058+
for (int i = 0; i < _polygon->num_loops(); ++i) {
1059+
const S2Loop* loop = _polygon->loop(i);
1060+
for (int j = 0; j < loop->num_vertices(); ++j) {
1061+
const S2Point& p1 = loop->vertex(j);
1062+
const S2Point& p2 = loop->vertex((j + 1) % loop->num_vertices());
1063+
for (int k = 0; k < line->polyline()->num_vertices() - 1; ++k) {
1064+
const S2Point& p3 = line->polyline()->vertex(k);
1065+
const S2Point& p4 = line->polyline()->vertex(k + 1);
1066+
if ((compute_distance_to_line(p3, p1, p2) < TOLERANCE ||
1067+
compute_distance_to_line(p4, p1, p2) < TOLERANCE) &&
1068+
!is_line_touches_line(p1, p2, p3, p4)) {
1069+
return false;
1070+
}
1071+
}
1072+
}
1073+
}
1074+
10401075
return _polygon->Contains(*line->polyline());
10411076
}
10421077
case GEO_SHAPE_POLYGON: {
@@ -1271,10 +1306,14 @@ bool GeoMultiPolygon::contains(const GeoShape* rhs) const {
12711306
//All polygons in rhs need to be contained
12721307
const GeoMultiPolygon* multi_polygon = assert_cast<const GeoMultiPolygon*>(rhs);
12731308
for (const auto& other : multi_polygon->polygons()) {
1309+
bool is_contains = false;
12741310
for (const auto& polygon : this->_polygons) {
12751311
if (polygon->contains(other.get())) {
1276-
continue;
1312+
is_contains = true;
1313+
break;
12771314
}
1315+
}
1316+
if (!is_contains) {
12781317
return false;
12791318
}
12801319
}

be/test/geo/geo_types_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1482,7 +1482,7 @@ TEST_F(GeoTypesTest, polygon_hole_contains) {
14821482
GeoPoint point;
14831483
point.from_coord(20, 20);
14841484
auto res = polygon->contains(&point);
1485-
EXPECT_TRUE(res);
1485+
EXPECT_FALSE(res);
14861486
}
14871487
}
14881488

regression-test/data/nereids_p0/sql_functions/spatial_functions/test_gis_function.out

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,29 @@ POINT (24.7 56.7)
99
CIRCLE ((111 64), 10000)
1010

1111
-- ST_Contains --
12+
-- POLYGON_Contains_POINT
1213
-- !sql --
1314
true
1415

1516
-- !sql --
1617
false
1718

19+
-- !sql --
20+
false
21+
22+
-- POLYGON_Contains_LINESTRING
23+
-- !sql --
24+
false
25+
26+
-- !sql --
27+
true
28+
29+
-- !sql --
30+
false
31+
32+
-- !sql --
33+
false
34+
1835
-- !sql --
1936
true
2037

@@ -24,6 +41,150 @@ true
2441
-- !sql --
2542
false
2643

44+
-- POLYGON_Contains_Polygon
45+
-- !sql --
46+
true
47+
48+
-- !sql --
49+
false
50+
51+
-- !sql --
52+
false
53+
54+
-- !sql --
55+
true
56+
57+
-- !sql --
58+
false
59+
60+
-- !sql --
61+
false
62+
63+
-- !sql --
64+
true
65+
66+
-- !sql --
67+
false
68+
69+
-- POLYGON_Contains_MULTIPOLYGON
70+
-- !sql --
71+
true
72+
73+
-- !sql --
74+
false
75+
76+
-- MULTIPOLYGON_Contains_POINT
77+
-- !sql --
78+
true
79+
80+
-- !sql --
81+
true
82+
83+
-- !sql --
84+
false
85+
86+
-- !sql --
87+
false
88+
89+
-- !sql --
90+
false
91+
92+
-- !sql --
93+
false
94+
95+
-- !sql --
96+
false
97+
98+
-- !sql --
99+
true
100+
101+
-- !sql --
102+
false
103+
104+
-- MULTIPOLYGON_Contains_LINESTRING
105+
-- !sql --
106+
true
107+
108+
-- !sql --
109+
true
110+
111+
-- !sql --
112+
false
113+
114+
-- !sql --
115+
true
116+
117+
-- !sql --
118+
true
119+
120+
-- !sql --
121+
false
122+
123+
-- !sql --
124+
false
125+
126+
-- !sql --
127+
true
128+
129+
-- !sql --
130+
false
131+
132+
-- MULTIPOLYGON_Contains_POLYGON
133+
-- !sql --
134+
true
135+
136+
-- !sql --
137+
true
138+
139+
-- !sql --
140+
false
141+
142+
-- !sql --
143+
true
144+
145+
-- !sql --
146+
false
147+
148+
-- !sql --
149+
false
150+
151+
-- !sql --
152+
false
153+
154+
-- !sql --
155+
true
156+
157+
-- !sql --
158+
false
159+
160+
-- MULTIPOLYGON_Contains_MULTIPOLYGON
161+
-- !sql --
162+
true
163+
164+
-- !sql --
165+
false
166+
167+
-- !sql --
168+
true
169+
170+
-- !sql --
171+
false
172+
173+
-- !sql --
174+
false
175+
176+
-- !sql --
177+
false
178+
179+
-- !sql --
180+
true
181+
182+
-- !sql --
183+
false
184+
185+
-- !sql --
186+
false
187+
27188
-- ST_Intersects --
28189
-- POINT_Intersects
29190
-- !sql --

regression-test/suites/nereids_p0/sql_functions/spatial_functions/test_gis_function.groovy

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,66 @@ suite("test_gis_function") {
2727
qt_sql "SELECT ST_Contains(ST_Polygon(\"POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))\"), ST_Point(5, 5));"
2828
qt_sql "SELECT ST_Contains(ST_Polygon(\"POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))\"), ST_Point(50, 50));"
2929
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('POINT(2 10)'));"
30-
qt_sql "SELECT ST_Contains(ST_GeomFromText(\"POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))\"),ST_GeomFromText(\"MULTIPOLYGON(((2 2, 4 2, 4 4, 2 4, 2 2)), ((6 6, 8 6, 8 8, 6 8, 6 6)))\"));"
31-
qt_sql "SELECT ST_Contains(ST_GeomFromText(\"POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))\"),ST_GeomFromText(\"MULTIPOLYGON(((2 2, 2 8, 8 8, 8 2, 2 2)), ((10 10, 10 15, 15 15, 15 10, 10 10)))\"));"
3230

31+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(2 0, 8 0)'));"
32+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(2 5, 8 5)'));"
33+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(0 0, 10 0)'));"
34+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(10 0, 0 0)'));"
35+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(5 0, 5 5)'));"
36+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(0 0, 10 10)'));"
37+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('LINESTRING(-0.000001 0, 10 10)'));"
38+
39+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
40+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('POLYGON((10 10, 20 10, 20 20, 10 20, 10 10))'));"
41+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('POLYGON((0 0, 0 10.000001, 10.000001 10.000001, 10.000001 0, 0 0))'));"
42+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), ST_GeomFromText('POLYGON((3 3, 3 7, 7 7, 7 3, 3 3))'));"
43+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8, 3 8, 3 3))'), ST_GeomFromText('POLYGON((4 4, 7 4, 7 7, 4 7, 4 4))'));"
44+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8, 3 8, 3 3))'), ST_GeomFromText('POLYGON((3 3, 8 3, 8 8, 3 8, 3 3))'));"
45+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8, 3 8, 3 3))'), ST_GeomFromText('POLYGON((2.999999 2.999999, 8.000001 2.999999, 8.000001 8.000001, 2.999999 8.000001, 2.999999 2.999999), (3 3, 8 3, 8 8, 3 8, 3 3))'));"
46+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8, 3 8, 3 3))'), ST_GeomFromText('POLYGON((1 1, 9 1, 9 9, 1 9, 1 1), (3.000001 3.000001, 7.999999 3.000001, 7.999999 7.999999, 3.000001 7.999999, 3.000001 3.000001))'));"
47+
48+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'),ST_GeomFromText('MULTIPOLYGON(((2 2, 4 2, 4 4, 2 4, 2 2)), ((6 6, 8 6, 8 8, 6 8, 6 6)))'));"
49+
qt_sql "SELECT ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'),ST_GeomFromText('MULTIPOLYGON(((2 2, 2 8, 8 8, 8 2, 2 2)), ((10 10, 10 15, 15 15, 15 10, 10 10)))'));"
50+
51+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(5 5)'));"
52+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(17 7)'));"
53+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(12 7)'));"
54+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(0 5)'));"
55+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(10 10)'));"
56+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('POINT(5 5)'));"
57+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('POINT(2 5)'));"
58+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(0.000001 0.000001)'));"
59+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POINT(-0.000001 0)'));"
60+
61+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(2 2, 8 8)'));"
62+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(16 6, 19 9)'));"
63+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(5 5, 16 6)'));"
64+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(0 0, 10 10)'));"
65+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(5 0, 5 10)'));"
66+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('LINESTRING(3 3, 7 7)'));"
67+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('LINESTRING(1 1, 9 9)'));"
68+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(0.000001 0.000001, 9.999999 9.999999)'));"
69+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('LINESTRING(0.000001 0.000001, 10.000001 10.000001)'));"
70+
71+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((1 1, 1 9, 9 9, 9 1, 1 1))'));"
72+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((16 6, 16 9, 19 9, 19 6, 16 6))'));"
73+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((5 5, 5 15, 15 15, 15 5, 5 5))'));"
74+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
75+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((-5 -5, -5 15, 15 15, 15 -5, -5 -5))'));"
76+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('POLYGON((3 3, 3 7, 7 7, 7 3, 3 3))'));"
77+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)))'), ST_GeomFromText('POLYGON((1 1, 1 9, 9 9, 9 1, 1 1))'));"
78+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((0.000001 0.000001, 0.000001 9.999999, 9.999999 9.999999, 9.999999 0.000001, 0.000001 0.000001))'));"
79+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('POLYGON((-0.000001 -0.000001, -0.000001 10.000001, 10.000001 10.000001, 10.000001 -0.000001, -0.000001 -0.000001))'));"
80+
81+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((1 1, 1 5, 5 5, 5 1, 1 1)), ((16 6, 16 9, 19 9, 19 6, 16 6)))'));"
82+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((1 1, 1 5, 5 5, 5 1, 1 1)), ((12 6, 12 9, 14 9, 14 6, 12 6)))'));"
83+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'));"
84+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((1 1, 1 9, 9 9, 9 1, 1 1)), ((16 6, 16 9, 19 9, 19 6, 16 6)))'));"
85+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 8, 8 8, 8 2, 2 2)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((3 3, 3 7, 7 7, 7 3, 3 3)), ((16 6, 16 9, 19 9, 19 6, 16 6)))'));"
86+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((25 5, 25 10, 30 10, 30 5, 25 5)))'));"
87+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((0.000001 0.000001, 0.000001 9.999999, 9.999999 9.999999, 9.999999 0.000001, 0.000001 0.000001)), ((15.000001 5.000001, 15.000001 9.999999, 19.999999 9.999999, 19.999999 5.000001, 15.000001 5.000001)))'));"
88+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((-0.000001 -0.000001, -0.000001 10.000001, 10.000001 10.000001, 10.000001 -0.000001, -0.000001 -0.000001)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'));"
89+
qt_sql "SELECT ST_Contains(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0), (3 3, 3 7, 7 7, 7 3, 3 3)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'), ST_GeomFromText('MULTIPOLYGON(((1 1, 1 9, 9 9, 9 1, 1 1), (4 4, 4 6, 6 6, 6 4, 4 4)), ((16 6, 16 9, 19 9, 19 6, 16 6)))'));"
3390

3491
qt_sql "SELECT ST_Intersects(ST_Point(0, 0), ST_Point(0, 0));"
3592
qt_sql "SELECT ST_Intersects(ST_Point(0, 0), ST_Point(5, 5));"

0 commit comments

Comments
 (0)