fix MBR calculation error of spherical coordinate geometry under spatial index
This commit is contained in:
37
deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp
vendored
37
deps/oblib/src/lib/geo/ob_geo_to_s2_visitor.cpp
vendored
@ -17,6 +17,15 @@
|
|||||||
namespace oceanbase {
|
namespace oceanbase {
|
||||||
namespace common {
|
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)
|
void ObWkbToS2Visitor::add_cell_from_point(S2Point point)
|
||||||
{
|
{
|
||||||
S2CellId cell_id = S2CellId(point).parent(options_.max_level());
|
S2CellId cell_id = S2CellId(point).parent(options_.max_level());
|
||||||
@ -33,8 +42,8 @@ template<typename T_IBIN>
|
|||||||
S2Cell* ObWkbToS2Visitor::MakeS2Point(T_IBIN *geo)
|
S2Cell* ObWkbToS2Visitor::MakeS2Point(T_IBIN *geo)
|
||||||
{
|
{
|
||||||
S2LatLng latlng = S2LatLng::FromDegrees(geo->y(), geo->x());
|
S2LatLng latlng = S2LatLng::FromDegrees(geo->y(), geo->x());
|
||||||
mbr_.AddPoint(latlng);
|
|
||||||
add_cell_from_point(latlng);
|
add_cell_from_point(latlng);
|
||||||
|
mbr_ = mbr_.is_empty() ? S2LatLngRect(latlng, latlng) : mbr_.Union(S2LatLngRect(latlng, latlng));
|
||||||
S2Cell* p = new S2Cell(latlng);
|
S2Cell* p = new S2Cell(latlng);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -105,7 +114,6 @@ S2Polyline* ObWkbToS2Visitor::MakeS2Polyline(T_IBIN *geo)
|
|||||||
for ( ; iter != line->end(); iter++) {
|
for ( ; iter != line->end(); iter++) {
|
||||||
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(),
|
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(),
|
||||||
iter->template get<0>());
|
iter->template get<0>());
|
||||||
mbr_.AddPoint(latlng);
|
|
||||||
add_cell_from_point(latlng);
|
add_cell_from_point(latlng);
|
||||||
vertices.push_back(latlng);
|
vertices.push_back(latlng);
|
||||||
}
|
}
|
||||||
@ -142,7 +150,6 @@ S2Polygon* ObWkbToS2Visitor::MakeS2Polygon(T_IBIN *geo)
|
|||||||
typename T_BIN_RING::iterator iter = exterior.begin();
|
typename T_BIN_RING::iterator iter = exterior.begin();
|
||||||
for (; iter != exterior.end(); ++iter) {
|
for (; iter != exterior.end(); ++iter) {
|
||||||
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>());
|
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>());
|
||||||
mbr_.AddPoint(latlng);
|
|
||||||
add_cell_from_point(latlng);
|
add_cell_from_point(latlng);
|
||||||
vertices.push_back(S2Point(latlng));
|
vertices.push_back(S2Point(latlng));
|
||||||
}
|
}
|
||||||
@ -157,7 +164,6 @@ S2Polygon* ObWkbToS2Visitor::MakeS2Polygon(T_IBIN *geo)
|
|||||||
typename T_BIN_RING::iterator iter = (*iterInnerRing).begin();
|
typename T_BIN_RING::iterator iter = (*iterInnerRing).begin();
|
||||||
for (; iter != (*iterInnerRing).end(); ++iter) {
|
for (; iter != (*iterInnerRing).end(); ++iter) {
|
||||||
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>());
|
S2LatLng latlng = S2LatLng::FromDegrees(iter->template get<1>(), iter->template get<0>());
|
||||||
mbr_.AddPoint(latlng);
|
|
||||||
add_cell_from_point(latlng);
|
add_cell_from_point(latlng);
|
||||||
vertices.push_back(S2Point(latlng));
|
vertices.push_back(S2Point(latlng));
|
||||||
}
|
}
|
||||||
@ -213,7 +219,12 @@ S2Polygon* ObWkbToS2Visitor::MakeProjS2Polygon(T_IBIN *geo)
|
|||||||
int ObWkbToS2Visitor::visit(ObIWkbGeogPoint *geo)
|
int ObWkbToS2Visitor::visit(ObIWkbGeogPoint *geo)
|
||||||
{
|
{
|
||||||
INIT_SUCC(ret);
|
INIT_SUCC(ret);
|
||||||
|
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<ObIWkbGeogPoint>(geo));
|
s2v_.emplace_back(MakeS2Point<ObIWkbGeogPoint>(geo));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +240,14 @@ int ObWkbToS2Visitor::visit(ObIWkbGeomPoint *geo)
|
|||||||
int ObWkbToS2Visitor::visit(ObIWkbGeogLineString *geo)
|
int ObWkbToS2Visitor::visit(ObIWkbGeogLineString *geo)
|
||||||
{
|
{
|
||||||
INIT_SUCC(ret);
|
INIT_SUCC(ret);
|
||||||
s2v_.emplace_back(MakeS2Polyline<ObIWkbGeogLineString, ObWkbGeogLineString>(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<ObIWkbGeogLineString, ObWkbGeogLineString>(geo);
|
||||||
|
s2v_.emplace_back(polyline);
|
||||||
|
mbr_ = mbr_.is_empty() ? polyline->GetRectBound() : mbr_.Union(polyline->GetRectBound());
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,8 +267,10 @@ int ObWkbToS2Visitor::visit(ObIWkbGeogPolygon *geo)
|
|||||||
ret = OB_ERR_GIS_INVALID_DATA;
|
ret = OB_ERR_GIS_INVALID_DATA;
|
||||||
LOG_WARN("invalid swkb length", K(ret), K(geo->length()));
|
LOG_WARN("invalid swkb length", K(ret), K(geo->length()));
|
||||||
} else {
|
} else {
|
||||||
s2v_.emplace_back(MakeS2Polygon<ObIWkbGeogPolygon, ObWkbGeogPolygon,
|
S2Polygon *polygon = MakeS2Polygon<ObIWkbGeogPolygon, ObWkbGeogPolygon,
|
||||||
ObWkbGeogLinearRing, ObWkbGeogPolygonInnerRings>(geo));
|
ObWkbGeogLinearRing, ObWkbGeogPolygonInnerRings>(geo);
|
||||||
|
s2v_.emplace_back(polygon);
|
||||||
|
mbr_ = mbr_.is_empty() ? polygon->GetRectBound() : mbr_.Union(polygon->GetRectBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -350,7 +370,8 @@ int64_t ObWkbToS2Visitor::get_mbr(S2LatLngRect &mbr, bool need_buffer, S1Angle d
|
|||||||
if (need_buffer) {
|
if (need_buffer) {
|
||||||
mbr_ = mbr_.ExpandedByDistance(distance);
|
mbr_ = mbr_.ExpandedByDistance(distance);
|
||||||
}
|
}
|
||||||
mbr = mbr_;
|
// avoid rounding errors in mbr_ calculation
|
||||||
|
mbr = mbr_.ExpandedByDistance(S1Angle::Degrees(DBL_EPSILON));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include "s2/s2polygon.h"
|
#include "s2/s2polygon.h"
|
||||||
#include "s2/s2region_coverer.h"
|
#include "s2/s2region_coverer.h"
|
||||||
#include "s2/s2latlng_rect.h"
|
#include "s2/s2latlng_rect.h"
|
||||||
|
#include "s2/s2latlng_rect_bounder.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ public:
|
|||||||
typename T_BIN_RING, typename T_BIN_INNER_RING>
|
typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||||
S2Polygon* MakeProjS2Polygon(T_IBIN *geo);
|
S2Polygon* MakeProjS2Polygon(T_IBIN *geo);
|
||||||
|
|
||||||
bool prepare(ObGeometry *geo) { UNUSED(geo); return true; }
|
bool prepare(ObGeometry *geo);
|
||||||
// wkb
|
// wkb
|
||||||
int visit(ObIWkbGeometry *geo) { INIT_SUCC(ret); return ret; }
|
int visit(ObIWkbGeometry *geo) { INIT_SUCC(ret); return ret; }
|
||||||
int visit(ObIWkbGeogPoint *geo);
|
int visit(ObIWkbGeogPoint *geo);
|
||||||
|
|||||||
@ -13,12 +13,12 @@ let $c1 = query_get_value(select count(*) as cnt from oceanbase.__all_spatial_re
|
|||||||
#alter system change tenant mysql ;
|
#alter system change tenant mysql ;
|
||||||
#sleep 2;
|
#sleep 2;
|
||||||
|
|
||||||
if ($c1 != 5152)
|
if ($c1 != 5160)
|
||||||
{
|
{
|
||||||
--source mysql_test/test_suite/geometry/t/default_srs_data_mysql.sql
|
--source mysql_test/test_suite/geometry/t/default_srs_data_mysql.sql
|
||||||
|
sleep 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 30;
|
|
||||||
# TODO@dazhi: use mysql tenant
|
# TODO@dazhi: use mysql tenant
|
||||||
#disconnect conn_admin;
|
#disconnect conn_admin;
|
||||||
#connection default;
|
#connection default;
|
||||||
|
|||||||
Reference in New Issue
Block a user