diff --git a/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp b/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp index 8382e68a8..1015b1369 100644 --- a/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp +++ b/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp @@ -17,6 +17,15 @@ namespace oceanbase { namespace common { +bool ObWkbToS2Visitor::prepare(ObGeometry *geo) +{ + bool bret = true; + if (OB_ISNULL(geo)) { + bret = false; + } + return bret; +} + void ObWkbToS2Visitor::add_cell_from_point(S2Point point) { S2CellId cell_id = S2CellId(point).parent(options_.max_level()); @@ -33,8 +42,8 @@ template S2Cell* ObWkbToS2Visitor::MakeS2Point(T_IBIN *geo) { S2LatLng latlng = S2LatLng::FromDegrees(geo->y(), geo->x()); - mbr_.AddPoint(latlng); add_cell_from_point(latlng); + mbr_ = mbr_.is_empty() ? S2LatLngRect(latlng, latlng) : mbr_.Union(S2LatLngRect(latlng, latlng)); S2Cell* p = new S2Cell(latlng); return p; } @@ -105,7 +114,6 @@ S2Polyline* ObWkbToS2Visitor::MakeS2Polyline(T_IBIN *geo) for ( ; iter != line->end(); iter++) { S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>()); - mbr_.AddPoint(latlng); add_cell_from_point(latlng); vertices.push_back(latlng); } @@ -142,7 +150,6 @@ S2Polygon* ObWkbToS2Visitor::MakeS2Polygon(T_IBIN *geo) typename T_BIN_RING::iterator iter = exterior.begin(); for (; iter != exterior.end(); ++iter) { S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>()); - mbr_.AddPoint(latlng); add_cell_from_point(latlng); vertices.push_back(S2Point(latlng)); } @@ -157,7 +164,6 @@ S2Polygon* ObWkbToS2Visitor::MakeS2Polygon(T_IBIN *geo) typename T_BIN_RING::iterator iter = (*iterInnerRing).begin(); for (; iter != (*iterInnerRing).end(); ++iter) { S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>()); - mbr_.AddPoint(latlng); add_cell_from_point(latlng); vertices.push_back(S2Point(latlng)); } @@ -213,7 +219,12 @@ S2Polygon* ObWkbToS2Visitor::MakeProjS2Polygon(T_IBIN *geo) int ObWkbToS2Visitor::visit(ObIWkbGeogPoint *geo) { INIT_SUCC(ret); - s2v_.emplace_back(MakeS2Point(geo)); + if (geo->length() < (WKB_GEO_BO_SIZE + WKB_GEO_TYPE_SIZE)) { + ret = OB_ERR_GIS_INVALID_DATA; + LOG_WARN("invalid swkb length", K(ret), K(geo->length())); + } else { + s2v_.emplace_back(MakeS2Point(geo)); + } return ret; } @@ -229,7 +240,14 @@ int ObWkbToS2Visitor::visit(ObIWkbGeomPoint *geo) int ObWkbToS2Visitor::visit(ObIWkbGeogLineString *geo) { INIT_SUCC(ret); - s2v_.emplace_back(MakeS2Polyline(geo)); + if (geo->length() < WKB_COMMON_WKB_HEADER_LEN) { + ret = OB_ERR_GIS_INVALID_DATA; + LOG_WARN("invalid swkb length", K(ret), K(geo->length())); + } else { + S2Polyline *polyline = MakeS2Polyline(geo); + s2v_.emplace_back(polyline); + mbr_ = mbr_.is_empty() ? polyline->GetRectBound() : mbr_.Union(polyline->GetRectBound()); + } return ret; } @@ -249,8 +267,10 @@ int ObWkbToS2Visitor::visit(ObIWkbGeogPolygon *geo) ret = OB_ERR_GIS_INVALID_DATA; LOG_WARN("invalid swkb length", K(ret), K(geo->length())); } else { - s2v_.emplace_back(MakeS2Polygon(geo)); + S2Polygon *polygon = MakeS2Polygon(geo); + s2v_.emplace_back(polygon); + mbr_ = mbr_.is_empty() ? polygon->GetRectBound() : mbr_.Union(polygon->GetRectBound()); } return ret; @@ -350,7 +370,8 @@ int64_t ObWkbToS2Visitor::get_mbr(S2LatLngRect &mbr, bool need_buffer, S1Angle d if (need_buffer) { mbr_ = mbr_.ExpandedByDistance(distance); } - mbr = mbr_; + // avoid rounding errors in mbr_ calculation + mbr = mbr_.ExpandedByDistance(S1Angle::Degrees(DBL_EPSILON)); } return ret; } diff --git a/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.h b/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.h index 416cf7560..00be56fcf 100644 --- a/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.h +++ b/deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.h @@ -23,6 +23,7 @@ #include "s2/s2polygon.h" #include "s2/s2region_coverer.h" #include "s2/s2latlng_rect.h" +#include "s2/s2latlng_rect_bounder.h" #include @@ -66,7 +67,7 @@ public: typename T_BIN_RING, typename T_BIN_INNER_RING> S2Polygon* MakeProjS2Polygon(T_IBIN *geo); - bool prepare(ObGeometry *geo) { UNUSED(geo); return true; } + bool prepare(ObGeometry *geo); // wkb int visit(ObIWkbGeometry *geo) { INIT_SUCC(ret); return ret; } int visit(ObIWkbGeogPoint *geo); diff --git a/tools/deploy/mysql_test/test_suite/geometry/t/import_default_srs_data_mysql.inc b/tools/deploy/mysql_test/test_suite/geometry/t/import_default_srs_data_mysql.inc index 9e2a67066..f721a406a 100644 --- a/tools/deploy/mysql_test/test_suite/geometry/t/import_default_srs_data_mysql.inc +++ b/tools/deploy/mysql_test/test_suite/geometry/t/import_default_srs_data_mysql.inc @@ -13,12 +13,12 @@ let $c1 = query_get_value(select count(*) as cnt from oceanbase.__all_spatial_re #alter system change tenant mysql ; #sleep 2; -if ($c1 != 5152) +if ($c1 != 5160) { --source mysql_test/test_suite/geometry/t/default_srs_data_mysql.sql + sleep 30; } -sleep 30; # TODO@dazhi: use mysql tenant #disconnect conn_admin; #connection default;