zclllyybb commented on code in PR #48695:
URL: https://github.com/apache/doris/pull/48695#discussion_r2009206410


##########
be/src/geo/geo_types.cpp:
##########
@@ -299,6 +315,57 @@ const std::unique_ptr<GeoCoordinateListList> 
GeoPolygon::to_coords() const {
     return coordss;
 }
 
+bool GeoPoint::intersects(const GeoShape* rhs) const {
+    switch (rhs->type()) {
+    case GEO_SHAPE_POINT: {
+        // points and points are considered to intersect when they are equal
+        const GeoPoint* point = (const GeoPoint*)rhs;
+        return *_point == *point->point();
+    }
+    case GEO_SHAPE_LINE_STRING: {
+        const GeoLine* line = (const GeoLine*)rhs;
+        return line->intersects(this);
+    }
+    case GEO_SHAPE_POLYGON: {
+        const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+        return polygon->intersects(this);
+    }
+    case GEO_SHAPE_CIRCLE: {
+        const GeoCircle* circle = (const GeoCircle*)rhs;
+        return circle->intersects(this);
+    }
+    default:
+        return false;
+    }
+}
+
+bool GeoPoint::disjoint(const GeoShape* rhs) const {
+    return !intersects(rhs);
+}
+
+bool GeoPoint::touches(const GeoShape* rhs) const {
+    switch (rhs->type()) {
+    case GEO_SHAPE_POINT: {
+        // always returns false because the point has no boundaries
+        return false;
+    }
+    case GEO_SHAPE_LINE_STRING: {
+        const GeoLine* line = (const GeoLine*)rhs;
+        return line->touches(this);
+    }
+    case GEO_SHAPE_POLYGON: {
+        const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+        return polygon->touches(this);
+    }
+    case GEO_SHAPE_CIRCLE: {
+        const GeoCircle* circle = (const GeoCircle*)rhs;
+        return circle->touches(this);
+    }
+    default:

Review Comment:
   Is it possible to touch, intersect or disjoint for other shapes? like 
`GEO_SHAPE_MULTI_POINT` or something



##########
be/src/vec/functions/functions_geo.cpp:
##########
@@ -672,43 +674,37 @@ struct StContains {
                 break;
             }
         }
-
-        if (i == 2) {
-            auto contains_value = shapes[0]->contains(shapes[1].get());
-            res->insert_data(const_cast<const char*>((char*)&contains_value), 
0);
-        }
+        auto relation_value = Func::evaluate(shapes[0].get(), shapes[1].get());
+        res->insert_data(const_cast<const char*>((char*)&relation_value), 0);

Review Comment:
   1. why do these cast? seems weird.
   2. dont use `insert_data` interface. even if we allocated enough memory, it 
needs to do an unnecessary check for length. just get the Container(`PODArray`) 
from the column and change its data directly.



##########
be/src/geo/geo_types.cpp:
##########
@@ -75,6 +78,19 @@ static inline GeoParseStatus to_s2point(double lng, double 
lat, S2Point* point)
     return GEO_PARSE_OK;
 }
 
+static double compute_intersection_area(const S2Polygon* polygon1, const 
S2Polygon* polygon2) {
+    S2Polygon result;
+    S2BooleanOperation::Options options;
+    std::unique_ptr<s2builderutil::S2PolygonLayer> layer(
+            new s2builderutil::S2PolygonLayer(&result));
+    S2BooleanOperation op(S2BooleanOperation::OpType::INTERSECTION, 
std::move(layer));
+    S2Error error;

Review Comment:
   deal with the potiential error



##########
be/src/geo/geo_types.cpp:
##########
@@ -476,6 +656,155 @@ std::string GeoPolygon::as_wkt() const {
     return ss.str();
 }
 
+bool GeoPolygon::intersects(const GeoShape* rhs) const {
+    switch (rhs->type()) {
+    case GEO_SHAPE_POINT: {
+        const GeoPoint* point = (const GeoPoint*)rhs;

Review Comment:
   why do C-style cast here? seems useless



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/StDisjoint.java:
##########
@@ -0,0 +1,70 @@
+// 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.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'st_disjoint'. This class is generated by GenerateFunction.
+ */
+public class StDisjoint 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)

Review Comment:
   add StringType for args also



##########
be/src/geo/geo_types.cpp:
##########
@@ -476,6 +656,155 @@ std::string GeoPolygon::as_wkt() const {
     return ss.str();
 }
 
+bool GeoPolygon::intersects(const GeoShape* rhs) const {
+    switch (rhs->type()) {
+    case GEO_SHAPE_POINT: {
+        const GeoPoint* point = (const GeoPoint*)rhs;
+        // 1. when polygon contain the point return true
+        if (_polygon->Contains(*point->point())) {
+            return true;
+        }
+        // 2. calculate the distance between the point and the closest point 
on the boundary
+        S2Point closest_point = _polygon->ProjectToBoundary(*point->point());
+        S1Angle distance(closest_point, *point->point());
+        return distance.radians() < 1e-2;
+    }
+    case GEO_SHAPE_LINE_STRING: {
+        const GeoLine* line = (const GeoLine*)rhs;
+        std::vector<std::unique_ptr<S2Polyline>> intersect_lines =
+                _polygon->IntersectWithPolyline(*line->polyline());
+        if (intersect_lines.empty()) {
+            int next;
+            // s2geometry may not return the correct result when the line is 
on the boundary.
+            for (int i = 0; i < _polygon->num_loops(); ++i) {
+                const S2Loop* loop = _polygon->loop(i);
+                for (int j = 0; j < loop->num_vertices(); ++j) {
+                    const S2Point& p = loop->vertex(j);
+                    S2Point closest_point = line->polyline()->Project(p, 
&next);
+                    S1Angle distance(closest_point, p);
+                    if (distance.radians() < 1e-2) {

Review Comment:
   why use this as an error limit? It seems too great



##########
be/src/vec/functions/functions_geo.cpp:
##########
@@ -660,10 +662,10 @@ struct StContains {
     }
 
     static void loop_do(StringRef& lhs_value, StringRef& rhs_value,
-                        std::vector<std::shared_ptr<GeoShape>>& shapes, int& i,
+                        std::vector<std::shared_ptr<GeoShape>>& shapes,

Review Comment:
   `shapes` seems could be unique_ptr. could you confirm and fix it by the way?



##########
be/src/geo/geo_types.cpp:
##########
@@ -476,6 +656,155 @@ std::string GeoPolygon::as_wkt() const {
     return ss.str();
 }
 
+bool GeoPolygon::intersects(const GeoShape* rhs) const {
+    switch (rhs->type()) {
+    case GEO_SHAPE_POINT: {
+        const GeoPoint* point = (const GeoPoint*)rhs;
+        // 1. when polygon contain the point return true
+        if (_polygon->Contains(*point->point())) {
+            return true;
+        }
+        // 2. calculate the distance between the point and the closest point 
on the boundary
+        S2Point closest_point = _polygon->ProjectToBoundary(*point->point());
+        S1Angle distance(closest_point, *point->point());
+        return distance.radians() < 1e-2;
+    }
+    case GEO_SHAPE_LINE_STRING: {
+        const GeoLine* line = (const GeoLine*)rhs;
+        std::vector<std::unique_ptr<S2Polyline>> intersect_lines =
+                _polygon->IntersectWithPolyline(*line->polyline());
+        if (intersect_lines.empty()) {
+            int next;
+            // s2geometry may not return the correct result when the line is 
on the boundary.
+            for (int i = 0; i < _polygon->num_loops(); ++i) {
+                const S2Loop* loop = _polygon->loop(i);
+                for (int j = 0; j < loop->num_vertices(); ++j) {
+                    const S2Point& p = loop->vertex(j);
+                    S2Point closest_point = line->polyline()->Project(p, 
&next);
+                    S1Angle distance(closest_point, p);
+                    if (distance.radians() < 1e-2) {

Review Comment:
   btw, change it with the constexpr variable



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to