You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by "LemonLiTree (via GitHub)" <gi...@apache.org> on 2023/08/14 06:25:44 UTC
[GitHub] [doris] LemonLiTree opened a new pull request, #22933: [feature](geometry) Support geometry type and more Geo functions
LemonLiTree opened a new pull request, #22933:
URL: https://github.com/apache/doris/pull/22933
## Proposed changes
Issue Number: close #xxx
<!--Describe your changes.-->
## Further comments
If this is a relatively large or complex change, kick off the discussion at [dev@doris.apache.org](mailto:dev@doris.apache.org) by explaining why you chose the solution you did and what alternatives you considered, etc...
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700884381
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1293101257
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoMultiPoint : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPoint);
+
+public:
+ GeoMultiPoint();
+ ~GeoMultiPoint() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ GeoParseStatus from_coords(const GeoCoordinates& list);
+
+ std::unique_ptr<GeoCoordinates> to_coords() const;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOMULTIPOINT_H
^
```
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoMultiPoint : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPoint);
+
+public:
+ GeoMultiPoint();
+ ~GeoMultiPoint() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ GeoParseStatus from_coords(const GeoCoordinates& list);
+
+ std::unique_ptr<GeoCoordinates> to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoCoordinates> to_coords() const;
```
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoMultiPoint : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPoint);
+
+public:
+ GeoMultiPoint();
+ ~GeoMultiPoint() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
```
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoMultiPoint : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPoint);
+
+public:
+ GeoMultiPoint();
+ ~GeoMultiPoint() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ GeoParseStatus from_coords(const GeoCoordinates& list);
+
+ std::unique_ptr<GeoCoordinates> to_coords() const;
+
+ std::string as_wkt() const override;
+
+ GeoPoint* get_point_n(std::size_t n) const;
Review Comment:
warning: function 'get_point_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoPoint* get_point_n(std::size_t n) const;
```
##########
be/src/geo/util/GeoMultiPoint.h:
##########
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOINT_H
+#define DORIS_GEOMULTIPOINT_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoMultiPoint : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPoint);
+
+public:
+ GeoMultiPoint();
+ ~GeoMultiPoint() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POINT; }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ GeoParseStatus from_coords(const GeoCoordinates& list);
+
+ std::unique_ptr<GeoCoordinates> to_coords() const;
+
+ std::string as_wkt() const override;
+
+ GeoPoint* get_point_n(std::size_t n) const;
+
+ bool contains(const GeoShape* shape) const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoMultiPolygon.cpp:
##########
@@ -0,0 +1,121 @@
+// 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.
+
+#include "GeoMultiPolygon.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+
+namespace doris {
+
+GeoMultiPolygon::GeoMultiPolygon() = default;
+GeoMultiPolygon::~GeoMultiPolygon() = default;
+
+GeoParseStatus GeoMultiPolygon::from_coords(
+ const GeoCoordinateListCollections& coord_list_collections) {
+ for (int i = 0; i < coord_list_collections.coords_list_collections.size(); i++) {
+ std::unique_ptr<doris::GeoPolygon> polygon = GeoPolygon::create_unique();
+ if (polygon->from_coords(*coord_list_collections.coords_list_collections[i]) !=
+ GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(polygon.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinateListCollections> GeoMultiPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateListCollections> coords_collections(
+ new GeoCoordinateListCollections());
+ for (std::size_t i = 0; i < get_num_polygon(); ++i) {
+ const GeoPolygon* polygon = (const GeoPolygon*)GeoCollection::get_geometries_n(i);
+ if (polygon->is_empty()) continue;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (polygon->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ GeoParseStatus from_coords(const GeoCoordinateListCollections& coord_list_collections);
+
+ std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_polygon() const;
+
+ GeoPolygon* get_polygon_n(std::size_t n) const;
Review Comment:
warning: function 'get_polygon_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoPolygon* get_polygon_n(std::size_t n) const;
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ GeoParseStatus from_coords(const GeoCoordinateListCollections& coord_list_collections);
+
+ std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_polygon() const;
+
+ GeoPolygon* get_polygon_n(std::size_t n) const;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ GeoParseStatus from_coords(const GeoCoordinateListCollections& coord_list_collections);
+
+ std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_polygon() const;
Review Comment:
warning: function 'get_num_polygon' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::size_t get_num_polygon() const;
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOMULTIPOLYGON_H
^
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ GeoParseStatus from_coords(const GeoCoordinateListCollections& coord_list_collections);
+
+ std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoCoordinates to_coords() const;
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ GeoParseStatus from_coords(const GeoCoordinateListCollections& coord_list_collections);
+
+ std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_polygon() const;
+
+ GeoPolygon* get_polygon_n(std::size_t n) const;
+
+ std::string as_wkt() const override;
+
+ bool contains(const GeoShape* shape) const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoPoint.cpp:
##########
@@ -0,0 +1,228 @@
+// 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.
+
+#include "GeoPoint.h"
+
+#include <absl/strings/str_format.h>
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2earth.h>
+#include <s2/s2latlng.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/util/coding/coder.h>
+
+#include <iomanip>
+#include <sstream>
+
+namespace doris {
+GeoPoint::GeoPoint() : _point(new S2Point()) {}
+GeoPoint::~GeoPoint() = default;
+
+void GeoPoint::print_s2point(std::ostream& os, const S2Point& point) {
+ S2LatLng coord(point);
+ os << std::setprecision(12) << coord.lng().degrees() << " " << coord.lat().degrees();
+}
+
+static inline bool is_valid_lng_lat(double lng, double lat) {
+ return std::abs(lng) <= 180 && std::abs(lat) <= 90;
+}
+
+bool GeoPoint::is_valid() const {
+ return is_valid_lng_lat(x(), y());
+}
+
+// Return GEO_PARSE_OK, if and only if this can be converted to a valid S2Point
+GeoParseStatus GeoPoint::to_s2point(double lng, double lat, S2Point* point) {
+ if (!is_valid_lng_lat(lng, lat)) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ S2LatLng ll = S2LatLng::FromDegrees(lat, lng);
+ DCHECK(ll.is_valid()) << "invalid point, lng=" << lng << ", lat=" << lat;
+ *point = ll.ToPoint();
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPoint::to_s2point(const GeoCoordinate& coord, S2Point* point) {
+ return to_s2point(coord.x, coord.y, point);
+}
+
+GeoParseStatus GeoPoint::from_coord(double x, double y) {
+ return to_s2point(x, y, _point.get());
+}
+
+GeoParseStatus GeoPoint::from_coord(const GeoCoordinate& coord) {
+ return to_s2point(coord, _point.get());
+}
+
+GeoParseStatus GeoPoint::from_s2point(S2Point* point) {
+ *_point = *point;
+ return GEO_PARSE_OK;
+}
+
+//后面改成GeoCoordinate GeoPoint::to_coords(),现在涉及到wkb,暂时不动
+GeoCoordinates GeoPoint::to_coords() const {
+ GeoCoordinate coord;
+ coord.x = GeoPoint::x();
+ coord.y = GeoPoint::y();
+ GeoCoordinates coords;
+ coords.add(coord);
+ return coords;
+}
+
+std::unique_ptr<GeoCoordinate> GeoPoint::to_coord() const {
+ return std::make_unique<GeoCoordinate>(GeoPoint::x(), GeoPoint::y());
+}
+
+std::unique_ptr<S2Shape> GeoPoint::get_s2shape() const {
+ std::vector<S2Point> points;
+ points.emplace_back(*point());
+ return std::make_unique<S2PointVectorShape>(points);
+}
+
+bool GeoPoint::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return *_point == *(point->_point);
+ }
+ default:
+ return false;
+ }
+}
+
+bool GeoPoint::ComputeDistance(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* distance) {
+ S2LatLng x = S2LatLng::FromDegrees(x_lat, x_lng);
+ if (!x.is_valid()) {
+ return false;
+ }
+ S2LatLng y = S2LatLng::FromDegrees(y_lat, y_lng);
+ if (!y.is_valid()) {
+ return false;
+ }
+ *distance = S2Earth::GetDistanceMeters(x, y);
+ return true;
+}
+
+bool GeoPoint::ComputeAngleSphere(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* angle) {
+ S2LatLng x = S2LatLng::FromDegrees(x_lat, x_lng);
+ if (!x.is_valid()) {
+ return false;
+ }
+ S2LatLng y = S2LatLng::FromDegrees(y_lat, y_lng);
+ if (!y.is_valid()) {
+ return false;
+ }
+ *angle = (x.GetDistance(y)).degrees();
+ return true;
+}
+
+bool GeoPoint::ComputeAngle(GeoPoint* point1, GeoPoint* point2, GeoPoint* point3, double* angle) {
+ S2LatLng latLng1 = S2LatLng::FromDegrees(point1->x(), point1->y());
+ S2LatLng latLng2 = S2LatLng::FromDegrees(point2->x(), point2->y());
+ S2LatLng latLng3 = S2LatLng::FromDegrees(point3->x(), point3->y());
+
+ //If points 2 and 3 are the same or points 2 and 1 are the same, returns NULL.
+ if (latLng2.operator==(latLng1) || latLng2.operator==(latLng3)) {
+ return false;
+ }
+ double x = 0;
+ double y = 0;
+ //If points 2 and 3 are exactly antipodal or points 2 and 1 are exactly antipodal, returns NULL.
+ if (GeoPoint::ComputeAngleSphere(point1->x(), point1->y(), point2->x(), point2->y(), &x) &&
+ GeoPoint::ComputeAngleSphere(point3->x(), point3->y(), point2->x(), point2->y(), &y)) {
+ if (x == 180 || y == 180) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ //Computes the initial bearing (radians) from latLng2 to latLng3
+ double a = S2Earth::GetInitialBearing(latLng2, latLng3).radians();
+ //Computes the initial bearing (radians) from latLng2 to latLng1
+ double b = S2Earth::GetInitialBearing(latLng2, latLng1).radians();
+ //range [0, 2pi)
+ if (b - a < 0) {
+ *angle = b - a + 2 * M_PI;
+ } else {
+ *angle = b - a;
+ }
+ return true;
+}
+
+bool GeoPoint::ComputeAzimuth(GeoPoint* p1, GeoPoint* p2, double* angle) {
+ GeoPoint north;
+ north.from_coord(0, 90);
+ return GeoPoint::ComputeAngle(&north, p1, p2, angle);
+}
+
+std::string GeoPoint::as_wkt() const {
+ std::stringstream ss;
+ ss << "POINT ";
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ ss << "(";
+ print_s2point(ss, *_point);
+ ss << ")";
+ return ss.str();
+}
+
+std::unique_ptr<GeoShape> GeoPoint::boundary() const {
+ std::unique_ptr<GeoShape> point(GeoPoint::create_unique().release());
+ point->set_empty();
+ return point;
+}
+
+bool GeoPoint::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty() || !is_valid()) return false;
+ std::vector<S2Point> points;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
!is_valid()) { return false;
}
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOPOINT_H
^
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override { return !is_empty(); }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ [[nodiscard]] const S2Point* point() const { return _point.get(); }
+
+ [[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static bool ComputeDistance(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* distance);
+
+ static bool ComputeAngleSphere(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* angle);
+ static bool ComputeAngle(GeoPoint* p1, GeoPoint* p2, GeoPoint* p3, double* angle);
+ static bool ComputeAzimuth(GeoPoint* p1, GeoPoint* p2, double* angle);
+
+ std::string as_wkt() const override;
+
+ [[nodiscard]] std::size_t get_num_point() const override { return 1; }
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_valid() const override;
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override { return !is_empty(); }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ [[nodiscard]] const S2Point* point() const { return _point.get(); }
+
+ [[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static bool ComputeDistance(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* distance);
+
+ static bool ComputeAngleSphere(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* angle);
+ static bool ComputeAngle(GeoPoint* p1, GeoPoint* p2, GeoPoint* p3, double* angle);
+ static bool ComputeAzimuth(GeoPoint* p1, GeoPoint* p2, double* angle);
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override { return !is_empty(); }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ [[nodiscard]] const S2Point* point() const { return _point.get(); }
+
+ [[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static bool ComputeDistance(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* distance);
+
+ static bool ComputeAngleSphere(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* angle);
+ static bool ComputeAngle(GeoPoint* p1, GeoPoint* p2, GeoPoint* p3, double* angle);
+ static bool ComputeAzimuth(GeoPoint* p1, GeoPoint* p2, double* angle);
+
+ std::string as_wkt() const override;
+
+ [[nodiscard]] std::size_t get_num_point() const override { return 1; }
+
+ std::unique_ptr<GeoShape> boundary() const override;
+
+ bool add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const override;
+
+ //void add_to_s2point_index(S2PointIndex<int>& S2point_index, int i);
+
+ double x() const;
Review Comment:
warning: function 'x' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double x() const;
```
##########
be/src/geo/util/GeoPoint.cpp:
##########
@@ -0,0 +1,228 @@
+// 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.
+
+#include "GeoPoint.h"
+
+#include <absl/strings/str_format.h>
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2earth.h>
+#include <s2/s2latlng.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/util/coding/coder.h>
+
+#include <iomanip>
+#include <sstream>
+
+namespace doris {
+GeoPoint::GeoPoint() : _point(new S2Point()) {}
+GeoPoint::~GeoPoint() = default;
+
+void GeoPoint::print_s2point(std::ostream& os, const S2Point& point) {
+ S2LatLng coord(point);
+ os << std::setprecision(12) << coord.lng().degrees() << " " << coord.lat().degrees();
+}
+
+static inline bool is_valid_lng_lat(double lng, double lat) {
+ return std::abs(lng) <= 180 && std::abs(lat) <= 90;
+}
+
+bool GeoPoint::is_valid() const {
+ return is_valid_lng_lat(x(), y());
+}
+
+// Return GEO_PARSE_OK, if and only if this can be converted to a valid S2Point
+GeoParseStatus GeoPoint::to_s2point(double lng, double lat, S2Point* point) {
+ if (!is_valid_lng_lat(lng, lat)) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ S2LatLng ll = S2LatLng::FromDegrees(lat, lng);
+ DCHECK(ll.is_valid()) << "invalid point, lng=" << lng << ", lat=" << lat;
+ *point = ll.ToPoint();
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPoint::to_s2point(const GeoCoordinate& coord, S2Point* point) {
+ return to_s2point(coord.x, coord.y, point);
+}
+
+GeoParseStatus GeoPoint::from_coord(double x, double y) {
+ return to_s2point(x, y, _point.get());
+}
+
+GeoParseStatus GeoPoint::from_coord(const GeoCoordinate& coord) {
+ return to_s2point(coord, _point.get());
+}
+
+GeoParseStatus GeoPoint::from_s2point(S2Point* point) {
+ *_point = *point;
+ return GEO_PARSE_OK;
+}
+
+//后面改成GeoCoordinate GeoPoint::to_coords(),现在涉及到wkb,暂时不动
+GeoCoordinates GeoPoint::to_coords() const {
+ GeoCoordinate coord;
+ coord.x = GeoPoint::x();
+ coord.y = GeoPoint::y();
+ GeoCoordinates coords;
+ coords.add(coord);
+ return coords;
+}
+
+std::unique_ptr<GeoCoordinate> GeoPoint::to_coord() const {
+ return std::make_unique<GeoCoordinate>(GeoPoint::x(), GeoPoint::y());
+}
+
+std::unique_ptr<S2Shape> GeoPoint::get_s2shape() const {
+ std::vector<S2Point> points;
+ points.emplace_back(*point());
+ return std::make_unique<S2PointVectorShape>(points);
+}
+
+bool GeoPoint::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return *_point == *(point->_point);
+ }
+ default:
Review Comment:
warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'Vector3<double>' and 'Vector3<double>') to be ambiguous despite there being a unique best viable function [clang-diagnostic-ambiguous-reversed-operator]
```cpp
== *(point->_point);
^
```
<details>
<summary>Additional context</summary>
**thirdparty/installed/include/s2/util/math/vector.h:100:** ambiguity is between a regular call to this operator and a call with the argument order reversed
```cpp
bool operator==(const D& b) const {
^
```
</details>
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
Review Comment:
warning: function 'to_coord' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoCoordinate> to_coord() const;
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override { return !is_empty(); }
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_closed() const override { return !is_empty(); }
```
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_POINT; }
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1293091291
##########
be/src/geo/util/GeoLineString.cpp:
##########
@@ -0,0 +1,194 @@
+// 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.
+
+#include "GeoLineString.h"
+
+#include <s2/s2polyline.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoLineString::GeoLineString() = default;
+GeoLineString::~GeoLineString() = default;
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+bool GeoLineString::is_valid() const {
+ return polyline()->IsValid();
+}
+
+bool GeoLineString::is_closed() const {
+ return !is_empty() && polyline()->vertex(0) == polyline()->vertex(get_num_point() - 1);
Review Comment:
warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'const S2Point' (aka 'const Vector3<double>') and 'const S2Point') to be ambiguous despite there being a unique best viable function [clang-diagnostic-ambiguous-reversed-operator]
```cpp
return !is_empty() && polyline()->vertex(0) == polyline()->vertex(get_num_point() - 1);
^
```
<details>
<summary>Additional context</summary>
**thirdparty/installed/include/s2/util/math/vector.h:100:** ambiguity is between a regular call to this operator and a call with the argument order reversed
```cpp
bool operator==(const D& b) const {
^
```
</details>
##########
be/src/geo/util/GeoLineString.cpp:
##########
@@ -0,0 +1,194 @@
+// 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.
+
+#include "GeoLineString.h"
+
+#include <s2/s2polyline.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoLineString::GeoLineString() = default;
+GeoLineString::~GeoLineString() = default;
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+bool GeoLineString::is_valid() const {
+ return polyline()->IsValid();
+}
+
+bool GeoLineString::is_closed() const {
+ return !is_empty() && polyline()->vertex(0) == polyline()->vertex(get_num_point() - 1);
+}
+
+GeoParseStatus GeoLineString::to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. remove duplicate points
+ remove_duplicate_points(&points);
+ // 3. check if there is enough point
+ if (points.size() < 2) {
+ return GEO_PARSE_POLYLINE_LACK_VERTICES;
+ }
+ polyline->reset(new S2Polyline(points));
+ if (!(*polyline)->IsValid()) {
+ return GEO_PARSE_POLYLINE_INVALID;
+ }
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoLineString::from_coords(const GeoCoordinates& coords) {
+ return to_s2polyline(coords, &_polyline);
+}
+
+GeoCoordinates GeoLineString::to_coords() const {
+ GeoCoordinates coords;
+ for (int i = 0; i < GeoLineString::num_point(); ++i) {
+ GeoCoordinate coord;
+ coord.x = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Longitude(*GeoLineString::get_point(i)).degrees()));
+ coord.y = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Latitude(*GeoLineString::get_point(i)).degrees()));
+ coords.add(coord);
+ }
+ return coords;
+}
+
+std::unique_ptr<GeoCoordinates> GeoLineString::to_coords_ptr() const {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ for (int i = 0; i < GeoLineString::num_point(); ++i) {
+ GeoCoordinate coord;
+ coord.x = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Longitude(*GeoLineString::get_point(i)).degrees()));
+ coord.y = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Latitude(*GeoLineString::get_point(i)).degrees()));
+ coords->add(coord);
+ }
+ return coords;
+}
+
+double GeoLineString::length() const {
+ return _polyline->GetLength().radians();
+}
+
+std::unique_ptr<S2Shape> GeoLineString::get_s2shape() const {
+ return std::make_unique<S2Polyline::Shape>(polyline());
+}
+
+std::string GeoLineString::as_wkt() const {
+ std::stringstream ss;
+ ss << "LINESTRING ";
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+ for (int i = 0; i < _polyline->num_vertices(); ++i) {
+ if (i != 0) {
+ ss << ", ";
+ }
+ GeoPoint::print_s2point(ss, _polyline->vertex(i));
+ }
+ ss << ")";
+ return ss.str();
+}
+
+int GeoLineString::num_point() const {
+ return _polyline->num_vertices();
+}
+
+S2Point* GeoLineString::get_point(int i) const {
+ return const_cast<S2Point*>(&(_polyline->vertex(i)));
+}
+
+void GeoLineString::encode(std::string* buf, size_t& data_size) {
+ Encoder encoder;
+ _polyline->Encode(&encoder);
+ data_size = encoder.length();
+ buf->append(encoder.base(), encoder.length());
+}
+
+bool GeoLineString::decode(const void* data, size_t size) {
+ Decoder decoder(data, size);
+ _polyline.reset(new S2Polyline());
+ return _polyline->Decode(&decoder);
+}
+
+double GeoLineString::line_locate_point(GeoPoint* point) {
+ int num = num_point();
+ return _polyline->UnInterpolate(_polyline->Project(*point->point(), &num), num);
+}
+
+std::size_t GeoLineString::get_num_point() const {
+ if (is_empty()) return 0;
+ return _polyline->num_vertices();
+}
+
+std::unique_ptr<GeoShape> GeoLineString::boundary() const {
+ std::unique_ptr<GeoMultiPoint> multipoint = GeoMultiPoint::create_unique();
+ if (is_empty() || is_ring()) {
+ multipoint->set_empty();
+ return multipoint;
+ }
+
+ std::unique_ptr<GeoPoint> point1 = GeoPoint::create_unique();
+ std::unique_ptr<GeoPoint> point2 = GeoPoint::create_unique();
+ point1->from_s2point(get_point(0));
+ point2->from_s2point(get_point(num_point() - 1));
+
+ if (point1->contains(point2.get())) {
+ multipoint->set_empty();
+ return multipoint;
+ }
+
+ multipoint->add_one_geometry(point1.release());
+ multipoint->add_one_geometry(point2.release());
+
+ return multipoint;
+}
+
+bool GeoLineString::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty() || !is_valid()) return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (is_empty() || !is_valid()) { return false;
}
```
##########
be/src/geo/util/GeoLineString.cpp:
##########
@@ -0,0 +1,194 @@
+// 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.
+
+#include "GeoLineString.h"
+
+#include <s2/s2polyline.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoLineString::GeoLineString() = default;
+GeoLineString::~GeoLineString() = default;
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+bool GeoLineString::is_valid() const {
+ return polyline()->IsValid();
+}
+
+bool GeoLineString::is_closed() const {
+ return !is_empty() && polyline()->vertex(0) == polyline()->vertex(get_num_point() - 1);
+}
+
+GeoParseStatus GeoLineString::to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. remove duplicate points
+ remove_duplicate_points(&points);
+ // 3. check if there is enough point
+ if (points.size() < 2) {
+ return GEO_PARSE_POLYLINE_LACK_VERTICES;
+ }
+ polyline->reset(new S2Polyline(points));
+ if (!(*polyline)->IsValid()) {
+ return GEO_PARSE_POLYLINE_INVALID;
+ }
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoLineString::from_coords(const GeoCoordinates& coords) {
+ return to_s2polyline(coords, &_polyline);
+}
+
+GeoCoordinates GeoLineString::to_coords() const {
+ GeoCoordinates coords;
+ for (int i = 0; i < GeoLineString::num_point(); ++i) {
+ GeoCoordinate coord;
+ coord.x = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Longitude(*GeoLineString::get_point(i)).degrees()));
+ coord.y = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Latitude(*GeoLineString::get_point(i)).degrees()));
+ coords.add(coord);
+ }
+ return coords;
+}
+
+std::unique_ptr<GeoCoordinates> GeoLineString::to_coords_ptr() const {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ for (int i = 0; i < GeoLineString::num_point(); ++i) {
+ GeoCoordinate coord;
+ coord.x = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Longitude(*GeoLineString::get_point(i)).degrees()));
+ coord.y = std::stod(absl::StrFormat(
+ "%.12f", S2LatLng::Latitude(*GeoLineString::get_point(i)).degrees()));
+ coords->add(coord);
+ }
+ return coords;
+}
+
+double GeoLineString::length() const {
+ return _polyline->GetLength().radians();
+}
+
+std::unique_ptr<S2Shape> GeoLineString::get_s2shape() const {
+ return std::make_unique<S2Polyline::Shape>(polyline());
+}
+
+std::string GeoLineString::as_wkt() const {
+ std::stringstream ss;
+ ss << "LINESTRING ";
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+ for (int i = 0; i < _polyline->num_vertices(); ++i) {
+ if (i != 0) {
+ ss << ", ";
+ }
+ GeoPoint::print_s2point(ss, _polyline->vertex(i));
+ }
+ ss << ")";
+ return ss.str();
+}
+
+int GeoLineString::num_point() const {
+ return _polyline->num_vertices();
+}
+
+S2Point* GeoLineString::get_point(int i) const {
+ return const_cast<S2Point*>(&(_polyline->vertex(i)));
+}
+
+void GeoLineString::encode(std::string* buf, size_t& data_size) {
+ Encoder encoder;
+ _polyline->Encode(&encoder);
+ data_size = encoder.length();
+ buf->append(encoder.base(), encoder.length());
+}
+
+bool GeoLineString::decode(const void* data, size_t size) {
+ Decoder decoder(data, size);
+ _polyline.reset(new S2Polyline());
+ return _polyline->Decode(&decoder);
+}
+
+double GeoLineString::line_locate_point(GeoPoint* point) {
+ int num = num_point();
+ return _polyline->UnInterpolate(_polyline->Project(*point->point(), &num), num);
+}
+
+std::size_t GeoLineString::get_num_point() const {
+ if (is_empty()) return 0;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (is_empty()) { return 0;
}
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOLINESTRING_H
^
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
Review Comment:
warning: function 'get_s2shape' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ std::string as_wkt() const override;
+
+ int num_point() const;
+ S2Point* get_point(int i) const;
+
+ double line_locate_point(GeoPoint* point);
+
+ [[nodiscard]] std::size_t get_num_point() const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& list);
+
+ std::unique_ptr<GeoCoordinateLists> to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoCoordinateLists> to_coords() const;
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& list);
+
+ std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_line() const;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_closed() const override;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_valid() const override;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
Review Comment:
warning: function 'to_coords_ptr' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoCoordinates to_coords() const;
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
Review Comment:
warning: function 'polyline' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const S2Polyline* polyline() const { return _polyline.get(); }
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
```
##########
be/src/geo/util/GeoMultiPoint.cpp:
##########
@@ -0,0 +1,88 @@
+// 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.
+
+#include "GeoMultiPoint.h"
+
+#include <sstream>
+
+namespace doris {
+
+GeoMultiPoint::GeoMultiPoint() = default;
+GeoMultiPoint::~GeoMultiPoint() = default;
+
+GeoParseStatus GeoMultiPoint::from_coords(const GeoCoordinates& coord_list) {
+ for (int i = 0; i < coord_list.coords.size(); i++) {
+ std::unique_ptr<doris::GeoPoint> point = GeoPoint::create_unique();
+ if (point->from_coord(coord_list.coords[i]) != GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(point.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinates> GeoMultiPoint::to_coords() const {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ for (std::size_t i = 0; i < get_num_point(); ++i) {
+ const GeoPoint* point = (const GeoPoint*)GeoCollection::get_geometries_n(i);
+ if (point->is_empty()) continue;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (point->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoMultiLineString.cpp:
##########
@@ -0,0 +1,123 @@
+// 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.
+
+#include "GeoMultiLineString.h"
+
+#include <sstream>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoMultiLineString::GeoMultiLineString() = default;
+GeoMultiLineString::~GeoMultiLineString() = default;
+
+GeoParseStatus GeoMultiLineString::from_coords(const GeoCoordinateLists& coords_list) {
+ for (int i = 0; i < coords_list.coords_list.size(); i++) {
+ std::unique_ptr<doris::GeoLineString> line = GeoLineString::create_unique();
+ if (line->from_coords(*coords_list.coords_list[i]) != GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(line.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinateLists> GeoMultiLineString::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coords_list(new GeoCoordinateLists());
+ for (std::size_t i = 0; i < get_num_line(); ++i) {
+ const GeoLineString* line = (const GeoLineString*)GeoCollection::get_geometries_n(i);
+ if (line->is_empty()) continue;
+ std::unique_ptr<GeoCoordinates> coords = line->to_coords_ptr();
+ coords_list->add(coords.release());
+ }
+ return coords_list;
+}
+
+std::size_t GeoMultiLineString::get_num_line() const {
+ return GeoCollection::get_num_geometries();
+}
+
+std::string GeoMultiLineString::as_wkt() const {
+ std::stringstream ss;
+ ss << "MULTILINESTRING ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ ss << "(";
+ for (int i = 0; i < get_num_line(); ++i) {
+ if (i != 0) {
+ ss << ", ";
+ }
+ const GeoLineString* line = (const GeoLineString*)GeoCollection::get_geometries_n(i);
+ if (line->is_empty()) {
+ ss << "EMPTY";
+ continue;
+ }
+
+ ss << "(";
+
+ for (std::size_t g = 0; g < line->num_point(); g++) {
+ if (g != 0) {
+ ss << ", ";
+ }
+ GeoPoint::print_s2point(ss, *line->get_point(g));
+ }
+
+ ss << ")";
+ }
+ ss << ")";
+ return ss.str();
+}
+
+GeoLineString* GeoMultiLineString::get_line_string_n(std::size_t n) const {
+ return (GeoLineString*)GeoCollection::get_geometries_n(n);
+}
+
+bool GeoMultiLineString::contains(const GeoShape* shape) const {
+ return GeoCollection::contains(shape);
+}
+
+std::unique_ptr<GeoShape> GeoMultiLineString::boundary() const {
+ std::unique_ptr<GeoMultiPoint> multipoint = GeoMultiPoint::create_unique();
+ if (is_empty()) {
+ multipoint->set_empty();
+ return multipoint;
+ }
+
+ for (std::size_t i = 0; i < get_num_line(); ++i) {
+ const GeoLineString* line = (const GeoLineString*)GeoCollection::get_geometries_n(i);
+ if (line->is_empty() || line->is_ring()) {
+ continue;
+ }
+ std::unique_ptr<GeoPoint> point1 = GeoPoint::create_unique();
+ std::unique_ptr<GeoPoint> point2 = GeoPoint::create_unique();
+ point1->from_s2point(line->get_point(0));
+ point2->from_s2point(line->get_point(line->num_point() - 1));
+ multipoint->add_one_geometry(point1.release());
+ multipoint->add_one_geometry(point2.release());
+ }
+
+ if (multipoint->get_num_point() == 0) multipoint->set_empty();
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (multipoint->get_num_point() == 0) { multipoint->set_empty();
}
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ std::string as_wkt() const override;
+
+ int num_point() const;
+ S2Point* get_point(int i) const;
Review Comment:
warning: function 'get_point' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] S2Point* get_point(int i) const;
```
##########
be/src/geo/util/GeoMultiLineString.cpp:
##########
@@ -0,0 +1,123 @@
+// 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.
+
+#include "GeoMultiLineString.h"
+
+#include <sstream>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoMultiLineString::GeoMultiLineString() = default;
+GeoMultiLineString::~GeoMultiLineString() = default;
+
+GeoParseStatus GeoMultiLineString::from_coords(const GeoCoordinateLists& coords_list) {
+ for (int i = 0; i < coords_list.coords_list.size(); i++) {
+ std::unique_ptr<doris::GeoLineString> line = GeoLineString::create_unique();
+ if (line->from_coords(*coords_list.coords_list[i]) != GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(line.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinateLists> GeoMultiLineString::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coords_list(new GeoCoordinateLists());
+ for (std::size_t i = 0; i < get_num_line(); ++i) {
+ const GeoLineString* line = (const GeoLineString*)GeoCollection::get_geometries_n(i);
+ if (line->is_empty()) continue;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (line->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoLineString.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef DORIS_GEOLINESTRING_H
+#define DORIS_GEOLINESTRING_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polyline;
+
+namespace doris {
+
+class GeoLineString : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoLineString);
+
+public:
+ GeoLineString();
+ ~GeoLineString() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2polyline(const GeoCoordinates& coords,
+ std::unique_ptr<S2Polyline>* polyline);
+
+ GeoParseStatus from_coords(const GeoCoordinates& coords);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinates> to_coords_ptr() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ [[nodiscard]] double length() const;
+
+ const S2Polyline* polyline() const { return _polyline.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ std::string as_wkt() const override;
+
+ int num_point() const;
Review Comment:
warning: function 'num_point' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] int num_point() const;
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOMULTILINESTRING_H
^
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& list);
+
+ std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_line() const;
Review Comment:
warning: function 'get_num_line' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::size_t get_num_line() const;
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& list);
+
+ std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_line() const;
+
+ std::string as_wkt() const override;
+
+ GeoLineString* get_line_string_n(std::size_t n) const;
Review Comment:
warning: function 'get_line_string_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoLineString* get_line_string_n(std::size_t n) const;
```
##########
be/src/geo/util/GeoMultiLineString.h:
##########
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef DORIS_GEOMULTILINESTRING_H
+#define DORIS_GEOMULTILINESTRING_H
+
+#include "GeoCollection.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+
+class GeoMultiLineString : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiLineString);
+
+public:
+ GeoMultiLineString();
+ ~GeoMultiLineString() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_LINE_STRING; }
+
+ [[nodiscard]] int get_dimension() const override { return 1; }
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& list);
+
+ std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_line() const;
+
+ std::string as_wkt() const override;
+
+ GeoLineString* get_line_string_n(std::size_t n) const;
+
+ bool contains(const GeoShape* shape) const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1293072968
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+class S2Cap;
+
+namespace doris {
+class GeoCircle : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (!shape->is_empty()) { collection->add_one_geometry(shape.release());
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (is_empty()) { return 0;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if (polygon->is_empty()) continue;
+ if (!polygon->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* line_string =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ if (line_string->is_empty()) continue;
+ if (!line_string->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ if (polygon->is_empty()) continue;
+ if (!polygon->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+class S2Cap;
+
+namespace doris {
+class GeoCircle : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
+
+ double get_area() const;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_valid() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) { GeoShape::encode_to(buf); };
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
Review Comment:
warning: function 'get_num_geometries' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::size_t get_num_geometries() const override;
```
##########
be/src/geo/util/GeoLineString.cpp:
##########
@@ -0,0 +1,194 @@
+// 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.
+
+#include "GeoLineString.h"
+
+#include <s2/s2polyline.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoLineString::GeoLineString() = default;
+GeoLineString::~GeoLineString() = default;
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
Review Comment:
warning: ISO C++20 considers use of overloaded operator '!=' (with operand types '__gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type' (aka 'Vector3<double>') and '__gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type') to be ambiguous despite there being a unique best viable function with non-reversed arguments [clang-diagnostic-ambiguous-reversed-operator]
```cpp
if ((*points)[rhs] != (*points)[lhs]) {
^
```
<details>
<summary>Additional context</summary>
**thirdparty/installed/include/s2/util/math/vector.h:104:** candidate function with non-reversed arguments
```cpp
bool operator!=(const D& b) const { return !(AsD() == b); }
^
```
**thirdparty/installed/include/s2/util/math/vector.h:100:** ambiguous candidate function with reversed arguments
```cpp
bool operator==(const D& b) const {
^
```
</details>
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
Review Comment:
warning: function 'begin' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const_iterator begin() const { return geometries.begin(); };
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
Review Comment:
warning: function 'end' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const_iterator end() const { return geometries.end(); };
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+class S2Cap;
+
+namespace doris {
+class GeoCircle : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
+
+ double get_area() const;
Review Comment:
warning: function 'get_area' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double get_area() const;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
!g->is_valid()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (collection->get_num_geometries() == 0) { collection->set_empty();
}
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+class S2Cap;
+
+namespace doris {
+class GeoCircle : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if (polygon->is_empty()) continue;
+ if (!polygon->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
s_empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
_empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if (polygon->is_empty()) continue;
+ if (!polygon->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
>is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if (polygon->is_empty()) continue;
+ if (!polygon->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* line_string =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ if (line_string->is_empty()) continue;
+ if (!line_string->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
y()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
index) const { {
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
t->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_closed() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) { GeoShape::encode_to(buf); };
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
+
+ // Returns the number of geometries in this collection
+ GeoShape* get_geometries_n(std::size_t n) const override;
Review Comment:
warning: function 'get_geometries_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShape* get_geometries_n(std::size_t n) const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) { GeoShape::encode_to(buf); };
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
+
+ // Returns the number of geometries in this collection
+ GeoShape* get_geometries_n(std::size_t n) const override;
+
+ std::string as_wkt() const override;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ [[nodiscard]] std::size_t get_num_point() const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+
+namespace doris {
+class GeoCollection : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const { return geometries.begin(); };
+
+ const_iterator end() const { return geometries.end(); };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) { GeoShape::encode_to(buf); };
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
+
+ // Returns the number of geometries in this collection
+ GeoShape* get_geometries_n(std::size_t n) const override;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700911053
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702094727
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [feature](geometry) Support geometry type and more Geo functions [doris]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed pull request #22933: [feature](geometry) Support geometry type and more Geo functions
URL: https://github.com/apache/doris/pull/22933
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1293026907
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+
+class S2Cap;
+
+namespace doris {
+ class GeoCircle : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+ public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+
+class S2Cap;
+
+namespace doris {
+ class GeoCircle : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+ public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+
+class S2Cap;
+
+namespace doris {
+ class GeoCircle : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+ public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
+
+ double get_area() const;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOCIRCLE_H
^
```
##########
be/src/geo/util/GeoCircle.h:
##########
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef DORIS_GEOCIRCLE_H
+#define DORIS_GEOCIRCLE_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+
+class S2Cap;
+
+namespace doris {
+ class GeoCircle : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCircle);
+
+ public:
+ GeoCircle();
+ ~GeoCircle() override;
+
+ GeoParseStatus to_s2cap(double lng, double lat, double radius);
+
+ GeoShapeType type() const override { return GEO_SHAPE_CIRCLE; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ bool contains(const GeoShape* rhs) const override;
+ std::string as_wkt() const override;
+
+ double get_area() const;
Review Comment:
warning: function 'get_area' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double get_area() const;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if(collection->get_num_geometries()==0) { collection->set_empty();
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
d()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if(!shape->is_empty()) {
collection->add_one_geometry(shape.release());
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
const { {
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if(is_empty()) { return 0;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
empty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if(linestring->is_empty()) continue;
+ if(!linestring->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if(linestring->is_empty()) continue;
+ if(!linestring->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if(polygon->is_empty()) continue;
+ if(!polygon->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
y()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if(linestring->is_empty()) continue;
+ if(!linestring->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if(polygon->is_empty()) continue;
+ if(!polygon->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* line_string = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ if(line_string->is_empty()) continue;
+ if(!line_string->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ if(polygon->is_empty()) continue;
+ if(!polygon->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
)) { continue;
}
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if(linestring->is_empty()) continue;
+ if(!linestring->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if(polygon->is_empty()) continue;
+ if(!polygon->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* line_string = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ if(line_string->is_empty()) continue;
+ if(!line_string->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
mp->get_geometries_n(i));
ontinue; {
}
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
Review Comment:
warning: function 'begin' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const_iterator begin() const
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,347 @@
+// 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.
+
+#include "GeoCollection.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPolygon.h"
+#include <sstream>
+
+namespace doris {
+
+ GeoCollection::GeoCollection() = default;
+ GeoCollection::~GeoCollection() = default;
+
+ bool GeoCollection::is_valid() const {
+ for(const auto& g : geometries) {
+ if(!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool GeoCollection::is_closed() const {
+ for(const auto& g : geometries) {
+ if(!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape){
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+ }
+
+ std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+ }
+
+ GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+ }
+
+ std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()){
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if(i != geometries.size()-1){
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+ }
+
+ bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(point)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING:{
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(line)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON:{
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for(const auto& g : geometries) {
+ if(!g->contains(polygon)){
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION:{
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for(const auto& g1 : collection->geometries) {
+ for(const auto& g2 : geometries) {
+ if(!g2->contains(g1.get())){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ std::size_t GeoCollection::get_num_point() const {
+ if(is_empty()) return 0;
+ std::size_t num_point = 0;
+ for(const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+ }
+
+ std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if(is_empty()){
+ collection->set_empty();
+ return collection;
+ }
+
+ for(const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if(!shape->is_empty())
+ collection->add_one_geometry(shape.release());
+ }
+ if(collection->get_num_geometries()==0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+ }
+
+ std::unique_ptr<GeoCollection> GeoCollection::to_homogenize(){
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for(const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp = dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp = dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if(multi_point->get_num_point() == 1){
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ }else if(multi_point->get_num_point() > 1){
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_linestring->get_num_line() == 1){
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ }else if(multi_linestring->get_num_line() > 1){
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if(multi_polygon->get_num_polygon() == 1){
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ }else if(multi_polygon->get_num_polygon() > 1){
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+ }
+
+ bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if(is_empty()) return false;
+ for(const auto& g : geometries) {
+ if(g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if(point->is_empty()) continue;
+ if(!point->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if(linestring->is_empty()) continue;
+ if(!linestring->add_to_s2shape_index(S2shape_index)){
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if(polygon->is_empty()) continue;
+ if(!polygon->add_to_s2shape_index(S2shape_index)){
+ return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
pty()) { continue;
}
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOCOLLECTION_H
^
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_valid() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) {
+ GeoShape::encode_to(buf);
+ };
+
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
Review Comment:
warning: function 'get_num_geometries' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::size_t get_num_geometries() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) {
+ GeoShape::encode_to(buf);
+ };
+
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
+
+ // Returns the number of geometries in this collection
+ GeoShape* get_geometries_n(std::size_t n) const override;
+
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_closed() const override;
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
Review Comment:
warning: function 'end' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const_iterator end() const
```
##########
be/src/geo/util/GeoCollection.h:
##########
@@ -0,0 +1,108 @@
+// 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.
+
+#ifndef DORIS_GEOCOLLECTION_H
+#define DORIS_GEOCOLLECTION_H
+
+#include "common/factory_creator.h"
+#include "GeoShape.h"
+#include "GeoPoint.h"
+#include "GeoLineString.h"
+#include "GeoPolygon.h"
+
+namespace doris {
+ class GeoCollection : public GeoShape{
+ ENABLE_FACTORY_CREATOR(GeoCollection);
+
+ public:
+ using const_iterator = std::vector<std::unique_ptr<GeoShape>>::const_iterator;
+
+ using iterator = std::vector<std::unique_ptr<GeoShape>>::iterator;
+
+ const_iterator begin() const
+ {
+ return geometries.begin();
+ };
+
+ const_iterator end() const
+ {
+ return geometries.end();
+ };
+
+ GeoCollection();
+ ~GeoCollection() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_GEOMETRY_COLLECTION; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ void encode_to(std::string* buf) {
+ GeoShape::encode_to(buf);
+ };
+
+
+ [[nodiscard]] int get_dimension() const override {
+ if (get_num_geometries() == 0) {
+ return -1;
+ }
+
+ int dim = get_geometries_n(0)->get_dimension();
+ for (int i = 1; i < get_num_geometries(); i++) {
+ if (dim < get_geometries_n(i)->get_dimension()) {
+ dim = get_geometries_n(i)->get_dimension();
+ }
+ }
+
+ return dim;
+ }
+
+ GeoParseStatus add_one_geometry(GeoShape* shape);
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_geometries() const override;
+
+ // Returns the number of geometries in this collection
+ GeoShape* get_geometries_n(std::size_t n) const override;
Review Comment:
warning: function 'get_geometries_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShape* get_geometries_n(std::size_t n) const override;
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700799532
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700713954
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1311056800
##########
be/src/geo/util/GeoMultiPolygon.cpp:
##########
@@ -0,0 +1,121 @@
+// 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.
+
+#include "GeoMultiPolygon.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+
+namespace doris {
+
+GeoMultiPolygon::GeoMultiPolygon() = default;
+GeoMultiPolygon::~GeoMultiPolygon() = default;
+
+GeoParseStatus GeoMultiPolygon::from_coords(
+ const GeoCoordinateListCollections& coord_list_collections) {
+ for (int i = 0; i < coord_list_collections.coords_list_collections.size(); i++) {
+ std::unique_ptr<doris::GeoPolygon> polygon = GeoPolygon::create_unique();
+ if (polygon->from_coords(*coord_list_collections.coords_list_collections[i]) !=
+ GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(polygon.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinateListCollections> GeoMultiPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateListCollections> coords_collections(
+ new GeoCoordinateListCollections());
+ for (std::size_t i = 0; i < get_num_polygon(); ++i) {
+ const GeoPolygon* polygon = (const GeoPolygon*)GeoCollection::get_geometries_n(i);
+ if (polygon->is_empty()) continue;
+ std::unique_ptr<GeoCoordinateLists> coord = polygon->to_coords();
+ coords_collections->add(coord.release());
+ }
+ return coords_collections;
+}
+
+std::size_t GeoMultiPolygon::get_num_polygon() const {
+ return GeoCollection::get_num_geometries();
+}
+
+std::string GeoMultiPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "MULTIPOLYGON ";
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ ss << "(";
+
+ for (int i = 0; i < get_num_polygon(); ++i) {
+ if (i != 0) {
+ ss << ", ";
+ }
+ const GeoPolygon* polygon = (const GeoPolygon*)GeoCollection::get_geometries_n(i);
+ if (polygon->is_empty()) {
+ ss << "EMPTY";
+ } else {
+ GeoPolygon::print_coords(ss, *polygon);
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+GeoPolygon* GeoMultiPolygon::get_polygon_n(std::size_t n) const {
+ return (GeoPolygon*)GeoCollection::get_geometries_n(n);
+}
+
+bool GeoMultiPolygon::contains(const GeoShape* shape) const {
+ return GeoCollection::contains(shape);
+}
+
+std::unique_ptr<GeoShape> GeoMultiPolygon::boundary() const {
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ if (is_empty()) {
+ multi_linestring->set_empty();
+ return multi_linestring;
+ }
+
+ std::unique_ptr<GeoCoordinateListCollections> coords_list_collections = to_coords();
+
+ if (coords_list_collections->coords_list_collections.size() == 1 &&
+ coords_list_collections->coords_list_collections[0]->coords_list.size() == 1) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(
+ *coords_list_collections->coords_list_collections[0]->coords_list[0]);
+ return linestring;
+ }
+
+ for (int i = 0; i < coords_list_collections->coords_list_collections.size(); ++i) {
+ for (int j = 0; j < coords_list_collections->coords_list_collections[i]->coords_list.size();
+ ++j) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(
Review Comment:
warning: ignoring return value of function declared with 'nodiscard' attribute [clang-diagnostic-unused-result]
```cpp
linestring->from_coords(
^
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
+ return false;
+ }
+ return true;
+}
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. check if it is a closed loop
+ if (!is_loop_closed(points)) {
+ return GEO_PARSE_LOOP_NOT_CLOSED;
+ }
+ // 3. remove duplicate points
+ remove_duplicate_points(&points);
+ // 4. remove last point
+ points.resize(points.size() - 1);
+ // 5. check if there is enough point
+ if (points.size() < 3) {
+ return GEO_PARSE_LOOP_LACK_VERTICES;
+ }
+ loop->reset(new S2Loop(points));
+ if (!(*loop)->IsValid()) {
+ return GEO_PARSE_LOOP_INVALID;
+ }
+ (*loop)->Normalize();
+ return GEO_PARSE_OK;
+}
+
+static GeoParseStatus to_s2polygon(const GeoCoordinateLists& coords_list,
+ std::unique_ptr<S2Polygon>* polygon) {
+ std::vector<std::unique_ptr<S2Loop>> loops(coords_list.coords_list.size());
+ for (int i = 0; i < coords_list.coords_list.size(); ++i) {
+ auto res = to_s2loop(*coords_list.coords_list[i], &loops[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ if (i != 0 && !(loops[0]->Contains(*loops[i]))) {
+ return GEO_PARSE_POLYGON_NOT_HOLE;
+ }
+ }
+ polygon->reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+bool GeoPolygon::is_valid() const {
+ return polygon()->IsValid();
+}
+
+bool GeoPolygon::is_closed() const {
+ return polygon()->is_full();
+}
+
+GeoParseStatus GeoPolygon::from_coords(const GeoCoordinateLists& list) {
+ return to_s2polygon(list, &_polygon);
+}
+
+const std::unique_ptr<GeoCoordinateLists> GeoPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coordss(new GeoCoordinateLists());
+ for (int i = 0; i < GeoPolygon::num_loops(); ++i) {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ S2Loop* loop = GeoPolygon::get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ GeoCoordinate coord;
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(j)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(j)).degrees()));
+ coords->add(coord);
+ if (j == loop->num_vertices() - 1) {
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(0)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(0)).degrees()));
+ coords->add(coord);
+ }
+ }
+ coordss->add(coords.release());
+ }
+ return coordss;
+}
+
+GeoParseStatus GeoPolygon::from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops) {
+ _polygon.reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPolygon::from_s2polygon(std::unique_ptr<S2Polygon> s2polygon) {
+ _polygon.reset(s2polygon.release());
+ return GEO_PARSE_OK;
+}
+
+double GeoPolygon::get_perimeter() const {
+ double perimeter = 0;
+ std::unique_ptr<S2Shape> shape = get_s2shape();
+ for (int i = 0; i < shape->num_edges(); i++) {
+ S2Shape::Edge e = shape->edge(i);
+ S1ChordAngle angle(e.v0, e.v1);
+ perimeter += angle.radians();
+ }
+ return perimeter;
+}
+
+std::unique_ptr<S2Shape> GeoPolygon::get_s2shape() const {
+ return std::make_unique<S2Polygon::Shape>(_polygon.get());
+}
+
+bool GeoPolygon::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return _polygon->Contains(*point->point());
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ return _polygon->Contains(*line->polyline());
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ return _polygon->Contains(*polygon->polygon());
+ }
+ default:
+ return false;
+ }
+}
+
+void GeoPolygon::print_coords(std::ostream& os, const GeoPolygon& polygon) {
+ os << "(";
+ for (int i = 0; i < polygon.num_loops(); ++i) {
+ if (i != 0) {
+ os << ", ";
+ }
+ os << "(";
+ const S2Loop* loop = polygon.get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ if (j != 0) {
+ os << ", ";
+ }
+ GeoPoint::print_s2point(os, loop->vertex(j));
+ }
+ os << ", ";
+ GeoPoint::print_s2point(os, loop->vertex(0));
+ os << ")";
+ }
+ os << ")";
+}
+
+std::string GeoPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "POLYGON ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ print_coords(ss, *this);
+ return ss.str();
+}
+
+int GeoPolygon::num_loops() const {
+ return _polygon->num_loops();
+}
+
+double GeoPolygon::get_area() const {
+ return _polygon->GetArea();
+}
+
+S2Loop* GeoPolygon::get_loop(int i) const {
+ return _polygon->loop(i);
+}
+
+std::size_t GeoPolygon::get_num_point() const {
+ if (is_empty()) return 0;
+ return _polygon->num_vertices() + _polygon->num_loops();
+}
+
+std::unique_ptr<GeoShape> GeoPolygon::boundary() const {
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ if (is_empty()) {
+ multi_linestring->set_empty();
+ return multi_linestring;
+ }
+
+ std::unique_ptr<GeoCoordinateLists> coords_list = to_coords();
+
+ if (coords_list->coords_list.size() == 1) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(*coords_list->coords_list[0]);
Review Comment:
warning: ignoring return value of function declared with 'nodiscard' attribute [clang-diagnostic-unused-result]
```cpp
linestring->from_coords(*coords_list->coords_list[0]);
^
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual GeoShapeType type() const = 0;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) const {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+
+ S2ClosestEdgeQuery query1(&shape_index1);
+
+ query1.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result1 = query1.FindClosestEdge(&target);
+
+ if (result1.edge_id() == -1) {
+ //这里表示没找到最近的edge,应该返回失败,理论上不会走到这里,因为set_include_interiors(false);
+ return nullptr;
+ }
+
+ // Get the edge from index1 (edge1) that is closest to index2.
+ S2Shape::Edge edge1 = query1.GetEdge(result1);
+
+ // Now find the edge from index2 (edge2) that is closest to edge1.
+ S2ClosestEdgeQuery query2(&shape_index2);
+ query2.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::EdgeTarget target2(edge1.v0, edge1.v1);
+ auto result2 = query2.FindClosestEdge(&target2);
+
+ // what if result2 has no edges?
+ if (result2.is_interior()) {
+ //这里应该返回报错
+ return nullptr;
+ //throw Exception("S2ClosestEdgeQuery result is interior!");
+ }
+
+ S2Shape::Edge edge2 = query2.GetEdge(result2);
+
+ std::unique_ptr<GeoPoint> res_point = GeoPoint::create_unique();
+
+ S2Point s2Point = S2::GetEdgePairClosestPoints(edge1.v0, edge1.v1, edge2.v0, edge2.v1).first;
+ res_point->from_s2point(&s2Point);
+
+ return res_point;
+}
+
+bool GeoShape::dwithin(const GeoShape* shape, double distance) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ S2ClosestEdgeQuery query(&shape_index1);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result = query.FindClosestEdge(&target);
+
+ return S2Earth::RadiansToMeters(result.distance().ToAngle().radians()) <= distance;
+}
+
+std::unique_ptr<GeoShape> one_geo_buffer(S2BufferOperation::Options& options,
+ MutableS2ShapeIndex& shape_index) {
+ auto output = std::make_unique<S2Polygon>();
+ S2BufferOperation op(std::make_unique<s2builderutil::S2PolygonLayer>(output.get()), options);
+
+ op.AddShapeIndex(shape_index);
+
+ S2Error error;
+ if (!op.Build(&error)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+ std::unique_ptr<GeoPolygon> res_polygon = GeoPolygon::create_unique();
+ res_polygon->from_s2polygon(std::move(output));
+ return res_polygon;
+}
+
+std::unique_ptr<GeoShape> GeoShape::buffer(double buffer_radius, double num_seg_quarter_circle,
+ std::string end_cap, std::string side) {
+ S2BufferOperation::Options options;
+ options.set_buffer_radius(S2Earth::MetersToAngle(buffer_radius));
+ options.set_circle_segments(num_seg_quarter_circle * 4);
+
+ if (end_cap == "ROUND") {
+ options.set_end_cap_style(S2BufferOperation::EndCapStyle::ROUND);
+ } else if (end_cap == "FLAT") {
+ options.set_end_cap_style(S2BufferOperation::EndCapStyle::FLAT);
+ } else {
+ //这里应该返回不正确的 end_cap 或者在function.cpp校验。
+ return nullptr;
+ }
+
+ if (side == "BOTH") {
+ options.set_polyline_side(S2BufferOperation::PolylineSide::BOTH);
+ } else if (end_cap == "LEFT") {
+ options.set_polyline_side(S2BufferOperation::PolylineSide::LEFT);
+ } else if (end_cap == "RIGHT") {
+ options.set_polyline_side(S2BufferOperation::PolylineSide::RIGHT);
+ } else {
+ //这里应该返回不正确的 end_cap 或者在function.cpp校验。
+ return nullptr;
+ }
+
+ switch (type()) {
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_POLYGON: {
+ MutableS2ShapeIndex shape_index;
+ if (!this->add_to_s2shape_index(shape_index)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+ return one_geo_buffer(options, shape_index);
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ std::unique_ptr<GeoMultiPolygon> res_multi_polygon = GeoMultiPolygon::create_unique();
+ for (int i = 0; i < this->get_num_geometries(); ++i) {
+ MutableS2ShapeIndex shape_index;
+ if (this->get_geometries_n(i)->is_empty()) continue;
+ if (!this->get_geometries_n(i)->add_to_s2shape_index(shape_index)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+ res_multi_polygon->add_one_geometry(one_geo_buffer(options, shape_index).release());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
dex shape_index; {
}
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
Review Comment:
warning: function 'is_ring' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_ring() const;
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
+
+ bool is_empty() const { return empty; }
+
+ void set_empty() { empty = true; }
+
+ [[nodiscard]] virtual int get_dimension() const = 0;
+
+ // decode from serialized data
+ static GeoShape* from_encoded(const void* data, size_t& size);
+
+ void encode_to(std::string* buf);
+
+ bool decode_from(const void* data, size_t& data_size);
+
+ // Returns the number of geometries in this collection
+ // (or 1 if this is not a collection)
+ virtual std::size_t get_num_geometries() const { return 1; }
Review Comment:
warning: function 'get_num_geometries' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual std::size_t get_num_geometries() const { return 1; }
```
##########
be/test/geo/geo_types_test.cpp:
##########
@@ -15,15 +15,16 @@
// specific language governing permissions and limitations
// under the License.
-#include "geo/geo_types.h"
-
#include <gtest/gtest-message.h>
#include <gtest/gtest-test-part.h>
#include <string.h>
#include <ostream>
#include "common/logging.h"
Review Comment:
warning: 'common/logging.h' file not found [clang-diagnostic-error]
```cpp
#include "common/logging.h"
^
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
+ return false;
+ }
+ return true;
+}
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. check if it is a closed loop
+ if (!is_loop_closed(points)) {
+ return GEO_PARSE_LOOP_NOT_CLOSED;
+ }
+ // 3. remove duplicate points
+ remove_duplicate_points(&points);
+ // 4. remove last point
+ points.resize(points.size() - 1);
+ // 5. check if there is enough point
+ if (points.size() < 3) {
+ return GEO_PARSE_LOOP_LACK_VERTICES;
+ }
+ loop->reset(new S2Loop(points));
+ if (!(*loop)->IsValid()) {
+ return GEO_PARSE_LOOP_INVALID;
+ }
+ (*loop)->Normalize();
+ return GEO_PARSE_OK;
+}
+
+static GeoParseStatus to_s2polygon(const GeoCoordinateLists& coords_list,
+ std::unique_ptr<S2Polygon>* polygon) {
+ std::vector<std::unique_ptr<S2Loop>> loops(coords_list.coords_list.size());
+ for (int i = 0; i < coords_list.coords_list.size(); ++i) {
+ auto res = to_s2loop(*coords_list.coords_list[i], &loops[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ if (i != 0 && !(loops[0]->Contains(*loops[i]))) {
+ return GEO_PARSE_POLYGON_NOT_HOLE;
+ }
+ }
+ polygon->reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+bool GeoPolygon::is_valid() const {
+ return polygon()->IsValid();
+}
+
+bool GeoPolygon::is_closed() const {
+ return polygon()->is_full();
+}
+
+GeoParseStatus GeoPolygon::from_coords(const GeoCoordinateLists& list) {
+ return to_s2polygon(list, &_polygon);
+}
+
+const std::unique_ptr<GeoCoordinateLists> GeoPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coordss(new GeoCoordinateLists());
+ for (int i = 0; i < GeoPolygon::num_loops(); ++i) {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ S2Loop* loop = GeoPolygon::get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ GeoCoordinate coord;
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(j)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(j)).degrees()));
+ coords->add(coord);
+ if (j == loop->num_vertices() - 1) {
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(0)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(0)).degrees()));
+ coords->add(coord);
+ }
+ }
+ coordss->add(coords.release());
+ }
+ return coordss;
+}
+
+GeoParseStatus GeoPolygon::from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops) {
+ _polygon.reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPolygon::from_s2polygon(std::unique_ptr<S2Polygon> s2polygon) {
+ _polygon.reset(s2polygon.release());
+ return GEO_PARSE_OK;
+}
+
+double GeoPolygon::get_perimeter() const {
+ double perimeter = 0;
+ std::unique_ptr<S2Shape> shape = get_s2shape();
+ for (int i = 0; i < shape->num_edges(); i++) {
+ S2Shape::Edge e = shape->edge(i);
+ S1ChordAngle angle(e.v0, e.v1);
+ perimeter += angle.radians();
+ }
+ return perimeter;
+}
+
+std::unique_ptr<S2Shape> GeoPolygon::get_s2shape() const {
+ return std::make_unique<S2Polygon::Shape>(_polygon.get());
+}
+
+bool GeoPolygon::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return _polygon->Contains(*point->point());
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ return _polygon->Contains(*line->polyline());
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ return _polygon->Contains(*polygon->polygon());
+ }
+ default:
+ return false;
+ }
+}
+
+void GeoPolygon::print_coords(std::ostream& os, const GeoPolygon& polygon) {
+ os << "(";
+ for (int i = 0; i < polygon.num_loops(); ++i) {
+ if (i != 0) {
+ os << ", ";
+ }
+ os << "(";
+ const S2Loop* loop = polygon.get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ if (j != 0) {
+ os << ", ";
+ }
+ GeoPoint::print_s2point(os, loop->vertex(j));
+ }
+ os << ", ";
+ GeoPoint::print_s2point(os, loop->vertex(0));
+ os << ")";
+ }
+ os << ")";
+}
+
+std::string GeoPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "POLYGON ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ print_coords(ss, *this);
+ return ss.str();
+}
+
+int GeoPolygon::num_loops() const {
+ return _polygon->num_loops();
+}
+
+double GeoPolygon::get_area() const {
+ return _polygon->GetArea();
+}
+
+S2Loop* GeoPolygon::get_loop(int i) const {
+ return _polygon->loop(i);
+}
+
+std::size_t GeoPolygon::get_num_point() const {
+ if (is_empty()) return 0;
+ return _polygon->num_vertices() + _polygon->num_loops();
+}
+
+std::unique_ptr<GeoShape> GeoPolygon::boundary() const {
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ if (is_empty()) {
+ multi_linestring->set_empty();
+ return multi_linestring;
+ }
+
+ std::unique_ptr<GeoCoordinateLists> coords_list = to_coords();
+
+ if (coords_list->coords_list.size() == 1) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(*coords_list->coords_list[0]);
+ return linestring;
+ }
+
+ for (int i = 0; i < coords_list->coords_list.size(); ++i) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(*coords_list->coords_list[i]);
Review Comment:
warning: ignoring return value of function declared with 'nodiscard' attribute [clang-diagnostic-unused-result]
```cpp
linestring->from_coords(*coords_list->coords_list[i]);
^
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual bool is_valid() const { return false; }
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual bool is_closed() const { return false; }
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOSHAPE_H
^
```
##########
be/src/geo/util/GeoMultiPolygon.cpp:
##########
@@ -0,0 +1,121 @@
+// 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.
+
+#include "GeoMultiPolygon.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+
+namespace doris {
+
+GeoMultiPolygon::GeoMultiPolygon() = default;
+GeoMultiPolygon::~GeoMultiPolygon() = default;
+
+GeoParseStatus GeoMultiPolygon::from_coords(
+ const GeoCoordinateListCollections& coord_list_collections) {
+ for (int i = 0; i < coord_list_collections.coords_list_collections.size(); i++) {
+ std::unique_ptr<doris::GeoPolygon> polygon = GeoPolygon::create_unique();
+ if (polygon->from_coords(*coord_list_collections.coords_list_collections[i]) !=
+ GeoParseStatus::GEO_PARSE_OK) {
+ return GEO_PARSE_COORD_INVALID;
+ }
+ geometries.emplace_back(polygon.release());
+ }
+ return GEO_PARSE_OK;
+}
+
+std::unique_ptr<GeoCoordinateListCollections> GeoMultiPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateListCollections> coords_collections(
+ new GeoCoordinateListCollections());
+ for (std::size_t i = 0; i < get_num_polygon(); ++i) {
+ const GeoPolygon* polygon = (const GeoPolygon*)GeoCollection::get_geometries_n(i);
+ if (polygon->is_empty()) continue;
+ std::unique_ptr<GeoCoordinateLists> coord = polygon->to_coords();
+ coords_collections->add(coord.release());
+ }
+ return coords_collections;
+}
+
+std::size_t GeoMultiPolygon::get_num_polygon() const {
+ return GeoCollection::get_num_geometries();
+}
+
+std::string GeoMultiPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "MULTIPOLYGON ";
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ ss << "(";
+
+ for (int i = 0; i < get_num_polygon(); ++i) {
+ if (i != 0) {
+ ss << ", ";
+ }
+ const GeoPolygon* polygon = (const GeoPolygon*)GeoCollection::get_geometries_n(i);
+ if (polygon->is_empty()) {
+ ss << "EMPTY";
+ } else {
+ GeoPolygon::print_coords(ss, *polygon);
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+GeoPolygon* GeoMultiPolygon::get_polygon_n(std::size_t n) const {
+ return (GeoPolygon*)GeoCollection::get_geometries_n(n);
+}
+
+bool GeoMultiPolygon::contains(const GeoShape* shape) const {
+ return GeoCollection::contains(shape);
+}
+
+std::unique_ptr<GeoShape> GeoMultiPolygon::boundary() const {
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ if (is_empty()) {
+ multi_linestring->set_empty();
+ return multi_linestring;
+ }
+
+ std::unique_ptr<GeoCoordinateListCollections> coords_list_collections = to_coords();
+
+ if (coords_list_collections->coords_list_collections.size() == 1 &&
+ coords_list_collections->coords_list_collections[0]->coords_list.size() == 1) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(
Review Comment:
warning: ignoring return value of function declared with 'nodiscard' attribute [clang-diagnostic-unused-result]
```cpp
linestring->from_coords(
^
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) const {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+
+ S2ClosestEdgeQuery query1(&shape_index1);
+
+ query1.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result1 = query1.FindClosestEdge(&target);
+
+ if (result1.edge_id() == -1) {
+ //这里表示没找到最近的edge,应该返回失败,理论上不会走到这里,因为set_include_interiors(false);
+ return nullptr;
+ }
+
+ // Get the edge from index1 (edge1) that is closest to index2.
+ S2Shape::Edge edge1 = query1.GetEdge(result1);
+
+ // Now find the edge from index2 (edge2) that is closest to edge1.
+ S2ClosestEdgeQuery query2(&shape_index2);
+ query2.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::EdgeTarget target2(edge1.v0, edge1.v1);
+ auto result2 = query2.FindClosestEdge(&target2);
+
+ // what if result2 has no edges?
+ if (result2.is_interior()) {
+ //这里应该返回报错
+ return nullptr;
+ //throw Exception("S2ClosestEdgeQuery result is interior!");
+ }
+
+ S2Shape::Edge edge2 = query2.GetEdge(result2);
+
+ std::unique_ptr<GeoPoint> res_point = GeoPoint::create_unique();
+
+ S2Point s2Point = S2::GetEdgePairClosestPoints(edge1.v0, edge1.v1, edge2.v0, edge2.v1).first;
+ res_point->from_s2point(&s2Point);
+
+ return res_point;
+}
+
+bool GeoShape::dwithin(const GeoShape* shape, double distance) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ S2ClosestEdgeQuery query(&shape_index1);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result = query.FindClosestEdge(&target);
+
+ return S2Earth::RadiansToMeters(result.distance().ToAngle().radians()) <= distance;
+}
+
+std::unique_ptr<GeoShape> one_geo_buffer(S2BufferOperation::Options& options,
+ MutableS2ShapeIndex& shape_index) {
+ auto output = std::make_unique<S2Polygon>();
+ S2BufferOperation op(std::make_unique<s2builderutil::S2PolygonLayer>(output.get()), options);
+
+ op.AddShapeIndex(shape_index);
+
+ S2Error error;
+ if (!op.Build(&error)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+ std::unique_ptr<GeoPolygon> res_polygon = GeoPolygon::create_unique();
+ res_polygon->from_s2polygon(std::move(output));
+ return res_polygon;
+}
+
+std::unique_ptr<GeoShape> GeoShape::buffer(double buffer_radius, double num_seg_quarter_circle,
+ std::string end_cap, std::string side) {
+ S2BufferOperation::Options options;
Review Comment:
warning: method 'buffer' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:515:
```diff
- std::string end_cap, std::string side) {
+ std::string end_cap, std::string side) const {
```
be/src/geo/util/GeoShape.h:121:
```diff
- std::string end_cap = "ROUND", std::string side = "BOTH");
+ std::string end_cap = "ROUND", std::string side = "BOTH") const;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) const {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+
+ S2ClosestEdgeQuery query1(&shape_index1);
+
+ query1.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result1 = query1.FindClosestEdge(&target);
+
+ if (result1.edge_id() == -1) {
+ //这里表示没找到最近的edge,应该返回失败,理论上不会走到这里,因为set_include_interiors(false);
+ return nullptr;
+ }
+
+ // Get the edge from index1 (edge1) that is closest to index2.
+ S2Shape::Edge edge1 = query1.GetEdge(result1);
+
+ // Now find the edge from index2 (edge2) that is closest to edge1.
+ S2ClosestEdgeQuery query2(&shape_index2);
+ query2.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::EdgeTarget target2(edge1.v0, edge1.v1);
+ auto result2 = query2.FindClosestEdge(&target2);
+
+ // what if result2 has no edges?
+ if (result2.is_interior()) {
+ //这里应该返回报错
+ return nullptr;
+ //throw Exception("S2ClosestEdgeQuery result is interior!");
+ }
+
+ S2Shape::Edge edge2 = query2.GetEdge(result2);
+
+ std::unique_ptr<GeoPoint> res_point = GeoPoint::create_unique();
+
+ S2Point s2Point = S2::GetEdgePairClosestPoints(edge1.v0, edge1.v1, edge2.v0, edge2.v1).first;
+ res_point->from_s2point(&s2Point);
+
+ return res_point;
+}
+
+bool GeoShape::dwithin(const GeoShape* shape, double distance) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
Review Comment:
warning: method 'dwithin' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:481:
```diff
- thin(const GeoShape* shape, double distance) {
+ thin(const GeoShape* shape, double distance) const {
```
be/src/geo/util/GeoShape.h:118:
```diff
- bool dwithin(const GeoShape* shape, double distance);
+ bool dwithin(const GeoShape* shape, double distance) const;
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
Review Comment:
warning: function 'is_collection' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_collection() const {
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
+
+ bool is_empty() const { return empty; }
Review Comment:
warning: function 'is_empty' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_empty() const { return empty; }
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
+
+ bool is_empty() const { return empty; }
+
+ void set_empty() { empty = true; }
+
+ [[nodiscard]] virtual int get_dimension() const = 0;
+
+ // decode from serialized data
+ static GeoShape* from_encoded(const void* data, size_t& size);
+
+ void encode_to(std::string* buf);
+
+ bool decode_from(const void* data, size_t& data_size);
+
+ // Returns the number of geometries in this collection
+ // (or 1 if this is not a collection)
+ virtual std::size_t get_num_geometries() const { return 1; }
+
+ // \brief Returns a pointer to the nth Geometry in this collection
+ // (or self if this is not a collection)
+ virtual const GeoShape* get_geometries_n(std::size_t /*n*/) const { return this; }
+
+ // Returns the number of point in this shape
+ [[nodiscard]] virtual std::size_t get_num_point() const { return 0; }
+
+ // try to construct a GeoShape from a WKT. If construct successfully, a GeoShape will
+ // be returned, and the client should delete it when don't need it.
+ // return nullptr if convert failed, and reason will be set in status
+ static GeoShape* from_wkt(const char* data, size_t size, GeoParseStatus* status);
+
+ virtual std::string as_wkt() const = 0;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual std::string as_wkt() const = 0;
```
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,135 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
+
+ bool is_empty() const { return empty; }
+
+ void set_empty() { empty = true; }
+
+ [[nodiscard]] virtual int get_dimension() const = 0;
+
+ // decode from serialized data
+ static GeoShape* from_encoded(const void* data, size_t& size);
+
+ void encode_to(std::string* buf);
+
+ bool decode_from(const void* data, size_t& data_size);
+
+ // Returns the number of geometries in this collection
+ // (or 1 if this is not a collection)
+ virtual std::size_t get_num_geometries() const { return 1; }
+
+ // \brief Returns a pointer to the nth Geometry in this collection
+ // (or self if this is not a collection)
+ virtual const GeoShape* get_geometries_n(std::size_t /*n*/) const { return this; }
Review Comment:
warning: function 'get_geometries_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] virtual const GeoShape* get_geometries_n(std::size_t /*n*/) const { return this; }
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ [[nodiscard]] GeoParseStatus from_coords(
+ const GeoCoordinateListCollections& coord_list_collections);
+
+ [[nodiscard]] std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
Review Comment:
warning: function 'get_num_polygon' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::size_t get_num_polygon() const;
```
##########
be/src/geo/util/GeoMultiPolygon.h:
##########
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef DORIS_GEOMULTIPOLYGON_H
+#define DORIS_GEOMULTIPOLYGON_H
+
+#include "common/factory_creator.h"
+//#include "GeoMultiLineString.h"
+#include "GeoCollection.h"
+
+namespace doris {
+
+class GeoMultiPolygon : public GeoCollection {
+ ENABLE_FACTORY_CREATOR(GeoMultiPolygon);
+
+public:
+ GeoMultiPolygon();
+ ~GeoMultiPolygon() override;
+
+ GeoShapeType type() const override { return GEO_SHAPE_MULTI_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ [[nodiscard]] GeoParseStatus from_coords(
+ const GeoCoordinateListCollections& coord_list_collections);
+
+ [[nodiscard]] std::unique_ptr<GeoCoordinateListCollections> to_coords() const;
+
+ // Returns the number of geometries in this collection
+ std::size_t get_num_polygon() const;
+
Review Comment:
warning: function 'get_polygon_n' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoPolygon* get_polygon_n(std::size_t n) const;
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1704568098
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1312481943
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,571 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size);
+ if (!res) {
+ return nullptr;
+ }
+
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
Review Comment:
warning: method 'intersects' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:197:
```diff
- e* shape) {
+ e* shape) const {
```
be/src/geo/util/GeoShape.h:98:
```diff
- bool intersects(GeoShape* shape);
+ bool intersects(GeoShape* shape) const;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,571 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size);
+ if (!res) {
+ return nullptr;
+ }
+
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) const {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+
+ S2ClosestEdgeQuery query1(&shape_index1);
+
+ query1.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result1 = query1.FindClosestEdge(&target);
+
+ if (result1.edge_id() == -1) {
+ //这里表示没找到最近的edge,应该返回失败,理论上不会走到这里,因为set_include_interiors(false);
+ return nullptr;
+ }
+
+ // Get the edge from index1 (edge1) that is closest to index2.
+ S2Shape::Edge edge1 = query1.GetEdge(result1);
+
+ // Now find the edge from index2 (edge2) that is closest to edge1.
+ S2ClosestEdgeQuery query2(&shape_index2);
+ query2.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::EdgeTarget target2(edge1.v0, edge1.v1);
+ auto result2 = query2.FindClosestEdge(&target2);
+
+ // what if result2 has no edges?
+ if (result2.is_interior()) {
+ //这里应该返回报错
+ return nullptr;
+ //throw Exception("S2ClosestEdgeQuery result is interior!");
+ }
+
+ S2Shape::Edge edge2 = query2.GetEdge(result2);
+
+ std::unique_ptr<GeoPoint> res_point = GeoPoint::create_unique();
+
+ S2Point s2Point = S2::GetEdgePairClosestPoints(edge1.v0, edge1.v1, edge2.v0, edge2.v1).first;
+ res_point->from_s2point(&s2Point);
+
+ return res_point;
+}
+
+bool GeoShape::dwithin(const GeoShape* shape, double distance) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
Review Comment:
warning: method 'dwithin' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:480:
```diff
- thin(const GeoShape* shape, double distance) {
+ thin(const GeoShape* shape, double distance) const {
```
be/src/geo/util/GeoShape.h:118:
```diff
- bool dwithin(const GeoShape* shape, double distance);
+ bool dwithin(const GeoShape* shape, double distance) const;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,571 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size);
+ if (!res) {
+ return nullptr;
+ }
+
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) const {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+
+ S2ClosestEdgeQuery query1(&shape_index1);
+
+ query1.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result1 = query1.FindClosestEdge(&target);
+
+ if (result1.edge_id() == -1) {
+ //这里表示没找到最近的edge,应该返回失败,理论上不会走到这里,因为set_include_interiors(false);
+ return nullptr;
+ }
+
+ // Get the edge from index1 (edge1) that is closest to index2.
+ S2Shape::Edge edge1 = query1.GetEdge(result1);
+
+ // Now find the edge from index2 (edge2) that is closest to edge1.
+ S2ClosestEdgeQuery query2(&shape_index2);
+ query2.mutable_options()->set_include_interiors(false);
+ S2ClosestEdgeQuery::EdgeTarget target2(edge1.v0, edge1.v1);
+ auto result2 = query2.FindClosestEdge(&target2);
+
+ // what if result2 has no edges?
+ if (result2.is_interior()) {
+ //这里应该返回报错
+ return nullptr;
+ //throw Exception("S2ClosestEdgeQuery result is interior!");
+ }
+
+ S2Shape::Edge edge2 = query2.GetEdge(result2);
+
+ std::unique_ptr<GeoPoint> res_point = GeoPoint::create_unique();
+
+ S2Point s2Point = S2::GetEdgePairClosestPoints(edge1.v0, edge1.v1, edge2.v0, edge2.v1).first;
+ res_point->from_s2point(&s2Point);
+
+ return res_point;
+}
+
+bool GeoShape::dwithin(const GeoShape* shape, double distance) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ S2ClosestEdgeQuery query(&shape_index1);
+ S2ClosestEdgeQuery::ShapeIndexTarget target(&shape_index2);
+
+ const auto& result = query.FindClosestEdge(&target);
+
+ return S2Earth::RadiansToMeters(result.distance().ToAngle().radians()) <= distance;
+}
+
+std::unique_ptr<GeoShape> one_geo_buffer(S2BufferOperation::Options& options,
+ MutableS2ShapeIndex& shape_index) {
+ auto output = std::make_unique<S2Polygon>();
+ S2BufferOperation op(std::make_unique<s2builderutil::S2PolygonLayer>(output.get()), options);
+
+ op.AddShapeIndex(shape_index);
+
+ S2Error error;
+ if (!op.Build(&error)) {
+ //这里应该返回报错
+ return nullptr;
+ }
+ std::unique_ptr<GeoPolygon> res_polygon = GeoPolygon::create_unique();
+ res_polygon->from_s2polygon(std::move(output));
+ return res_polygon;
+}
+
+std::unique_ptr<GeoShape> GeoShape::buffer(double buffer_radius, double num_seg_quarter_circle,
+ std::string end_cap, std::string side) {
+ S2BufferOperation::Options options;
Review Comment:
warning: method 'buffer' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:514:
```diff
- std::string end_cap, std::string side) {
+ std::string end_cap, std::string side) const {
```
be/src/geo/util/GeoShape.h:121:
```diff
- std::string end_cap = "ROUND", std::string side = "BOTH");
+ std::string end_cap = "ROUND", std::string side = "BOTH") const;
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] hello-stephen commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702542754
(From new machine)TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 45.87 seconds
stream load tsv: 536 seconds loaded 74807831229 Bytes, about 133 MB/s
stream load json: 20 seconds loaded 2358488459 Bytes, about 112 MB/s
stream load orc: 64 seconds loaded 1101869774 Bytes, about 16 MB/s
stream load parquet: 31 seconds loaded 861443392 Bytes, about 26 MB/s
insert into select: 29.0 seconds inserted 10000000 Rows, about 344K ops/s
storage size: 17161888053 Bytes
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1314410847
##########
be/test/geo/geo_types_test.cpp:
##########
@@ -44,15 +45,10 @@ TEST_F(GeoTypesTest, point_normal) {
std::string buf;
point.encode_to(&buf);
{
- std::unique_ptr<GeoShape> point2(GeoShape::from_encoded(buf.data(), buf.size()));
+ size_t a = buf.size();
+ std::unique_ptr<GeoShape> point2(GeoShape::from_encoded(buf.data(), a));
Review Comment:
warning: variable 'point2' is not initialized [cppcoreguidelines-init-variables]
```suggestion
std::unique_ptr<GeoShape> point2 = 0(GeoShape::from_encoded(buf.data(), a));
```
##########
be/test/geo/geo_types_test.cpp:
##########
@@ -85,14 +81,10 @@
line->encode_to(&buf);
{
- std::unique_ptr<GeoShape> line2(GeoShape::from_encoded(buf.data(), buf.size()));
+ size_t a = buf.size();
+ std::unique_ptr<GeoShape> line2(GeoShape::from_encoded(buf.data(), a));
Review Comment:
warning: variable 'line2' is not initialized [cppcoreguidelines-init-variables]
```suggestion
std::unique_ptr<GeoShape> line2 = 0(GeoShape::from_encoded(buf.data(), a));
```
##########
be/test/geo/geo_types_test.cpp:
##########
@@ -118,16 +110,11 @@
polygon->encode_to(&buf);
{
- std::unique_ptr<GeoShape> shape(GeoShape::from_encoded(buf.data(), buf.size()));
+ size_t a = buf.size();
+ std::unique_ptr<GeoShape> shape(GeoShape::from_encoded(buf.data(), a));
Review Comment:
warning: variable 'shape' is not initialized [cppcoreguidelines-init-variables]
```suggestion
std::unique_ptr<GeoShape> shape = 0(GeoShape::from_encoded(buf.data(), a));
```
##########
be/test/geo/geo_types_test.cpp:
##########
@@ -184,22 +171,17 @@
TEST_F(GeoTypesTest, circle) {
GeoCircle circle;
- auto res = circle.init(110.123, 64, 1000);
+ auto res = circle.to_s2cap(110.123, 64, 1000);
EXPECT_EQ(GEO_PARSE_OK, res);
std::string buf;
circle.encode_to(&buf);
{
- std::unique_ptr<GeoShape> circle2(GeoShape::from_encoded(buf.data(), buf.size()));
+ size_t a = buf.size();
+ std::unique_ptr<GeoShape> circle2(GeoShape::from_encoded(buf.data(), a));
Review Comment:
warning: variable 'circle2' is not initialized [cppcoreguidelines-init-variables]
```suggestion
std::unique_ptr<GeoShape> circle2 = 0(GeoShape::from_encoded(buf.data(), a));
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] hello-stephen commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702600945
(From new machine)TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 48.61 seconds
stream load tsv: 537 seconds loaded 74807831229 Bytes, about 132 MB/s
stream load json: 20 seconds loaded 2358488459 Bytes, about 112 MB/s
stream load orc: 65 seconds loaded 1101869774 Bytes, about 16 MB/s
stream load parquet: 31 seconds loaded 861443392 Bytes, about 26 MB/s
insert into select: 28.9 seconds inserted 10000000 Rows, about 346K ops/s
storage size: 17162173102 Bytes
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1312490187
##########
be/src/geo/util/GeoShape.h:
##########
@@ -0,0 +1,136 @@
+// 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.
+
+#ifndef DORIS_GEOSHAPE_H
+#define DORIS_GEOSHAPE_H
+
+#pragma once
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+
+class MutableS2ShapeIndex;
+
+namespace doris {
+
+class GeoShape {
+public:
+ virtual ~GeoShape() = default;
+
+ virtual GeoShapeType type() const = 0;
+
+ virtual bool is_valid() const { return false; }
+
+ virtual bool is_closed() const { return false; }
+
+ bool is_collection() const {
+ if ((type() == GEO_SHAPE_MULTI_POINT || type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ type() == GEO_SHAPE_MULTI_POLYGON || type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !is_empty()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool is_ring() const;
+
+ bool is_empty() const { return empty; }
+
+ void set_empty() { empty = true; }
+
+ [[nodiscard]] virtual int get_dimension() const = 0;
+
+ // decode from serialized data
+ static GeoShape* from_encoded(const void* data, size_t& size);
+
+ void encode_to(std::string* buf);
+
+ bool decode_from(const void* data, size_t& data_size);
+
+ // Returns the number of geometries in this collection
+ // (or 1 if this is not a collection)
+ virtual std::size_t get_num_geometries() const { return 1; }
+
+ // \brief Returns a pointer to the nth Geometry in this collection
+ // (or self if this is not a collection)
+ virtual const GeoShape* get_geometries_n(std::size_t /*n*/) const { return this; }
+
+ // Returns the number of point in this shape
+ [[nodiscard]] virtual std::size_t get_num_point() const { return 0; }
+
+ // try to construct a GeoShape from a WKT. If construct successfully, a GeoShape will
+ // be returned, and the client should delete it when don't need it.
+ // return nullptr if convert failed, and reason will be set in status
+ static GeoShape* from_wkt(const char* data, size_t size, GeoParseStatus* status);
+
+ virtual std::string as_wkt() const = 0;
+
+ static GeoShape* from_wkb(const char* data, size_t size, GeoParseStatus* status);
+
+ static std::string as_binary(GeoShape* rhs, int is_hex);
+ static std::string geo_tohex(std::string binary);
+
+ static GeoShape* from_geojson(const char* data, size_t size, GeoParseStatus* status);
+
+ bool as_geojson(std::string& res);
+
+ virtual bool contains(const GeoShape* rhs) const { return false; }
+
+ bool intersects(GeoShape* shape) const;
+
+ bool ComputeArea(double* angle, std::string square_unit);
+
+ [[nodiscard]] double get_length() const;
+
+ [[nodiscard]] double get_perimeter() const;
+
+ [[nodiscard]] std::unique_ptr<GeoShape> get_centroid() const;
+
+ [[nodiscard]] bool get_type_string(std::string& type_string) const;
+
+ [[nodiscard]] virtual std::unique_ptr<GeoShape> boundary() const = 0;
+
+ virtual bool add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const { return false; }
+
+ //virtual MutableS2ShapeIndex* to_s2shape_index() const { return nullptr; };
+
+ std::unique_ptr<GeoShape> find_closest_point(const GeoShape* shape) const;
+
+ bool dwithin(const GeoShape* shape, double distance) const;
+
+ std::unique_ptr<GeoShape> buffer(double buffer_radius, double num_seg_quarter_circle = 2,
Review Comment:
warning: function 'buffer' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> buffer(double buffer_radius, double num_seg_quarter_circle = 2,
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] hello-stephen commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1704614731
(From new machine)TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 46.26 seconds
stream load tsv: 549 seconds loaded 74807831229 Bytes, about 129 MB/s
stream load json: 20 seconds loaded 2358488459 Bytes, about 112 MB/s
stream load orc: 65 seconds loaded 1101869774 Bytes, about 16 MB/s
stream load parquet: 32 seconds loaded 861443392 Bytes, about 25 MB/s
insert into select: 28.7 seconds inserted 10000000 Rows, about 348K ops/s
storage size: 17162235521 Bytes
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [feature](geometry) Support geometry type and more Geo functions [doris]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-2081710046
We're closing this PR because it hasn't been updated in a while.
This isn't a judgement on the merit of the PR in any way. It's just a way of keeping the PR queue manageable.
If you'd like to revive this PR, please reopen it and feel free a maintainer to remove the Stale tag!
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700365343
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700848176
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] hello-stephen commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702140101
(From new machine)TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 46.05 seconds
stream load tsv: 535 seconds loaded 74807831229 Bytes, about 133 MB/s
stream load json: 21 seconds loaded 2358488459 Bytes, about 107 MB/s
stream load orc: 64 seconds loaded 1101869774 Bytes, about 16 MB/s
stream load parquet: 31 seconds loaded 861443392 Bytes, about 26 MB/s
insert into select: 28.9 seconds inserted 10000000 Rows, about 346K ops/s
storage size: 17162074779 Bytes
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702563710
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] github-actions[bot] commented on a diff in pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1293167519
##########
be/src/geo/util/GeoPoint.h:
##########
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef DORIS_GEOPOINT_H
+#define DORIS_GEOPOINT_H
+
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+template <typename T>
+class Vector3;
+class S2Shape;
+using S2Point = Vector3<double>;
+
+namespace doris {
+
+class GeoPoint : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPoint);
+
+public:
+ GeoPoint();
+ ~GeoPoint() override;
+
+ static void print_s2point(std::ostream& os, const S2Point& point);
+
+ static GeoParseStatus to_s2point(double lng, double lat, S2Point* point);
+ static GeoParseStatus to_s2point(const GeoCoordinate& coord, S2Point* point);
+
+ GeoParseStatus from_coord(double x, double y);
+ GeoParseStatus from_coord(const GeoCoordinate& point);
+
+ GeoParseStatus from_s2point(S2Point* point);
+
+ GeoCoordinates to_coords() const;
+
+ std::unique_ptr<GeoCoordinate> to_coord() const;
+
+ GeoShapeType type() const override { return GEO_SHAPE_POINT; }
+
+ bool is_valid() const override;
+
+ bool is_closed() const override { return !is_empty(); }
+
+ [[nodiscard]] int get_dimension() const override { return 0; }
+
+ [[nodiscard]] const S2Point* point() const { return _point.get(); }
+
+ [[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static bool ComputeDistance(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* distance);
+
+ static bool ComputeAngleSphere(double x_lng, double x_lat, double y_lng, double y_lat,
+ double* angle);
+ static bool ComputeAngle(GeoPoint* p1, GeoPoint* p2, GeoPoint* p3, double* angle);
+ static bool ComputeAzimuth(GeoPoint* p1, GeoPoint* p2, double* angle);
+
+ std::string as_wkt() const override;
+
+ [[nodiscard]] std::size_t get_num_point() const override { return 1; }
+
+ std::unique_ptr<GeoShape> boundary() const override;
+
+ bool add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const override;
+
+ //void add_to_s2point_index(S2PointIndex<int>& S2point_index, int i);
+
+ double x() const;
+ double y() const;
Review Comment:
warning: function 'y' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double y() const;
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
+ return false;
+ }
+ return true;
+}
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. check if it is a closed loop
+ if (!is_loop_closed(points)) {
+ return GEO_PARSE_LOOP_NOT_CLOSED;
+ }
+ // 3. remove duplicate points
+ remove_duplicate_points(&points);
+ // 4. remove last point
+ points.resize(points.size() - 1);
+ // 5. check if there is enough point
+ if (points.size() < 3) {
+ return GEO_PARSE_LOOP_LACK_VERTICES;
+ }
+ loop->reset(new S2Loop(points));
+ if (!(*loop)->IsValid()) {
+ return GEO_PARSE_LOOP_INVALID;
+ }
+ (*loop)->Normalize();
+ return GEO_PARSE_OK;
+}
+
+static GeoParseStatus to_s2polygon(const GeoCoordinateLists& coords_list,
+ std::unique_ptr<S2Polygon>* polygon) {
+ std::vector<std::unique_ptr<S2Loop>> loops(coords_list.coords_list.size());
+ for (int i = 0; i < coords_list.coords_list.size(); ++i) {
+ auto res = to_s2loop(*coords_list.coords_list[i], &loops[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ if (i != 0 && !(loops[0]->Contains(*loops[i]))) {
+ return GEO_PARSE_POLYGON_NOT_HOLE;
+ }
+ }
+ polygon->reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+bool GeoPolygon::is_valid() const {
+ return polygon()->IsValid();
+}
+
+bool GeoPolygon::is_closed() const {
+ return polygon()->is_full();
+}
+
+GeoParseStatus GeoPolygon::from_coords(const GeoCoordinateLists& list) {
+ return to_s2polygon(list, &_polygon);
+}
+
+const std::unique_ptr<GeoCoordinateLists> GeoPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coordss(new GeoCoordinateLists());
+ for (int i = 0; i < GeoPolygon::num_loops(); ++i) {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ S2Loop* loop = GeoPolygon::get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ GeoCoordinate coord;
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(j)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(j)).degrees()));
+ coords->add(coord);
+ if (j == loop->num_vertices() - 1) {
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(0)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(0)).degrees()));
+ coords->add(coord);
+ }
+ }
+ coordss->add(coords.release());
+ }
+ return coordss;
+}
+
+GeoParseStatus GeoPolygon::from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops) {
+ _polygon.reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPolygon::from_s2polygon(std::unique_ptr<S2Polygon> s2polygon) {
+ _polygon.reset(s2polygon.release());
+ return GEO_PARSE_OK;
+}
+
+double GeoPolygon::get_perimeter() const {
+ double perimeter = 0;
+ std::unique_ptr<S2Shape> shape = get_s2shape();
+ for (int i = 0; i < shape->num_edges(); i++) {
+ S2Shape::Edge e = shape->edge(i);
+ S1ChordAngle angle(e.v0, e.v1);
+ perimeter += angle.radians();
+ }
+ return perimeter;
+}
+
+std::unique_ptr<S2Shape> GeoPolygon::get_s2shape() const {
+ return std::make_unique<S2Polygon::Shape>(_polygon.get());
+}
+
+bool GeoPolygon::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return _polygon->Contains(*point->point());
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ return _polygon->Contains(*line->polyline());
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ return _polygon->Contains(*polygon->polygon());
+ }
+ default:
+ return false;
+ }
+}
+
+void GeoPolygon::print_coords(std::ostream& os, const GeoPolygon& polygon) {
+ os << "(";
+ for (int i = 0; i < polygon.num_loops(); ++i) {
+ if (i != 0) {
+ os << ", ";
+ }
+ os << "(";
+ const S2Loop* loop = polygon.get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ if (j != 0) {
+ os << ", ";
+ }
+ GeoPoint::print_s2point(os, loop->vertex(j));
+ }
+ os << ", ";
+ GeoPoint::print_s2point(os, loop->vertex(0));
+ os << ")";
+ }
+ os << ")";
+}
+
+std::string GeoPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "POLYGON ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ print_coords(ss, *this);
+ return ss.str();
+}
+
+int GeoPolygon::num_loops() const {
+ return _polygon->num_loops();
+}
+
+double GeoPolygon::get_area() const {
+ return _polygon->GetArea();
+}
+
+S2Loop* GeoPolygon::get_loop(int i) const {
+ return _polygon->loop(i);
+}
+
+std::size_t GeoPolygon::get_num_point() const {
+ if (is_empty()) return 0;
+ return _polygon->num_vertices() + _polygon->num_loops();
+}
+
+std::unique_ptr<GeoShape> GeoPolygon::boundary() const {
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ if (is_empty()) {
+ multi_linestring->set_empty();
+ return multi_linestring;
+ }
+
+ std::unique_ptr<GeoCoordinateLists> coords_list = to_coords();
+
+ if (coords_list->coords_list.size() == 1) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(*coords_list->coords_list[0]);
+ return linestring;
+ }
+
+ for (int i = 0; i < coords_list->coords_list.size(); ++i) {
+ std::unique_ptr<GeoLineString> linestring = GeoLineString::create_unique();
+ linestring->from_coords(*coords_list->coords_list[i]);
+ multi_linestring->add_one_geometry(linestring.release());
+ }
+
+ return multi_linestring;
+}
+
+bool GeoPolygon::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty() || !is_valid()) return false;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (is_empty() || !is_valid()) { return false;
}
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
Review Comment:
warning: function 'is_valid' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_valid() const override;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static void print_coords(std::ostream& os, const GeoPolygon& polygon);
+ std::string as_wkt() const override;
+
+ int num_loops() const;
+ double get_area() const;
Review Comment:
warning: function 'get_area' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double get_area() const;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static void print_coords(std::ostream& os, const GeoPolygon& polygon);
+ std::string as_wkt() const override;
+
+ int num_loops() const;
Review Comment:
warning: function 'num_loops' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] int num_loops() const;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
n(i)->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
n(i)->is_empty()) { continue;
}
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
Review Comment:
warning: function 'polygon' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const S2Polygon* polygon() const { return _polygon.get(); }
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
Review Comment:
warning: function 'is_closed' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] bool is_closed() const override;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
Review Comment:
warning: macro is not used [clang-diagnostic-unused-macros]
```cpp
#define DORIS_GEOPOLYGON_H
^
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
+ return false;
+ }
+ return true;
+}
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
Review Comment:
warning: ISO C++20 considers use of overloaded operator '!=' (with operand types '__gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type' (aka 'Vector3<double>') and '__gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type') to be ambiguous despite there being a unique best viable function with non-reversed arguments [clang-diagnostic-ambiguous-reversed-operator]
```cpp
if ((*points)[rhs] != (*points)[lhs]) {
^
```
<details>
<summary>Additional context</summary>
**thirdparty/installed/include/s2/util/math/vector.h:104:** candidate function with non-reversed arguments
```cpp
bool operator!=(const D& b) const { return !(AsD() == b); }
^
```
**thirdparty/installed/include/s2/util/math/vector.h:100:** ambiguous candidate function with reversed arguments
```cpp
bool operator==(const D& b) const {
^
```
</details>
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
Review Comment:
warning: function 'to_coords' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] const std::unique_ptr<GeoCoordinateLists> to_coords() const;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
Review Comment:
warning: function 'get_perimeter' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] double get_perimeter() const;
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
Review Comment:
warning: ISO C++20 considers use of overloaded operator '!=' (with operand types 'const __gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type' (aka 'const Vector3<double>') and 'const __gnu_cxx::__alloc_traits<std::allocator<Vector3<double>>, Vector3<double>>::value_type') to be ambiguous despite there being a unique best viable function with non-reversed arguments [clang-diagnostic-ambiguous-reversed-operator]
```cpp
if (points[0] != points[points.size() - 1]) {
^
```
<details>
<summary>Additional context</summary>
**thirdparty/installed/include/s2/util/math/vector.h:104:** candidate function with non-reversed arguments
```cpp
bool operator!=(const D& b) const { return !(AsD() == b); }
^
```
**thirdparty/installed/include/s2/util/math/vector.h:100:** ambiguous candidate function with reversed arguments
```cpp
bool operator==(const D& b) const {
^
```
</details>
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static void print_coords(std::ostream& os, const GeoPolygon& polygon);
+ std::string as_wkt() const override;
+
+ int num_loops() const;
+ double get_area() const;
+ S2Loop* get_loop(int i) const;
Review Comment:
warning: function 'get_loop' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] S2Loop* get_loop(int i) const;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
Review Comment:
warning: function 'type' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
Review Comment:
warning: function 'get_s2shape' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<S2Shape> get_s2shape() const;
```
##########
be/src/geo/util/GeoPolygon.cpp:
##########
@@ -0,0 +1,279 @@
+// 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.
+
+#include "GeoPolygon.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2polygon.h>
+#include <s2/util/coding/coder.h>
+
+#include <vector>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+
+namespace doris {
+
+GeoPolygon::GeoPolygon() : _polygon(new S2Polygon()) {}
+GeoPolygon::~GeoPolygon() = default;
+
+static bool is_loop_closed(const std::vector<S2Point>& points) {
+ if (points.empty()) {
+ return false;
+ }
+ if (points[0] != points[points.size() - 1]) {
+ return false;
+ }
+ return true;
+}
+
+// remove adjacent duplicate points
+static void remove_duplicate_points(std::vector<S2Point>* points) {
+ int lhs = 0;
+ int rhs = 1;
+ for (; rhs < points->size(); ++rhs) {
+ if ((*points)[rhs] != (*points)[lhs]) {
+ lhs++;
+ if (lhs != rhs) {
+ (*points)[lhs] = (*points)[rhs];
+ }
+ }
+ }
+ points->resize(lhs + 1);
+}
+
+GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop) {
+ // 1. convert all coordinates to points
+ std::vector<S2Point> points(coords.coords.size());
+ for (int i = 0; i < coords.coords.size(); ++i) {
+ auto res = GeoPoint::to_s2point(coords.coords[i].x, coords.coords[i].y, &points[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ }
+ // 2. check if it is a closed loop
+ if (!is_loop_closed(points)) {
+ return GEO_PARSE_LOOP_NOT_CLOSED;
+ }
+ // 3. remove duplicate points
+ remove_duplicate_points(&points);
+ // 4. remove last point
+ points.resize(points.size() - 1);
+ // 5. check if there is enough point
+ if (points.size() < 3) {
+ return GEO_PARSE_LOOP_LACK_VERTICES;
+ }
+ loop->reset(new S2Loop(points));
+ if (!(*loop)->IsValid()) {
+ return GEO_PARSE_LOOP_INVALID;
+ }
+ (*loop)->Normalize();
+ return GEO_PARSE_OK;
+}
+
+static GeoParseStatus to_s2polygon(const GeoCoordinateLists& coords_list,
+ std::unique_ptr<S2Polygon>* polygon) {
+ std::vector<std::unique_ptr<S2Loop>> loops(coords_list.coords_list.size());
+ for (int i = 0; i < coords_list.coords_list.size(); ++i) {
+ auto res = to_s2loop(*coords_list.coords_list[i], &loops[i]);
+ if (res != GEO_PARSE_OK) {
+ return res;
+ }
+ if (i != 0 && !(loops[0]->Contains(*loops[i]))) {
+ return GEO_PARSE_POLYGON_NOT_HOLE;
+ }
+ }
+ polygon->reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+bool GeoPolygon::is_valid() const {
+ return polygon()->IsValid();
+}
+
+bool GeoPolygon::is_closed() const {
+ return polygon()->is_full();
+}
+
+GeoParseStatus GeoPolygon::from_coords(const GeoCoordinateLists& list) {
+ return to_s2polygon(list, &_polygon);
+}
+
+const std::unique_ptr<GeoCoordinateLists> GeoPolygon::to_coords() const {
+ std::unique_ptr<GeoCoordinateLists> coordss(new GeoCoordinateLists());
+ for (int i = 0; i < GeoPolygon::num_loops(); ++i) {
+ std::unique_ptr<GeoCoordinates> coords(new GeoCoordinates());
+ S2Loop* loop = GeoPolygon::get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ GeoCoordinate coord;
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(j)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(j)).degrees()));
+ coords->add(coord);
+ if (j == loop->num_vertices() - 1) {
+ coord.x = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Longitude(loop->vertex(0)).degrees()));
+ coord.y = std::stod(
+ absl::StrFormat("%.13f", S2LatLng::Latitude(loop->vertex(0)).degrees()));
+ coords->add(coord);
+ }
+ }
+ coordss->add(coords.release());
+ }
+ return coordss;
+}
+
+GeoParseStatus GeoPolygon::from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops) {
+ _polygon.reset(new S2Polygon(std::move(loops)));
+ return GEO_PARSE_OK;
+}
+
+GeoParseStatus GeoPolygon::from_s2polygon(std::unique_ptr<S2Polygon> s2polygon) {
+ _polygon.reset(s2polygon.release());
+ return GEO_PARSE_OK;
+}
+
+double GeoPolygon::get_perimeter() const {
+ double perimeter = 0;
+ std::unique_ptr<S2Shape> shape = get_s2shape();
+ for (int i = 0; i < shape->num_edges(); i++) {
+ S2Shape::Edge e = shape->edge(i);
+ S1ChordAngle angle(e.v0, e.v1);
+ perimeter += angle.radians();
+ }
+ return perimeter;
+}
+
+std::unique_ptr<S2Shape> GeoPolygon::get_s2shape() const {
+ return std::make_unique<S2Polygon::Shape>(_polygon.get());
+}
+
+bool GeoPolygon::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ return _polygon->Contains(*point->point());
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ return _polygon->Contains(*line->polyline());
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ return _polygon->Contains(*polygon->polygon());
+ }
+ default:
+ return false;
+ }
+}
+
+void GeoPolygon::print_coords(std::ostream& os, const GeoPolygon& polygon) {
+ os << "(";
+ for (int i = 0; i < polygon.num_loops(); ++i) {
+ if (i != 0) {
+ os << ", ";
+ }
+ os << "(";
+ const S2Loop* loop = polygon.get_loop(i);
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ if (j != 0) {
+ os << ", ";
+ }
+ GeoPoint::print_s2point(os, loop->vertex(j));
+ }
+ os << ", ";
+ GeoPoint::print_s2point(os, loop->vertex(0));
+ os << ")";
+ }
+ os << ")";
+}
+
+std::string GeoPolygon::as_wkt() const {
+ std::stringstream ss;
+ ss << "POLYGON ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+
+ print_coords(ss, *this);
+ return ss.str();
+}
+
+int GeoPolygon::num_loops() const {
+ return _polygon->num_loops();
+}
+
+double GeoPolygon::get_area() const {
+ return _polygon->GetArea();
+}
+
+S2Loop* GeoPolygon::get_loop(int i) const {
+ return _polygon->loop(i);
+}
+
+std::size_t GeoPolygon::get_num_point() const {
+ if (is_empty()) return 0;
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
if (is_empty()) { return 0;
}
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
Review Comment:
warning: method 'intersects' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:198:
```diff
- e* shape) {
+ e* shape) const {
```
be/src/geo/util/GeoShape.h:98:
```diff
- bool intersects(GeoShape* shape);
+ bool intersects(GeoShape* shape) const;
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static void print_coords(std::ostream& os, const GeoPolygon& polygon);
+ std::string as_wkt() const override;
Review Comment:
warning: function 'as_wkt' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::string as_wkt() const override;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
sion() != 1) { return length;
}
```
##########
be/src/geo/util/GeoPolygon.h:
##########
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef DORIS_GEOPOLYGON_H
+#define DORIS_GEOPOLYGON_H
+
+#include "GeoLineString.h"
+#include "GeoPoint.h"
+#include "GeoShape.h"
+#include "common/factory_creator.h"
+#include "geo/wkt_parse_type.h"
+
+class S2Polygon;
+class S2Loop;
+
+namespace doris {
+class GeoPolygon : public GeoShape {
+ ENABLE_FACTORY_CREATOR(GeoPolygon);
+
+public:
+ GeoPolygon();
+ ~GeoPolygon() override;
+
+ bool is_valid() const override;
+
+ bool is_closed() const override;
+
+ static GeoParseStatus to_s2loop(const GeoCoordinates& coords, std::unique_ptr<S2Loop>* loop);
+
+ GeoParseStatus from_coords(const GeoCoordinateLists& coords_list);
+ const std::unique_ptr<GeoCoordinateLists> to_coords() const;
+
+ GeoParseStatus from_s2loop(std::vector<std::unique_ptr<S2Loop>>& loops);
+
+ GeoParseStatus from_s2polygon(std::unique_ptr<S2Polygon> s2polygon);
+
+ GeoShapeType type() const override { return GEO_SHAPE_POLYGON; }
+
+ [[nodiscard]] int get_dimension() const override { return 2; }
+
+ double get_perimeter() const;
+
+ const S2Polygon* polygon() const { return _polygon.get(); }
+
+ std::unique_ptr<S2Shape> get_s2shape() const;
+
+ bool contains(const GeoShape* rhs) const override;
+
+ static void print_coords(std::ostream& os, const GeoPolygon& polygon);
+ std::string as_wkt() const override;
+
+ int num_loops() const;
+ double get_area() const;
+ S2Loop* get_loop(int i) const;
+
+ [[nodiscard]] std::size_t get_num_point() const override;
+
+ std::unique_ptr<GeoShape> boundary() const override;
Review Comment:
warning: function 'boundary' should be marked [[nodiscard]] [modernize-use-nodiscard]
```suggestion
[[nodiscard]] std::unique_ptr<GeoShape> boundary() const override;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
n() != 2) { return perimeter;
}
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
+ multi_line_string->get_line_string_n(i)->polyline());
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += S2::TrueCentroid(e.v0, e.v1);
+ }
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon = (const GeoMultiPolygon*)this;
+ for (int i = 0; i < multi_polygon->get_num_polygon(); ++i) {
+ if (multi_polygon->get_polygon_n(i)->is_empty()) continue;
+ S2Point centroid_tmp = multi_polygon->get_polygon_n(i)->polygon()->GetCentroid();
+ centroid_vector += centroid_tmp;
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ GeoPoint* point = (GeoPoint*)collection->get_geometries_n(i)->get_centroid().release();
+ centroid_vector += *point->point();
+ }
+ centroid->from_s2point(¢roid_vector);
+ return centroid;
+ }
+ default:
+ //报错
+ return nullptr;
+ }
+}
+
+bool GeoShape::get_type_string(std::string& type_string) const {
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ type_string = "ST_Point";
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ type_string = "ST_LineString";
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ type_string = "ST_Polygon";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ type_string = "ST_MultiPoint";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ type_string = "ST_MultiLineString";
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ type_string = "ST_MultiPolygon";
+ return true;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ type_string = "ST_GeometryCollection";
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::find_closest_point(const GeoShape* shape) {
Review Comment:
warning: method 'find_closest_point' can be made const [readability-make-member-function-const]
be/src/geo/util/GeoShape.cpp:431:
```diff
- _point(const GeoShape* shape) {
+ _point(const GeoShape* shape) const {
```
be/src/geo/util/GeoShape.h:116:
```diff
- std::unique_ptr<GeoShape> find_closest_point(const GeoShape* shape);
+ std::unique_ptr<GeoShape> find_closest_point(const GeoShape* shape) const;
```
##########
be/src/geo/util/GeoShape.cpp:
##########
@@ -0,0 +1,572 @@
+// 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.
+
+#include "GeoShape.h"
+
+#include <s2/mutable_s2shape_index.h>
+#include <s2/s2boolean_operation.h>
+#include <s2/s2buffer_operation.h>
+#include <s2/s2builderutil_lax_polygon_layer.h>
+#include <s2/s2builderutil_s2polygon_layer.h>
+#include <s2/s2centroids.h>
+#include <s2/s2closest_edge_query.h>
+#include <s2/s2closest_point_query.h>
+#include <s2/s2earth.h>
+#include <s2/s2error.h>
+#include <s2/s2lax_polygon_shape.h>
+#include <s2/s2point_vector_shape.h>
+#include <s2/s2polygon.h>
+#include <s2/s2polyline.h>
+
+#include "GeoCircle.h"
+#include "GeoCollection.h"
+#include "GeoLineString.h"
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+#include "GeoPoint.h"
+#include "GeoPolygon.h"
+#include "geo/geo_tobinary.h"
+#include "geo/geo_tojson.h"
+#include "geo/geojson_parse.h"
+#include "geo/wkb_parse.h"
+#include "geo/wkt_parse.h"
+
+namespace doris {
+
+size_t hash_coord(const GeoCoordinate& coord) {
+ return std::hash<double>()(coord.x) ^ std::hash<double>()(coord.y);
+}
+
+bool GeoShape::is_ring() const {
+ if (type() == GEO_SHAPE_LINE_STRING && is_closed()) {
+ const GeoLineString* line_string = (const GeoLineString*)this;
+ std::unique_ptr<GeoCoordinates> coords(line_string->to_coords_ptr().release());
+ std::set<GeoCoordinate, CompareA> coords_set(coords->coords.begin(), coords->coords.end());
+ /*for (int i = 0; i < line_string->get_num_point() - 1; ++i) {
+ auto [it, inserted] = coords_set.insert(coords->coords[i]);
+ if (!inserted) {
+ return false;
+ }
+ }*/
+ return coords->coords.size() - 1 == coords_set.size();
+ } else {
+ //这里应该报错
+ return false;
+ }
+}
+
+bool GeoShape::decode_from(const void* data, size_t& data_size) {
+ char reserved_byte = ((const char*)data)[0];
+ if (reserved_byte == 0X01) {
+ set_empty();
+ return true;
+ }
+
+ char type_byte = ((const char*)data)[1];
+ if (reserved_byte != 0X00 || type_byte != type()) {
+ return false;
+ }
+
+ std::memcpy(&data_size, (const char*)data + 2, sizeof(data_size));
+
+ return decode((const char*)data + 10, data_size);
+}
+
+void GeoShape::encode_to(std::string* buf) {
+ size_t data_size = 0;
+ // Whether the first byte storage is empty, 0X01 is empty.6
+ if (is_empty()) {
+ buf->push_back(0X01);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ return;
+ }
+ buf->push_back(0X00);
+ buf->push_back((char)type());
+ buf->append(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
+ encode(buf, data_size);
+ std::memcpy(&(*buf)[2], &data_size, sizeof(data_size));
+}
+
+GeoShape* GeoShape::from_wkt(const char* data, size_t size, GeoParseStatus* status) {
+ GeoShape* shape = nullptr;
+ *status = WktParse::parse_wkt(data, size, &shape);
+ return shape;
+}
+
+GeoShape* GeoShape::from_wkb(const char* data, size_t size, GeoParseStatus* status) {
+ std::stringstream wkb;
+
+ for (int i = 0; i < size; ++i) {
+ if ((i == 1 && wkb.str() == "x") || (i == 2 && wkb.str() == "\\x")) {
+ wkb.str(std::string());
+ }
+ wkb << *data;
+ data++;
+ }
+ GeoShape* shape = nullptr;
+ *status = WkbParse::parse_wkb(wkb, &shape);
+ return shape;
+}
+
+std::string GeoShape::as_binary(GeoShape* rhs, int is_hex) {
+ std::string res;
+ if (toBinary::geo_tobinary(rhs, &res, is_hex)) {
+ return res;
+ }
+ return res;
+}
+
+std::string GeoShape::geo_tohex(std::string binary) {
+ return toBinary::to_hex(binary);
+}
+
+GeoShape* GeoShape::from_geojson(const char* data, size_t size, GeoParseStatus* status) {
+ std::string geojson(data, size);
+
+ GeoShape* shape = nullptr;
+ *status = GeoJsonParse::parse_geojson(geojson, &shape);
+ return shape;
+}
+
+bool GeoShape::as_geojson(std::string& res) {
+ return toGeoJson::geo_tojson(this, res);
+}
+
+GeoShape* GeoShape::from_encoded(const void* ptr, size_t& size) {
+ std::unique_ptr<GeoShape> shape;
+ switch (((const char*)ptr)[1]) {
+ case GEO_SHAPE_POINT: {
+ shape.reset(GeoPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ shape.reset(GeoLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ shape.reset(GeoPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ shape.reset(GeoMultiPoint::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ shape.reset(GeoMultiLineString::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ shape.reset(GeoMultiPolygon::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ shape.reset(GeoCollection::create_unique().release());
+ break;
+ }
+ case GEO_SHAPE_CIRCLE: {
+ shape.reset(GeoCircle::create_unique().release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ auto res = shape->decode_from(ptr, size); //shape->decode((const char *) ptr + 2, size - 2);
+ if (!res) {
+ return nullptr;
+ }
+
+ //shape->decode_from(ptr,size);
+ return shape.release();
+}
+
+bool GeoShape::intersects(GeoShape* shape) {
+ MutableS2ShapeIndex shape_index1;
+ MutableS2ShapeIndex shape_index2;
+ if (!this->add_to_s2shape_index(shape_index1) || !shape->add_to_s2shape_index(shape_index2)) {
+ //这里应该返回报错
+ return false;
+ }
+
+ return S2BooleanOperation::Intersects(shape_index1, shape_index2);
+}
+
+bool GeoShape::ComputeArea(double* area, std::string square_unit) {
+ if (is_empty()) {
+ *area = 0;
+ return true;
+ }
+
+ std::vector<double> steradians;
+ switch (type()) {
+ case GEO_SHAPE_CIRCLE: {
+ const GeoCircle* circle = (const GeoCircle*)this;
+ steradians.emplace_back(circle->get_area());
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)this;
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ case GEO_SHAPE_POINT:
+ case GEO_SHAPE_LINE_STRING:
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ *area = 0;
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)this;
+ for (int i = 0; i < collection->get_num_geometries(); ++i) {
+ switch (collection->get_geometries_n(i)->type()) {
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)collection->get_geometries_n(i);
+ steradians.emplace_back(polygon->get_area());
+ break;
+ }
+ default:
+ steradians.emplace_back(0);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (square_unit.compare("square_meters") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareMeters(s) + *area;
+ }
+ return true;
+ } else if (square_unit.compare("square_km") == 0) {
+ for (double& s : steradians) {
+ *area = S2Earth::SteradiansToSquareKm(s) + *area;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+double GeoShape::get_length() const {
+ double length = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_LINE_STRING: {
+ return S2Earth::RadiansToMeters(((const GeoLineString*)this)->length());
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 1) return length;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ if ((get_geometries_n(i)->type() == GEO_SHAPE_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_MULTI_LINE_STRING ||
+ get_geometries_n(i)->type() == GEO_SHAPE_GEOMETRY_COLLECTION) &&
+ !get_geometries_n(i)->is_empty()) {
+ length += get_geometries_n(i)->get_length();
+ }
+ }
+ return length;
+ }
+ default:
+ return length;
+ }
+}
+
+double GeoShape::get_perimeter() const {
+ double perimeter = 0;
+
+ switch (type()) {
+ case GEO_SHAPE_POLYGON: {
+ return S2Earth::RadiansToMeters(((const GeoPolygon*)this)->get_perimeter());
+ }
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ if (get_dimension() != 2) return perimeter;
+ for (int i = 0; i < get_num_geometries(); ++i) {
+ perimeter += S2Earth::RadiansToMeters(
+ ((const GeoLineString*)get_geometries_n(i))->get_perimeter());
+ }
+ return perimeter;
+ }
+ default:
+ return perimeter;
+ }
+}
+
+std::unique_ptr<GeoShape> GeoShape::get_centroid() const {
+ std::unique_ptr<GeoPoint> centroid = GeoPoint::create_unique();
+ if (is_empty()) {
+ centroid->set_empty();
+ return centroid;
+ }
+
+ S2Point centroid_vector(0, 0, 0);
+
+ switch (type()) {
+ case GEO_SHAPE_POINT: {
+ centroid->from_s2point(const_cast<S2Point*>(((GeoPoint*)this)->point()));
+ return centroid;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ S2Point s2_point = ((const GeoLineString*)this)->polyline()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_POLYGON: {
+ S2Point s2_point = ((const GeoPolygon*)this)->polygon()->GetCentroid();
+ centroid->from_s2point(&s2_point);
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ std::vector<S2Point> points;
+ const GeoMultiPoint* multi_point = (const GeoMultiPoint*)this;
+ for (int i = 0; i < multi_point->get_num_point(); ++i) {
+ if (multi_point->get_point_n(i)->is_empty()) continue;
+ points.emplace_back(*multi_point->get_point_n(i)->point());
+ }
+
+ auto shape = std::make_unique<S2PointVectorShape>(points);
+ for (int j = 0; j < shape->num_edges(); j++) {
+ S2Shape::Edge e = shape->edge(j);
+ centroid_vector += e.v0;
+ }
+
+ centroid->from_s2point(¢roid_vector);
+
+ return centroid;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_line_string = (const GeoMultiLineString*)this;
+ for (int i = 0; i < multi_line_string->get_num_line(); ++i) {
+ if (multi_line_string->get_line_string_n(i)->is_empty()) continue;
+ auto shape = std::make_unique<S2Polyline::Shape>(
Review Comment:
warning: statement should be inside braces [readability-braces-around-statements]
```suggestion
n(i)->is_empty()) { continue;
}
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [feature](geometry) Support geometry type and more Geo functions [doris]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #22933:
URL: https://github.com/apache/doris/pull/22933#discussion_r1377255254
##########
be/src/geo/geo_tojson.h:
##########
@@ -0,0 +1,78 @@
+// 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.
+
+#pragma once
+
+#include <rapidjson/allocators.h>
Review Comment:
warning: 'rapidjson/allocators.h' file not found [clang-diagnostic-error]
```cpp
#include <rapidjson/allocators.h>
^
```
##########
be/src/geo/geojson_parse.h:
##########
@@ -0,0 +1,78 @@
+// 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.
+
+#pragma once
+
+#include <memory>
+
+#include "geo/geo_common.h"
+#include "geo/wkt_parse_type.h"
+#include "rapidjson/document.h"
Review Comment:
warning: 'rapidjson/document.h' file not found [clang-diagnostic-error]
```cpp
#include "rapidjson/document.h"
^
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
const auto* point = (const GeoPoint*)rhs;
```
##########
be/src/geo/util/GeoCircle.cpp:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#include "GeoCircle.h"
+
+#include <s2/s2cap.h>
Review Comment:
warning: 's2/s2cap.h' file not found [clang-diagnostic-error]
```cpp
#include <s2/s2cap.h>
^
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
++i) {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
YGON: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
++i) {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
* }
Polygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);auto
```
##########
be/src/geo/geo_tobinary.cpp:
##########
@@ -69,29 +81,56 @@
bool toBinary::writeGeoPoint(GeoPoint* point, ToBinaryContext* ctx) {
writeByteOrder(ctx);
writeGeometryType(wkbType::wkbPoint, ctx);
- GeoCoordinateList p = point->to_coords();
-
- writeCoordinateList(p, false, ctx);
+ if (point->is_empty()) {
+ GeoCoordinate c(DoubleNotANumber, DoubleNotANumber);
+ writeCoordinate(c, ctx);
+ } else {
+ GeoCoordinates p = point->to_coords();
+ writeCoordinateList(p, false, ctx);
+ }
return true;
}
-bool toBinary::writeGeoLine(GeoLine* line, ToBinaryContext* ctx) {
+bool toBinary::writeGeoLine(GeoLineString* linestring, ToBinaryContext* ctx) {
writeByteOrder(ctx);
writeGeometryType(wkbType::wkbLine, ctx);
- GeoCoordinateList p = line->to_coords();
-
- writeCoordinateList(p, true, ctx);
+ if (linestring->is_empty()) {
+ writeInt(0, ctx);
+ } else {
+ GeoCoordinates p = linestring->to_coords();
+ writeCoordinateList(p, true, ctx);
+ }
return true;
}
bool toBinary::writeGeoPolygon(doris::GeoPolygon* polygon, ToBinaryContext* ctx) {
writeByteOrder(ctx);
writeGeometryType(wkbType::wkbPolygon, ctx);
- writeInt(polygon->numLoops(), ctx);
- std::unique_ptr<GeoCoordinateListList> coordss(polygon->to_coords());
+ if (polygon->is_empty()) {
+ writeInt(0, ctx);
+ } else {
+ writeInt(polygon->num_loops(), ctx);
+ std::unique_ptr<GeoCoordinateLists> coords_list(polygon->to_coords());
+ for (int i = 0; i < coords_list->coords_list.size(); ++i) {
+ writeCoordinateList(*coords_list->coords_list[i], true, ctx);
Review Comment:
warning: use range-based for loop instead [modernize-loop-convert]
```suggestion
for (auto & i : coords_list->coords_list) {
writeCoordinateList(*i, true, ctx);
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
const auto* polygon = (const GeoPolygon*)rhs;
```
##########
be/src/geo/geo_tobinary.cpp:
##########
@@ -69,29 +81,56 @@ bool toBinary::write(GeoShape* shape, ToBinaryContext* ctx) {
bool toBinary::writeGeoPoint(GeoPoint* point, ToBinaryContext* ctx) {
writeByteOrder(ctx);
writeGeometryType(wkbType::wkbPoint, ctx);
- GeoCoordinateList p = point->to_coords();
-
- writeCoordinateList(p, false, ctx);
+ if (point->is_empty()) {
+ GeoCoordinate c(DoubleNotANumber, DoubleNotANumber);
Review Comment:
warning: no matching constructor for initialization of 'doris::GeoCoordinate' [clang-diagnostic-error]
```cpp
GeoCoordinate c(DoubleNotANumber, DoubleNotANumber);
^
```
<details>
<summary>Additional context</summary>
**be/src/geo/wkt_parse_type.h:24:** candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
```cpp
struct GeoCoordinate {
^
```
**be/src/geo/wkt_parse_type.h:24:** candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
```cpp
struct GeoCoordinate {
^
```
**be/src/geo/wkt_parse_type.h:24:** candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
```cpp
struct GeoCoordinate {
^
```
</details>
##########
be/src/geo/geojson_parse.cpp:
##########
@@ -0,0 +1,259 @@
+// 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.
+
+#include "geojson_parse.h"
+
+#include <stdint.h>
Review Comment:
warning: inclusion of deprecated C++ header 'stdint.h'; consider using 'cstdint' instead [modernize-deprecated-headers]
```suggestion
#include <cstdint>
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
const auto* collection = (const GeoCollection*)rhs;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
const auto* line = (const GeoLineString*)rhs;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
RING: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
+ if (!linestring->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ if (polygon->is_empty()) continue;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
_SHAPE_POLYGON: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
if (multi_linestring->get_num_line() == 1) {auto
```
##########
be/src/geo/util/GeoCircle.cpp:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#include "GeoCircle.h"
+
+#include <s2/s2cap.h>
+#include <s2/s2earth.h>
+#include <s2/util/coding/coder.h>
+
+namespace doris {
+
+GeoCircle::GeoCircle() = default;
+GeoCircle::~GeoCircle() = default;
+
+GeoParseStatus GeoCircle::to_s2cap(double lng, double lat, double radius_meter) {
+ S2Point center;
+ auto status = GeoPoint::to_s2point(lng, lat, ¢er);
+ if (status != GEO_PARSE_OK) {
+ return status;
+ }
+ S1Angle radius = S2Earth::ToAngle(util::units::Meters(radius_meter));
+ _cap.reset(new S2Cap(center, radius));
+ if (!_cap->is_valid()) {
+ return GEO_PARSE_CIRCLE_INVALID;
+ }
+ return GEO_PARSE_OK;
+}
+
+bool GeoCircle::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
const auto* point = (const GeoPoint*)rhs;
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
RING: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
OINT: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
++i) {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
YGON: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
nt->get_num_point() == 1) {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
case GEO_SHAPE_POINT: {auto
```
##########
be/src/geo/util/GeoCollection.cpp:
##########
@@ -0,0 +1,352 @@
+// 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.
+
+#include "GeoCollection.h"
+
+#include <sstream>
+
+#include "GeoMultiLineString.h"
+#include "GeoMultiPoint.h"
+#include "GeoMultiPolygon.h"
+
+namespace doris {
+
+GeoCollection::GeoCollection() = default;
+GeoCollection::~GeoCollection() = default;
+
+bool GeoCollection::is_valid() const {
+ for (const auto& g : geometries) {
+ if (!g->is_valid()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GeoCollection::is_closed() const {
+ for (const auto& g : geometries) {
+ if (!g->is_closed()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GeoParseStatus GeoCollection::add_one_geometry(GeoShape* shape) {
+ geometries.emplace_back(std::unique_ptr<GeoShape>(shape));
+ return GEO_PARSE_OK;
+}
+
+std::size_t GeoCollection::get_num_geometries() const {
+ return geometries.size();
+}
+
+GeoShape* GeoCollection::get_geometries_n(std::size_t n) const {
+ return geometries[n].get();
+}
+
+std::string GeoCollection::as_wkt() const {
+ std::stringstream ss;
+ ss << "GEOMETRYCOLLECTION ";
+
+ if (is_empty()) {
+ ss << "EMPTY";
+ return ss.str();
+ }
+ ss << "(";
+
+ for (int i = 0; i < geometries.size(); ++i) {
+ ss << geometries[i]->as_wkt();
+ if (i != geometries.size() - 1) {
+ ss << ",";
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+bool GeoCollection::contains(const GeoShape* rhs) const {
+ switch (rhs->type()) {
+ case GEO_SHAPE_POINT: {
+ const GeoPoint* point = (const GeoPoint*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ const GeoLineString* line = (const GeoLineString*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_POLYGON: {
+ const GeoPolygon* polygon = (const GeoPolygon*)rhs;
+ for (const auto& g : geometries) {
+ if (!g->contains(polygon)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case GEO_SHAPE_MULTI_POINT:
+ case GEO_SHAPE_MULTI_LINE_STRING:
+ case GEO_SHAPE_MULTI_POLYGON:
+ case GEO_SHAPE_GEOMETRY_COLLECTION: {
+ const GeoCollection* collection = (const GeoCollection*)rhs;
+ for (const auto& g1 : collection->geometries) {
+ for (const auto& g2 : geometries) {
+ if (!g2->contains(g1.get())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+std::size_t GeoCollection::get_num_point() const {
+ if (is_empty()) return 0;
+ std::size_t num_point = 0;
+ for (const auto& g : geometries) {
+ num_point += g->get_num_point();
+ }
+ return num_point;
+}
+
+std::unique_ptr<GeoShape> GeoCollection::boundary() const {
+ std::unique_ptr<GeoCollection> collection = GeoCollection::create_unique();
+ if (is_empty()) {
+ collection->set_empty();
+ return collection;
+ }
+
+ for (const auto& g : geometries) {
+ std::unique_ptr<GeoShape> shape = g->boundary();
+ if (!shape->is_empty()) collection->add_one_geometry(shape.release());
+ }
+ if (collection->get_num_geometries() == 0) collection->set_empty();
+ return collection;
+
+ //to_homogenize 还有问题
+ //return collection->to_homogenize();
+}
+
+std::unique_ptr<GeoCollection> GeoCollection::to_homogenize() {
+ std::unique_ptr<GeoMultiPoint> multi_point = GeoMultiPoint::create_unique();
+ std::unique_ptr<GeoMultiLineString> multi_linestring = GeoMultiLineString::create_unique();
+ std::unique_ptr<GeoMultiPolygon> multi_polygon = GeoMultiPolygon::create_unique();
+
+ for (const auto& g : geometries) {
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ multi_point->add_one_geometry(g.get());
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ multi_linestring->add_one_geometry(linestring);
+ break;
+ }
+ case GEO_SHAPE_POLYGON: {
+ GeoPolygon* polygon = dynamic_cast<GeoPolygon*>(g.get());
+ multi_polygon->add_one_geometry(polygon);
+ break;
+ }
+ case GEO_SHAPE_MULTI_POINT: {
+ const GeoMultiPoint* multi_point_tmp = dynamic_cast<const GeoMultiPoint*>(g.get());
+ for (int i = 0; i < multi_point_tmp->get_num_point(); ++i) {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(multi_point_tmp->get_geometries_n(i));
+ multi_point->add_one_geometry(point);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_LINE_STRING: {
+ const GeoMultiLineString* multi_linestring_tmp =
+ dynamic_cast<const GeoMultiLineString*>(g.get());
+ for (int i = 0; i < multi_linestring_tmp->get_num_line(); ++i) {
+ GeoLineString* linestring =
+ dynamic_cast<GeoLineString*>(multi_linestring_tmp->get_geometries_n(i));
+ multi_linestring->add_one_geometry(linestring);
+ }
+ break;
+ }
+ case GEO_SHAPE_MULTI_POLYGON: {
+ const GeoMultiPolygon* multi_polygon_tmp =
+ dynamic_cast<const GeoMultiPolygon*>(g.get());
+ for (int i = 0; i < multi_polygon_tmp->get_num_polygon(); ++i) {
+ GeoPolygon* polygon =
+ dynamic_cast<GeoPolygon*>(multi_polygon_tmp->get_geometries_n(i));
+ multi_polygon->add_one_geometry(polygon);
+ }
+ break;
+ }
+ default: {
+ //这里应该输出告警日志
+ return nullptr;
+ }
+ }
+ }
+
+ std::unique_ptr<GeoCollection> res_collection = GeoCollection::create_unique();
+
+ if (multi_point->get_num_point() == 1) {
+ GeoPoint* point = (GeoPoint*)multi_point->get_geometries_n(0);
+ res_collection->add_one_geometry(point);
+ } else if (multi_point->get_num_point() > 1) {
+ res_collection->add_one_geometry(multi_point.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_linestring->get_num_line() == 1) {
+ GeoLineString* linestring = (GeoLineString*)multi_linestring->get_geometries_n(0);
+ res_collection->add_one_geometry(linestring);
+ } else if (multi_linestring->get_num_line() > 1) {
+ res_collection->add_one_geometry(multi_linestring.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ if (multi_polygon->get_num_polygon() == 1) {
+ GeoPolygon* polygon = (GeoPolygon*)multi_polygon->get_geometries_n(0);
+ res_collection->add_one_geometry(polygon);
+ } else if (multi_polygon->get_num_polygon() > 1) {
+ res_collection->add_one_geometry(multi_polygon.release());
+ }
+ /*
+ * else {
+ * 这里应该输出告警日志
+ * }
+ */
+
+ return res_collection;
+}
+
+bool GeoCollection::add_to_s2shape_index(MutableS2ShapeIndex& S2shape_index) const {
+ if (is_empty()) return false;
+ for (const auto& g : geometries) {
+ if (g->is_empty() || !g->is_valid()) continue;
+ switch (g->type()) {
+ case GEO_SHAPE_POINT: {
+ GeoPoint* point = dynamic_cast<GeoPoint*>(g.get());
+ if (point->is_empty()) continue;
+ if (!point->add_to_s2shape_index(S2shape_index)) {
+ return false;
+ }
+ break;
+ }
+ case GEO_SHAPE_LINE_STRING: {
+ GeoLineString* linestring = dynamic_cast<GeoLineString*>(g.get());
+ if (linestring->is_empty()) continue;
Review Comment:
warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
```suggestion
TRING: {auto
```
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702080314
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1702442041
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
[GitHub] [doris] LemonLiTree commented on pull request #22933: [feature](geometry) Support geometry type and more Geo functions
Posted by "LemonLiTree (via GitHub)" <gi...@apache.org>.
LemonLiTree commented on PR #22933:
URL: https://github.com/apache/doris/pull/22933#issuecomment-1700947898
run buildall
--
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: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org