gis bugfix
This commit is contained in:
2
deps/oblib/src/lib/geo/ob_geo_cache.h
vendored
2
deps/oblib/src/lib/geo/ob_geo_cache.h
vendored
@ -47,6 +47,7 @@ public:
|
||||
virtual ObVertexes& get_vertexes() = 0;
|
||||
virtual ObLineSegments* get_line_segments() = 0;
|
||||
virtual ObSegments* get_segments() = 0;
|
||||
virtual void destroy_cache() = 0;
|
||||
};
|
||||
|
||||
class ObCachedGeomBase : public ObCachedGeom {
|
||||
@ -67,6 +68,7 @@ public:
|
||||
virtual int contains(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
virtual int cover(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
virtual int within(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
virtual void destroy_cache() {this->~ObCachedGeomBase();}
|
||||
virtual ObGeometry* get_cached_geom() { return origin_geo_;}
|
||||
virtual ObGeoCacheType get_cache_type() { return ObGeoCacheType::GEO_BASE_CACHE;}
|
||||
virtual void set_cached_geom(ObGeometry* geo) { origin_geo_ = geo; }
|
||||
|
@ -37,7 +37,7 @@ int ObCachedGeoLinestring::init()
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc point location analyzer failed", K(ret));
|
||||
} else {
|
||||
lAnalyzer_ = new(buf) ObLineIntersectionAnalyzer(this, &rtree_);
|
||||
lAnalyzer_ = new(buf) ObLineIntersectionAnalyzer(this, rtree_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
virtual ObGeoCacheType get_cache_type() { return ObGeoCacheType::GEO_LINESTRING_CACHE;}
|
||||
virtual int intersects(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
virtual ObLineSegments* get_line_segments() { return &line_segments_; }
|
||||
virtual void destroy_cache() { this->~ObCachedGeoLinestring(); }
|
||||
private:
|
||||
ObRstarTree<ObLineSegment> rtree_;
|
||||
ObLineIntersectionAnalyzer *lAnalyzer_;
|
||||
|
1
deps/oblib/src/lib/geo/ob_geo_cache_point.h
vendored
1
deps/oblib/src/lib/geo/ob_geo_cache_point.h
vendored
@ -25,6 +25,7 @@ public:
|
||||
: ObCachedGeomBase(geom, allocator, srs) {}
|
||||
virtual ~ObCachedGeoPoint() {};
|
||||
virtual ObGeoCacheType get_cache_type() { return ObGeoCacheType::GEO_POINT_CACHE;}
|
||||
virtual void destroy_cache() { this->~ObCachedGeoPoint(); }
|
||||
virtual int intersects(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
};
|
||||
|
||||
|
37
deps/oblib/src/lib/geo/ob_geo_cache_polygon.cpp
vendored
37
deps/oblib/src/lib/geo/ob_geo_cache_polygon.cpp
vendored
@ -79,7 +79,7 @@ int ObCachedGeoPolygon::init_point_analyzer()
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc point location analyzer failed", K(ret));
|
||||
} else {
|
||||
pAnalyzer_ = new(buf) ObPointLocationAnalyzer(this, &seg_rtree_);
|
||||
pAnalyzer_ = new(buf) ObPointLocationAnalyzer(this, seg_rtree_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,7 +228,7 @@ int ObCachedGeoPolygon::init_line_analyzer()
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc line segment intersection analyzer failed", K(ret));
|
||||
} else {
|
||||
lAnalyzer_ = new(buf) ObLineIntersectionAnalyzer(this, &rtree_);
|
||||
lAnalyzer_ = new(buf) ObLineIntersectionAnalyzer(this, rtree_);
|
||||
// collect line segments
|
||||
ObGeoSegmentCollectVisitor seg_visitor(&line_segments_);
|
||||
if (OB_FAIL(get_cached_geom()->do_visit(seg_visitor))) {
|
||||
@ -318,24 +318,29 @@ int ObCachedGeoPolygon::get_point_position_in_polygon(int p_idx, const ObPoint2d
|
||||
} else {
|
||||
pos = ObPointLocation::INVALID;
|
||||
for (int i = start; i < end && OB_SUCC(ret) && pos == ObPointLocation::INVALID; ++i) {
|
||||
ObPointLocationAnalyzer tmp_pAnalyzer(this, rings_rtree_.rtrees_[i]);
|
||||
if (i == start) {
|
||||
// exterior ring
|
||||
if (OB_FAIL(tmp_pAnalyzer.calculate_point_position(test_point))) {
|
||||
if (OB_ISNULL(rings_rtree_.rtrees_[i])) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("rtree is null", K(ret), K(i));
|
||||
} else {
|
||||
ObPointLocationAnalyzer tmp_pAnalyzer(this, *rings_rtree_.rtrees_[i]);
|
||||
if (i == start) {
|
||||
// exterior ring
|
||||
if (OB_FAIL(tmp_pAnalyzer.calculate_point_position(test_point))) {
|
||||
LOG_WARN("calculate point position failed", K(ret), K(input_vertexes_[i]));
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::EXTERIOR) {
|
||||
// outside the exterior ring
|
||||
pos = ObPointLocation::EXTERIOR;
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::BOUNDARY) {
|
||||
pos = ObPointLocation::BOUNDARY;
|
||||
} // if is ObPointLocation::INTERIOR, need to check inner rings
|
||||
} else if (OB_FAIL(tmp_pAnalyzer.calculate_point_position(test_point))) {
|
||||
LOG_WARN("calculate point position failed", K(ret), K(input_vertexes_[i]));
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::EXTERIOR) {
|
||||
// outside the exterior ring
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::INTERIOR) {
|
||||
// inside a hole => outside the polygon
|
||||
pos = ObPointLocation::EXTERIOR;
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::BOUNDARY) {
|
||||
pos = ObPointLocation::BOUNDARY;
|
||||
} // if is ObPointLocation::INTERIOR, need to check inner rings
|
||||
} else if (OB_FAIL(tmp_pAnalyzer.calculate_point_position(test_point))) {
|
||||
LOG_WARN("calculate point position failed", K(ret), K(input_vertexes_[i]));
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::INTERIOR) {
|
||||
// inside a hole => outside the polygon
|
||||
pos = ObPointLocation::EXTERIOR;
|
||||
} else if (tmp_pAnalyzer.get_position() == ObPointLocation::BOUNDARY) {
|
||||
pos = ObPointLocation::BOUNDARY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,13 @@ public:
|
||||
ring_segments_(&seg_mode_arena, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
poly_count_(0),
|
||||
inited_(false) {}
|
||||
~ObRingsRtree() {}
|
||||
~ObRingsRtree() {
|
||||
for (int i = 0; i < rtrees_.size(); ++i) {
|
||||
if (OB_NOT_NULL(rtrees_[i])) {
|
||||
rtrees_[i]->~ObRstarTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
int get_ring_strat_idx(int p_idx, int &start, int& end);
|
||||
ObRtreeVecArena rtrees_arena_;
|
||||
ObIntArena int_arena_;
|
||||
@ -71,6 +77,7 @@ public:
|
||||
virtual int cover(ObGeometry& geo, ObGeoEvalCtx& gis_context, bool &res) override;
|
||||
virtual ObLineSegments* get_line_segments() { return &line_segments_; }
|
||||
virtual ObSegments* get_segments() { return &segments_; }
|
||||
virtual void destroy_cache() {this->~ObCachedGeoPolygon();}
|
||||
private:
|
||||
int get_farthest_point_position(ObVertexes& vertexes, ObPointLocation& farthest_position, bool& has_point_internal);
|
||||
int init_line_analyzer();
|
||||
|
@ -146,7 +146,7 @@ int ObGeoPointLocationVisitor::calculate_point_location_in_linestring(T_IBIN *ge
|
||||
typename T_IBIN::value_type::iterator iter = line->begin();
|
||||
typename T_IBIN::value_type::iterator iter_after = line->begin() + 1;
|
||||
ObSegment seg;
|
||||
for (uint32_t i = 0; i < geo_size - 1 && OB_SUCC(ret); ++i, ++iter, ++iter_after) {
|
||||
for (uint32_t i = 0; i < geo_size - 1 && OB_SUCC(ret) && point_location_ != ObPointLocation::BOUNDARY && point_location_ != ObPointLocation::INTERIOR; ++i, ++iter, ++iter_after) {
|
||||
seg.begin.x = iter->template get<0>();
|
||||
seg.begin.y = iter->template get<1>();
|
||||
seg.end.x = (iter_after)->template get<0>();
|
||||
|
1
deps/oblib/src/lib/geo/ob_geo_rstar_tree.h
vendored
1
deps/oblib/src/lib/geo/ob_geo_rstar_tree.h
vendored
@ -58,6 +58,7 @@ public:
|
||||
if (OB_FAIL(ret)) {
|
||||
} else {
|
||||
try {
|
||||
rtree_index_.~RStarTree();
|
||||
new (&rtree_index_) RStarTree(rtree_nodes.begin(), rtree_nodes.end());
|
||||
is_built_ = true;
|
||||
} catch (...) {
|
||||
|
@ -32,15 +32,12 @@ int ObLineIntersectionAnalyzer::segment_intersection_query(ObGeometry *geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_intersect_ = false;
|
||||
if (OB_ISNULL(rtree_index_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("rtree index is null", K(ret));
|
||||
} else if (!rtree_index_->is_built()) {
|
||||
if (!rtree_index_.is_built()) {
|
||||
ObLineSegments* line_segs = cache_geo_->get_line_segments();
|
||||
if (OB_ISNULL(line_segs)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("should not be null", K(ret));
|
||||
} else if (OB_FAIL(rtree_index_->construct_rtree_index(line_segs->segs_))) {
|
||||
} else if (OB_FAIL(rtree_index_.construct_rtree_index(line_segs->segs_))) {
|
||||
LOG_WARN("construct rtree index failed", K(ret));
|
||||
}
|
||||
}
|
||||
@ -58,7 +55,7 @@ int ObLineIntersectionAnalyzer::segment_intersection_query(ObGeometry *geo)
|
||||
inter_res = LineIntersect::NO_INTERSCT;
|
||||
if (OB_FAIL(input_segments.segs_[i].get_box(box))) {
|
||||
LOG_WARN("failed to get segment box", K(ret));
|
||||
} else if (OB_FAIL(rtree_index_->query(QueryRelation::INTERSECTS, box, res))) {
|
||||
} else if (OB_FAIL(rtree_index_.query(QueryRelation::INTERSECTS, box, res))) {
|
||||
LOG_WARN("failed to query rtree", K(ret));
|
||||
} else {
|
||||
for (uint32_t j = 0; j < res.size() && OB_SUCC(ret) && !is_check_done(inter_res); j++) {
|
||||
|
@ -23,7 +23,7 @@ class ObLineIntersectionAnalyzer {
|
||||
public:
|
||||
typedef std::pair<ObCartesianBox, ObLineSegment *> RtreeNodeValue;
|
||||
public:
|
||||
ObLineIntersectionAnalyzer(ObCachedGeomBase *cache_geo, ObRstarTree<ObLineSegment> *rtree_index)
|
||||
ObLineIntersectionAnalyzer(ObCachedGeomBase *cache_geo, ObRstarTree<ObLineSegment> &rtree_index)
|
||||
: cache_geo_(cache_geo),
|
||||
rtree_index_(rtree_index),
|
||||
flags_(0) {}
|
||||
@ -39,7 +39,7 @@ public:
|
||||
bool set_after_visitor() { return false; }
|
||||
private:
|
||||
ObCachedGeomBase *cache_geo_;
|
||||
ObRstarTree<ObLineSegment> *rtree_index_;
|
||||
ObRstarTree<ObLineSegment> &rtree_index_;
|
||||
union {
|
||||
struct {
|
||||
uint8_t is_intersect_ : 1;
|
||||
|
@ -20,14 +20,14 @@ namespace common {
|
||||
int ObPointLocationAnalyzer::calculate_point_position(const ObPoint2d &test_point)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(rtree_index_) || OB_ISNULL(cache_geo_)) {
|
||||
if (OB_ISNULL(cache_geo_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("rtree index or cache geo is null", K(rtree_index_), K(cache_geo_), K(ret));
|
||||
} else if (!rtree_index_->is_built()) {
|
||||
LOG_WARN("rtree index or cache geo is null", K(cache_geo_), K(ret));
|
||||
} else if (!rtree_index_.is_built()) {
|
||||
if (OB_ISNULL(cache_geo_->get_segments())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("should not be null.", K(ret));
|
||||
} else if (OB_FAIL(rtree_index_->construct_rtree_index(*(cache_geo_->get_segments())))) {
|
||||
} else if (OB_FAIL(rtree_index_.construct_rtree_index(*(cache_geo_->get_segments())))) {
|
||||
LOG_WARN("construct rtree index failed", K(ret));
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ int ObPointLocationAnalyzer::calculate_point_position(const ObPoint2d &test_poin
|
||||
ObCartesianBox box;
|
||||
box.set_box(std::min(cache_geo_->get_x_min() - 1.0, test_point.x), test_point.y,
|
||||
std::max(cache_geo_->get_x_max() + 1.0, test_point.x), test_point.y);
|
||||
if (OB_FAIL(rtree_index_->query(QueryRelation::INTERSECTS, box, res))) {
|
||||
if (OB_FAIL(rtree_index_.query(QueryRelation::INTERSECTS, box, res))) {
|
||||
LOG_WARN("failed to query rtree", K(ret));
|
||||
} else {
|
||||
bool is_on_boundary = false;
|
||||
|
@ -23,7 +23,7 @@ class ObPointLocationAnalyzer {
|
||||
public:
|
||||
typedef std::pair<ObCartesianBox, ObSegment *> RtreeNodeValue;
|
||||
public:
|
||||
ObPointLocationAnalyzer(ObCachedGeomBase *cache_geo, ObRstarTree<ObSegment> *rtree_index)
|
||||
ObPointLocationAnalyzer(ObCachedGeomBase *cache_geo, ObRstarTree<ObSegment> &rtree_index)
|
||||
: cache_geo_(cache_geo),
|
||||
rtree_index_(rtree_index),
|
||||
position_(ObPointLocation::INVALID),
|
||||
@ -36,7 +36,7 @@ public:
|
||||
void update_farthest_position();
|
||||
private:
|
||||
ObCachedGeomBase *cache_geo_;
|
||||
ObRstarTree<ObSegment> *rtree_index_;
|
||||
ObRstarTree<ObSegment> &rtree_index_;
|
||||
ObPointLocation position_;
|
||||
uint32_t intersect_cnt_;
|
||||
};
|
||||
|
@ -1798,8 +1798,7 @@ int ObDmlCgService::generate_das_projector(const ObIArray<uint64_t> &dml_column_
|
||||
int ret = OB_SUCCESS;
|
||||
IntFixedArray &old_row_projector = das_ctdef.old_row_projector_;
|
||||
IntFixedArray &new_row_projector = das_ctdef.new_row_projector_;
|
||||
bool is_spatial_index = das_ctdef.table_param_.get_data_table().is_spatial_index()
|
||||
&& das_ctdef.op_type_ == DAS_OP_TABLE_UPDATE;
|
||||
bool is_spatial_index = das_ctdef.table_param_.get_data_table().is_spatial_index();
|
||||
uint8_t extra_geo = (is_spatial_index) ? 1 : 0;
|
||||
//generate old row projector
|
||||
if (!old_row.empty()) {
|
||||
|
@ -624,19 +624,19 @@ int ObSpatialDMLIterator::get_geo_wkb(
|
||||
ObObjMeta &geo_meta) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const uint64_t geo_col_id = das_ctdef_->table_param_.get_data_table().get_spatial_geo_col_id();
|
||||
const bool has_old_row = !main_ctdef_->old_row_projector_.empty();
|
||||
geo_idx = -1;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < main_ctdef_->column_ids_.count() && -1 == geo_idx; ++i) {
|
||||
const int64_t projector_idx = has_old_row ? main_ctdef_->old_row_projector_.at(i) : i;
|
||||
if (geo_col_id == main_ctdef_->column_ids_.at(i)) {
|
||||
if (projector_idx >= store_row->cnt_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid index for sr", K(ret), KPC(store_row), K(i), K(main_ctdef_->old_row_projector_));
|
||||
} else {
|
||||
geo_idx = projector_idx;
|
||||
geo_wkb = store_row->cells()[projector_idx].get_string();
|
||||
const uint64_t rowkey_num = das_ctdef_->table_param_.get_data_table().get_rowkey_column_num();
|
||||
geo_idx = row_projector_->at(rowkey_num);
|
||||
if (geo_idx >= store_row->cnt_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid index for sr", K(ret), KPC(store_row), K(row_projector_));
|
||||
} else {
|
||||
geo_wkb = store_row->cells()[geo_idx].get_string();
|
||||
bool found = false;
|
||||
uint64_t geo_col_id = das_ctdef_->table_param_.get_data_table().get_spatial_geo_col_id();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < main_ctdef_->column_ids_.count() && !found; ++i) {
|
||||
if (geo_col_id == main_ctdef_->column_ids_.at(i)) {
|
||||
geo_meta = main_ctdef_->column_types_.at(i);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1193,6 +1193,18 @@ int ObGeoExprUtils::check_box_intersects(ObGeometry &geo1, ObGeometry &geo2, ObI
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObGeoConstParamCache::~ObGeoConstParamCache()
|
||||
{
|
||||
if (OB_NOT_NULL(cached_param1_)) {
|
||||
cached_param1_->destroy_cache();
|
||||
cached_param1_ = nullptr;
|
||||
}
|
||||
if (OB_NOT_NULL(cached_param2_)) {
|
||||
cached_param2_->destroy_cache();
|
||||
cached_param1_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ObGeometry * ObGeoConstParamCache::get_const_param_cache(int arg_idx)
|
||||
{
|
||||
ObGeometry * res = nullptr;
|
||||
|
@ -229,7 +229,7 @@ public:
|
||||
cached_param1_(nullptr),
|
||||
param2_(nullptr),
|
||||
cached_param2_(nullptr) {}
|
||||
~ObGeoConstParamCache() {};
|
||||
~ObGeoConstParamCache();
|
||||
|
||||
ObGeometry *get_const_param_cache(int arg_idx);
|
||||
ObCachedGeom *get_cached_geo(int arg_idx);
|
||||
|
@ -1338,3 +1338,6 @@ ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POLYGON((0 0,0 20,20 20,20 0, 0 0)))'))
|
||||
select st_intersects(ST_GeomFromText('LINESTRING(0 0 0, 10 10 10, 20 25 30, 50 60 -60)',26918),ST_GeomFromText('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(10 10 10), POINT(30 30 -30), LINESTRING(15 15 -15, 20 20 30),MULTIPOLYGON(((-1 -1 -1,10 10 0,-10 -20 20,0 -10 0,-1 -1 -1)))))',26918));
|
||||
st_intersects(ST_GeomFromText('LINESTRING(0 0 0, 10 10 10, 20 25 30, 50 60 -60)',26918),ST_GeomFromText('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(10 10 10), POINT(30 30 -30), LINESTRING(15 15 -15, 20 20 30),MULTIPOLYGON(((-1 -1 -1,10 10 0,-10 -20 20,0
|
||||
1
|
||||
select st_intersects(ST_GeomFromText('LINESTRING(0 0, 10 10, 20 25 , 50 60 )'),ST_GeomFromText('point(5 5 )')) ;
|
||||
st_intersects(ST_GeomFromText('LINESTRING(0 0, 10 10, 20 25 , 50 60 )'),ST_GeomFromText('point(5 5 )'))
|
||||
1
|
||||
|
@ -1099,4 +1099,6 @@
|
||||
SELECT ST_INTERSECTS(ST_GEOMFROMTEXT('POINT(10 10)'),
|
||||
ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POLYGON((0 0,0 20,20 20,20 0, 0 0)))'));
|
||||
|
||||
select st_intersects(ST_GeomFromText('LINESTRING(0 0 0, 10 10 10, 20 25 30, 50 60 -60)',26918),ST_GeomFromText('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(10 10 10), POINT(30 30 -30), LINESTRING(15 15 -15, 20 20 30),MULTIPOLYGON(((-1 -1 -1,10 10 0,-10 -20 20,0 -10 0,-1 -1 -1)))))',26918));
|
||||
select st_intersects(ST_GeomFromText('LINESTRING(0 0 0, 10 10 10, 20 25 30, 50 60 -60)',26918),ST_GeomFromText('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(10 10 10), POINT(30 30 -30), LINESTRING(15 15 -15, 20 20 30),MULTIPOLYGON(((-1 -1 -1,10 10 0,-10 -20 20,0 -10 0,-1 -1 -1)))))',26918));
|
||||
|
||||
select st_intersects(ST_GeomFromText('LINESTRING(0 0, 10 10, 20 25 , 50 60 )'),ST_GeomFromText('point(5 5 )')) ;
|
Reference in New Issue
Block a user