This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 145154c0474 [Enhancement](geo) Support ST_Within spatial functions
(#65790)
145154c0474 is described below
commit 145154c0474cd964ccbcb334371d03d3afd2d0ac
Author: yy782 <[email protected]>
AuthorDate: Mon Sep 21 14:57:08 2026 +0800
[Enhancement](geo) Support ST_Within spatial functions (#65790)
### What problem does this PR solve?
Issue Number: related https://github.com/apache/doris/issues/48203
Problem Summary:
Support ST_Within spatial functions
### Release note
Add the ST_Within spatial function.
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [x] Regression test
- [x] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [ ] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [ ] No.
- [x] Yes. https://github.com/apache/doris-website/pull/4000
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
---------
Signed-off-by: yy <[email protected]>
---
be/src/exprs/function/geo/functions_geo.cpp | 6 +
be/src/exprs/function/geo/geo_types.h | 2 +
be/test/exprs/function/geo/geo_types_test.cpp | 214 +++++++++++++++++++++
.../doris/catalog/BuiltinScalarFunctions.java | 2 +
.../expressions/functions/scalar/StWithin.java | 77 ++++++++
.../expressions/visitor/ScalarFunctionVisitor.java | 5 +
.../spatial_functions/test_gis_function.out | 84 ++++++++
.../spatial_functions/test_gis_function.groovy | 31 +++
8 files changed, 421 insertions(+)
diff --git a/be/src/exprs/function/geo/functions_geo.cpp
b/be/src/exprs/function/geo/functions_geo.cpp
index 00b2735ace2..48177452c18 100644
--- a/be/src/exprs/function/geo/functions_geo.cpp
+++ b/be/src/exprs/function/geo/functions_geo.cpp
@@ -559,6 +559,11 @@ struct StTouchesFunc {
static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return
shape1->touches(shape2); }
};
+struct StWithinFunc {
+ static constexpr auto NAME = "st_within";
+ static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return
shape1->within(shape2); }
+};
+
struct StGeometryFromText {
static constexpr auto NAME = "st_geometryfromtext";
static constexpr GeoShapeType shape_type = GEO_SHAPE_ANY;
@@ -1132,6 +1137,7 @@ void register_function_geo(SimpleFunctionFactory&
factory) {
factory.register_function<GeoFunction<StRelationFunction<StIntersectsFunc>>>();
factory.register_function<GeoFunction<StRelationFunction<StDisjointFunc>>>();
factory.register_function<GeoFunction<StRelationFunction<StTouchesFunc>>>();
+ factory.register_function<GeoFunction<StRelationFunction<StWithinFunc>>>();
factory.register_function<GeoFunction<StCircle>>();
factory.register_function<GeoFunction<StGeoFromText<StGeometryFromText>>>();
factory.register_function<GeoFunction<StGeoFromText<StGeomFromText>>>();
diff --git a/be/src/exprs/function/geo/geo_types.h
b/be/src/exprs/function/geo/geo_types.h
index 146ebf2a847..c971fc9b61d 100644
--- a/be/src/exprs/function/geo/geo_types.h
+++ b/be/src/exprs/function/geo/geo_types.h
@@ -70,6 +70,8 @@ public:
virtual bool touches(const GeoShape* rhs) const { return false; }
+ virtual bool within(const GeoShape* rhs) const { return
rhs->contains(this); }
+
virtual std::string GeometryType() const = 0;
virtual double Length() const { return 0.0; }
diff --git a/be/test/exprs/function/geo/geo_types_test.cpp
b/be/test/exprs/function/geo/geo_types_test.cpp
index 580218f4058..abc274ccca1 100644
--- a/be/test/exprs/function/geo/geo_types_test.cpp
+++ b/be/test/exprs/function/geo/geo_types_test.cpp
@@ -1978,6 +1978,220 @@ TEST_F(GeoTypesTest, polygon_hole_contains) {
}
}
+TEST_F(GeoTypesTest, within) {
+ GeoParseStatus status;
+
+ // ============================================================
+ // GeoPoint.within(X)
+ // ============================================================
+ {
+ // Point within simple Polygon
+ const char* wkt = "POLYGON ((10 10, 50 10, 50 50, 10 50, 10 10))";
+ auto polygon(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_NE(nullptr, polygon.get());
+
+ GeoPoint point;
+ point.from_coord(20, 20);
+ EXPECT_TRUE(point.within(polygon.get()));
+
+ point.from_coord(5, 5);
+ EXPECT_FALSE(point.within(polygon.get()));
+
+ point.from_coord(50, 50);
+ EXPECT_FALSE(point.within(polygon.get()));
+ }
+ {
+ // Point within Polygon with hole
+ const char* wkt =
+ "POLYGON ((10 10, 50 10, 50 50, 10 50, 10 10), (20 20, 40 20,
40 40, 20 40, 20 "
+ "20))";
+ auto polygon(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_NE(nullptr, polygon.get());
+
+ GeoPoint point;
+ point.from_coord(15, 15);
+ EXPECT_TRUE(point.within(polygon.get()));
+
+ point.from_coord(30, 30);
+ EXPECT_FALSE(point.within(polygon.get()));
+
+ point.from_coord(20, 20);
+ EXPECT_FALSE(point.within(polygon.get()));
+ }
+ {
+ // Point within MultiPolygon
+ const char* wkt =
+ "MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))";
+ auto multipolygon(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_NE(nullptr, multipolygon.get());
+
+ GeoPoint point;
+ point.from_coord(5, 5);
+ EXPECT_TRUE(point.within(multipolygon.get()));
+
+ point.from_coord(17, 7);
+ EXPECT_TRUE(point.within(multipolygon.get()));
+
+ point.from_coord(12, 5);
+ EXPECT_FALSE(point.within(multipolygon.get()));
+ }
+ {
+ // Point within LineString (LineString does not implement contains)
+ const char* wkt = "LINESTRING (0 0, 10 0)";
+ auto line(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_NE(nullptr, line.get());
+
+ GeoPoint point;
+ point.from_coord(5, 0);
+ EXPECT_FALSE(point.within(line.get()));
+ }
+ {
+ // Point within Circle
+ GeoCircle circle;
+ circle.init(0, 0, 1000000);
+
+ GeoPoint point;
+ point.from_coord(1, 1);
+ EXPECT_TRUE(point.within(&circle));
+
+ point.from_coord(90, 0);
+ EXPECT_FALSE(point.within(&circle));
+ }
+
+ // ============================================================
+ // GeoLine.within(X)
+ // ============================================================
+ {
+ // LineString within Polygon
+ const char* wkt_polygon = "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))";
+ auto polygon(GeoShape::from_wkt(wkt_polygon, strlen(wkt_polygon),
status));
+ EXPECT_NE(nullptr, polygon.get());
+
+ const char* wkt = "LINESTRING (2 5, 8 5)";
+ auto line(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(line->within(polygon.get()));
+ }
+ {
+ // LineString within MultiPolygon
+ const char* wkt =
+ "MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))";
+ auto multipolygon(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_NE(nullptr, multipolygon.get());
+
+ const char* wkt_line = "LINESTRING(2 2, 8 2)";
+ auto line(GeoShape::from_wkt(wkt_line, strlen(wkt_line), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(line->within(multipolygon.get()));
+
+ wkt_line = "LINESTRING(16 6, 19 9)";
+ auto line2(GeoShape::from_wkt(wkt_line, strlen(wkt_line), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(line2->within(multipolygon.get()));
+
+ wkt_line = "LINESTRING(5 5, 16 7)";
+ auto line3(GeoShape::from_wkt(wkt_line, strlen(wkt_line), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(line3->within(multipolygon.get()));
+
+ wkt_line = "LINESTRING(0 0, 0 10)";
+ auto line4(GeoShape::from_wkt(wkt_line, strlen(wkt_line), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(line4->within(multipolygon.get()));
+ }
+
+ // ============================================================
+ // GeoPolygon.within(X)
+ // ============================================================
+ {
+ // Polygon within Polygon
+ const char* wkt_outer = "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))";
+ auto outer(GeoShape::from_wkt(wkt_outer, strlen(wkt_outer), status));
+ EXPECT_NE(nullptr, outer.get());
+
+ const char* wkt = "POLYGON ((3 3, 7 3, 7 7, 3 7, 3 3))";
+ auto inner(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(inner->within(outer.get()));
+
+ wkt = "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))";
+ auto overlapping(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(overlapping->within(outer.get()));
+
+ wkt = "POLYGON ((20 20, 30 20, 30 30, 20 30, 20 20))";
+ auto separate(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(separate->within(outer.get()));
+ }
+ {
+ // Polygon within MultiPolygon
+ const char* wkt =
+ "MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))";
+ auto multipolygon(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_NE(nullptr, multipolygon.get());
+
+ const char* wkt_inner = "POLYGON((1 1, 1 9, 9 9, 9 1, 1 1))";
+ auto inner(GeoShape::from_wkt(wkt_inner, strlen(wkt_inner), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(inner->within(multipolygon.get()));
+
+ wkt_inner = "POLYGON((16 6, 16 9, 19 9, 19 6, 16 6))";
+ auto inner2(GeoShape::from_wkt(wkt_inner, strlen(wkt_inner), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(inner2->within(multipolygon.get()));
+
+ wkt_inner = "POLYGON((5 5, 5 15, 15 15, 15 5, 5 5))";
+ auto inner3(GeoShape::from_wkt(wkt_inner, strlen(wkt_inner), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(inner3->within(multipolygon.get()));
+ }
+
+ // ============================================================
+ // MultiPolygon.within(X)
+ // ============================================================
+ {
+ // MultiPolygon within Polygon
+ const char* wkt_outer = "POLYGON ((0 0, 20 0, 20 20, 0 20, 0 0))";
+ auto outer(GeoShape::from_wkt(wkt_outer, strlen(wkt_outer), status));
+ EXPECT_NE(nullptr, outer.get());
+
+ const char* wkt = "MULTIPOLYGON(((2 2, 4 2, 4 4, 2 4, 2 2)), ((6 6, 8
6, 8 8, 6 8, 6 6)))";
+ auto inner(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(inner->within(outer.get()));
+
+ wkt = "MULTIPOLYGON(((2 2, 4 2, 4 4, 2 4, 2 2)), ((15 15, 25 15, 25
25, 15 25, 15 15)))";
+ auto partial(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(partial->within(outer.get()));
+ }
+ {
+ // MultiPolygon within MultiPolygon
+ const char* wkt_outer =
+ "MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))";
+ auto outer(GeoShape::from_wkt(wkt_outer, strlen(wkt_outer), status));
+ EXPECT_NE(nullptr, outer.get());
+
+ const char* wkt =
+ "MULTIPOLYGON(((1 1, 1 9, 9 9, 9 1, 1 1)), ((16 6, 16 9, 19 9,
19 6, 16 6)))";
+ auto inner(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_TRUE(inner->within(outer.get()));
+
+ wkt = "MULTIPOLYGON(((1 1, 1 5, 5 5, 5 1, 1 1)), ((12 6, 12 9, 14 9,
14 6, 12 6)))";
+ auto inner2(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(inner2->within(outer.get()));
+
+ wkt = "MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1, 1 1)), ((5 5, 5 11, 12 11,
12 5, 5 5)))";
+ auto inner3(GeoShape::from_wkt(wkt, strlen(wkt), status));
+ EXPECT_EQ(GEO_PARSE_OK, status);
+ EXPECT_FALSE(inner3->within(outer.get()));
+ }
+}
+
TEST_F(GeoTypesTest, multipolygon_parse_fail) {
{
const char* wkt = "MULTIPOLYGON (((10 10, 50 10, 50 50, 10 50), (10 10
01)))";
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index a26f94f5ab9..6ccaead81c4 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -512,6 +512,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.StPolyfromtex
import org.apache.doris.nereids.trees.expressions.functions.scalar.StPolygon;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.StPolygonfromtext;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StTouches;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.StWithin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StX;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StY;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StartsWith;
@@ -1096,6 +1097,7 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(StIntersects.class, "st_intersects"),
scalar(StDisjoint.class, "st_disjoint"),
scalar(StTouches.class, "st_touches"),
+ scalar(StWithin.class, "st_within"),
scalar(StLength.class, "st_length"),
scalar(StGeometryType.class, "st_geometrytype"),
scalar(StIsClosed.class, "st_isclosed"),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/StWithin.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/StWithin.java
new file mode 100644
index 00000000000..d3630beced8
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/StWithin.java
@@ -0,0 +1,77 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
+import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import
org.apache.doris.nereids.trees.expressions.functions.PropagateNullLiteral;
+import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.BooleanType;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'st_within'. This class is generated by GenerateFunction.
+ */
+public class StWithin extends ScalarFunction
+ implements BinaryExpression, ExplicitlyCastableSignature,
AlwaysNullable, PropagateNullLiteral {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+
FunctionSignature.ret(BooleanType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT,
VarcharType.SYSTEM_DEFAULT),
+
FunctionSignature.ret(BooleanType.INSTANCE).args(StringType.INSTANCE,
StringType.INSTANCE)
+ );
+
+ /**
+ * constructor with 2 arguments.
+ */
+ public StWithin(Expression arg0, Expression arg1) {
+ super("st_within", arg0, arg1);
+ }
+
+ /** constructor for withChildren and reuse signature */
+ private StWithin(ScalarFunctionParams functionParams) {
+ super(functionParams);
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public StWithin withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 2);
+ return new StWithin(getFunctionParams(children));
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitStWithin(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 3ba1ab10352..246eea05671 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -530,6 +530,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.StPolyfromtex
import org.apache.doris.nereids.trees.expressions.functions.scalar.StPolygon;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.StPolygonfromtext;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StTouches;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.StWithin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StX;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StY;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StartsWith;
@@ -2423,6 +2424,10 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(stTouches, context);
}
+ default R visitStWithin(StWithin stWithin, C context) {
+ return visitScalarFunction(stWithin, context);
+ }
+
default R visitStLength(StLength stLength, C context) {
return visitScalarFunction(stLength, context);
}
diff --git
a/regression-test/data/query_p0/sql_functions/spatial_functions/test_gis_function.out
b/regression-test/data/query_p0/sql_functions/spatial_functions/test_gis_function.out
index c5404d8381c..acf0c020518 100644
---
a/regression-test/data/query_p0/sql_functions/spatial_functions/test_gis_function.out
+++
b/regression-test/data/query_p0/sql_functions/spatial_functions/test_gis_function.out
@@ -182,6 +182,90 @@ true
-- !sql --
false
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+true
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+false
+
+-- !sql --
+true
+
+-- !sql --
+false
+
-- !sql --
true
diff --git
a/regression-test/suites/query_p0/sql_functions/spatial_functions/test_gis_function.groovy
b/regression-test/suites/query_p0/sql_functions/spatial_functions/test_gis_function.groovy
index 35bc505604d..1f68796e629 100644
---
a/regression-test/suites/query_p0/sql_functions/spatial_functions/test_gis_function.groovy
+++
b/regression-test/suites/query_p0/sql_functions/spatial_functions/test_gis_function.groovy
@@ -86,6 +86,37 @@ suite("test_gis_function", "arrow_flight_sql") {
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)))'));"
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)))'));"
+ qt_sql "SELECT ST_Within(ST_Point(5, 5), ST_Polygon(\"POLYGON ((0 0, 10 0,
10 10, 0 10, 0 0))\"));"
+ qt_sql "SELECT ST_Within(ST_Point(50, 50), ST_Polygon(\"POLYGON ((0 0, 10
0, 10 10, 0 10, 0 0))\"));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POINT(2 10)'),
ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(2 5, 8 5)'),
ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(2 0, 8 0)'),
ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(0 0, 10 0)'),
ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(0 0, 10 10)'),
ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(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))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((3 3, 3 7, 7 7, 7 3, 3
3))'), ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((10 10, 20 10, 20 20, 10
20, 10 10))'), ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));"
+
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((4 4, 7 4, 7 7, 4 7, 4
4))'), ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8,
3 8, 3 3))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((1 1, 9 1, 9 9, 1 9, 1
1))'), ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (3 3, 8 3, 8 8,
3 8, 3 3))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('MULTIPOLYGON(((2 2, 4 2, 4 4, 2
4, 2 2)), ((6 6, 8 6, 8 8, 6 8, 6 6)))'), ST_GeomFromText('POLYGON((0 0, 0 10,
10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('MULTIPOLYGON(((2 2, 2 8, 8 8, 8
2, 2 2)), ((10 10, 10 15, 15 15, 15 10, 10 10)))'), ST_GeomFromText('POLYGON((0
0, 0 10, 10 10, 10 0, 0 0))'));"
+ qt_sql "SELECT ST_Within(ST_Point(5, 5), ST_GeomFromText('MULTIPOLYGON(((0
0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10, 20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_Point(17, 7),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_Point(12, 7),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(2 2, 8 8)'),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('LINESTRING(5 5, 16 6)'),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((1 1, 1 9, 9 9, 9 1, 1
1))'), ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5,
15 10, 20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((16 6, 16 9, 19 9, 19 6,
16 6))'), ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15
5, 15 10, 20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('POLYGON((5 5, 5 15, 15 15, 15 5,
5 5))'), ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5,
15 10, 20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('MULTIPOLYGON(((1 1, 1 5, 5 5, 5
1, 1 1)), ((16 6, 16 9, 19 9, 19 6, 16 6)))'),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_GeomFromText('MULTIPOLYGON(((1 1, 1 5, 5 5, 5
1, 1 1)), ((12 6, 12 9, 14 9, 14 6, 12 6)))'),
ST_GeomFromText('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((15 5, 15 10,
20 10, 20 5, 15 5)))'));"
+ qt_sql "SELECT ST_Within(ST_Point(0.5, 0.5), ST_Circle(0, 0, 1000000));"
+ qt_sql "SELECT ST_Within(ST_Point(90, 0), ST_Circle(0, 0, 1000000));"
+ qt_sql "SELECT ST_Within(ST_Point(0, 0), ST_Polygon(\"POLYGON ((0 0, 10 0,
10 10, 0 10, 0 0))\"));"
+ qt_sql "SELECT ST_Within(ST_Point(10, 10), ST_Polygon(\"POLYGON ((0 0, 10
0, 10 10, 0 10, 0 0))\"));"
+
qt_sql "SELECT ST_Intersects(ST_Point(0, 0), ST_Point(0, 0));"
qt_sql "SELECT ST_Intersects(ST_Point(0, 0), ST_Point(5, 5));"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]