#include #include #include #include #include #define private public #include "lib/geo/ob_geo_bin.h" #include "lib/geo/ob_geo_tree.h" #include "lib/geo/ob_geo_to_tree_visitor.h" #include "lib/geo/ob_geo_tree_traits.h" #include "lib/geo/ob_geo_bin_traits.h" #include "lib/geo/ob_geo_func_register.h" #include "lib/geo/ob_geo_func_union.h" #include "lib/geo/ob_geo_func_utils.h" #include "lib/json_type/ob_json_common.h" #include "lib/random/ob_random.h" #undef private #include #include #include #include namespace bg = boost::geometry; using namespace oceanbase::common; namespace oceanbase { namespace common { class TestGeoFuncUnion : public ::testing::Test { public: TestGeoFuncUnion() {} ~TestGeoFuncUnion() {} virtual void SetUp() {} virtual void TearDown() {} static void SetUpTestCase() {} static void TearDownTestCase() {} private: // disallow copy DISALLOW_COPY_AND_ASSIGN(TestGeoFuncUnion); }; int append_bo(ObJsonBuffer& data, ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) { uint8_t sbo = static_cast(bo); return data.append(reinterpret_cast(&sbo), sizeof(uint8_t)); } int append_type(ObJsonBuffer& data, ObGeoType type, ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) { INIT_SUCC(ret); uint32_t stype = static_cast(type); if (OB_FAIL(data.reserve(sizeof(uint32_t)))) { } else { char *ptr = data.ptr() + data.length(); ObGeoWkbByteOrderUtil::write(ptr, stype, bo); ret = data.set_length(data.length() + sizeof(uint32_t)); } return ret; } int append_uint32(ObJsonBuffer& data, uint32_t val, ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) { INIT_SUCC(ret); if (OB_FAIL(data.reserve(sizeof(uint32_t)))) { } else { char *ptr = data.ptr() + data.length(); ObGeoWkbByteOrderUtil::write(ptr, val, bo); ret = data.set_length(data.length() + sizeof(uint32_t)); } return ret; } int append_double(ObJsonBuffer& data, double val, ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) { INIT_SUCC(ret); if (OB_FAIL(data.reserve(sizeof(double)))) { } else { char *ptr = data.ptr() + data.length(); ObGeoWkbByteOrderUtil::write(ptr, val, bo); ret = data.set_length(data.length() + sizeof(double)); } return ret; } void create_point(ObJsonBuffer &data, double x, double y) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::POINT)); ASSERT_EQ(OB_SUCCESS, append_double(data, x)); ASSERT_EQ(OB_SUCCESS, append_double(data, y)); } void create_line(ObJsonBuffer &data, std::vector< std::pair > &value) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::LINESTRING)); ASSERT_EQ(OB_SUCCESS, append_uint32(data, value.size())); for (auto & p : value) { ASSERT_EQ(OB_SUCCESS, append_double(data, p.first)); ASSERT_EQ(OB_SUCCESS, append_double(data, p.second)); } } void create_polygon(ObJsonBuffer &data, int lnum, int pnum, std::vector< std::pair > &value) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::POLYGON)); ASSERT_EQ(OB_SUCCESS, append_uint32(data, lnum)); int i = 0; for (int l = 0; l < lnum; l++) { ASSERT_EQ(OB_SUCCESS, append_uint32(data, pnum)); for (int p = 0; p < pnum; p++) { ASSERT_EQ(OB_SUCCESS, append_double(data, value[i].first)); ASSERT_EQ(OB_SUCCESS, append_double(data, value[i].second)); i++; } } } void create_multipoint(ObJsonBuffer &data, std::vector< std::pair > &value) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::MULTIPOINT)); ASSERT_EQ(OB_SUCCESS, append_uint32(data, value.size())); for (auto & p : value) { create_point(data, p.first, p.second); } } void create_multiline(ObJsonBuffer &data, int lnum, int pnum, std::vector< std::pair > &value) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::MULTILINESTRING)); ASSERT_EQ(OB_SUCCESS, append_uint32(data, lnum)); int i = 0; for (int l = 0; l < lnum; l++) { ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::LINESTRING)); ASSERT_EQ(OB_SUCCESS, append_uint32(data, pnum)); for (int p = 0; p < pnum; p++) { ASSERT_EQ(OB_SUCCESS, append_double(data, value[i].first)); ASSERT_EQ(OB_SUCCESS, append_double(data, value[i].second)); i++; } } } template bool is_geo_equal(GEO1 &geo1, GEO2 &geo2) { std::stringstream left; std::stringstream right; left << bg::dsv(geo1); right << bg::dsv(geo2); if (left.str() == right.str()) { return true; } std::cout << left.str() << std::endl; std::cout << right.str() << std::endl; return false; } typedef bg::strategy::within::geographic_winding ObPlPaStrategy; typedef bg::strategy::intersection::geographic_segments<> ObLlLaAaStrategy; typedef bg::model::d2::point_xy point_geom_t; typedef bg::model::multi_point mpoint_geom_t; typedef bg::model::linestring line_geom_t; typedef bg::model::multi_linestring mline_geom_t; typedef bg::model::polygon polygon_geom_t; typedef bg::model::multi_polygon mpolygon_geom_t; typedef bg::model::d2::point_xy > point_geog_t; typedef bg::model::multi_point mpoint_geog_t; typedef bg::model::linestring line_geog_t; typedef bg::model::multi_linestring mline_geog_t; typedef bg::model::polygon polygon_geog_t; typedef bg::model::multi_polygon mpolygon_geog_t; TEST_F(TestGeoFuncUnion, point_point) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 1.2, 3.5); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); create_point(data1, 3.2, 5.5); ObIWkbGeomPoint q; q.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &q); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOINT); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipoint *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 2); ASSERT_EQ(1.2, (*res)[0].get<0>()); ASSERT_EQ(3.5, (*res)[0].get<1>()); ASSERT_EQ(3.2, (*res)[1].get<0>()); ASSERT_EQ(5.5, (*res)[1].get<1>()); } TEST_F(TestGeoFuncUnion, point_point_overlap) { point_geom_t p1_bg(3.2, 5.5); point_geom_t p2_bg(3.2, 5.5); mpoint_geom_t mp_res; bg::union_(p1_bg, p2_bg, mp_res); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 3.2, 5.5); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); create_point(data1, 3.2, 5.5); ObIWkbGeomPoint q; q.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &q); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOINT); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipoint *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mp_res.size()); int i = 0; for (auto & p : mp_res) { ASSERT_EQ(p.x(), (*res)[i].get<0>()); ASSERT_EQ(p.y(), (*res)[i].get<1>()); i++; } } TEST_F(TestGeoFuncUnion, point_line) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 1.0, 3.0); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.5, 1.2)); val.push_back(std::make_pair(2.0, 4.0)); create_line(data1, val); ObIWkbGeomLineString line; line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 2); ASSERT_EQ((*res)[0].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[0]); ASSERT_EQ(1.5, (*c_l)[0].get<0>()); ASSERT_EQ(1.2, (*c_l)[0].get<1>()); ASSERT_EQ(2.0, (*c_l)[1].get<0>()); ASSERT_EQ(4.0, (*c_l)[1].get<1>()); ASSERT_EQ((*res)[1].type(), ObGeoType::POINT); ASSERT_EQ((*res)[1].crs(), ObGeoCRS::Cartesian); ObCartesianPoint *c_p = static_cast(&(*res)[1]); ASSERT_EQ(1.0, (*c_p).get<0>()); ASSERT_EQ(3.0, (*c_p).get<1>()); } TEST_F(TestGeoFuncUnion, point_line_overlap) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 1.0, 3.0); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0)); val.push_back(std::make_pair(2.0, 6.0)); create_line(data1, val); ObIWkbGeomLineString line; line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 1); ASSERT_EQ((*res)[0].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[0]); ASSERT_EQ(0.0, (*c_l)[0].get<0>()); ASSERT_EQ(0.0, (*c_l)[0].get<1>()); ASSERT_EQ(2.0, (*c_l)[1].get<0>()); ASSERT_EQ(6.0, (*c_l)[1].get<1>()); } TEST_F(TestGeoFuncUnion, point_polygon) { int i = 0; for (; i < 2; i++) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 1.0, 3.0 + 2 * i); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data1, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); { ASSERT_EQ((*res)[0].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[0]); auto & ring = c_p->exterior_ring(); ASSERT_EQ(ring.size(), 5); int i = 0; for (auto & p : ring) { ASSERT_EQ(p.get<0>(), pol_val[i].first); ASSERT_EQ(p.get<1>(), pol_val[i].second); i++; } } if (i > 0) { ASSERT_EQ(res->size(), 2); ASSERT_EQ((*res)[1].type(), ObGeoType::POINT); ASSERT_EQ((*res)[1].crs(), ObGeoCRS::Cartesian); ObCartesianPoint *c_p = static_cast(&(*res)[0]); ASSERT_EQ(p.x(), c_p->x()); ASSERT_EQ(p.y(), c_p->y()); } } } TEST_F(TestGeoFuncUnion, point_multipoint) { int i = 0; for (; i < 2; i++) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 5.0, 0.0 + 2 * i); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(5.0, 0.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data1, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &multi_point); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOINT); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipoint *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 5 + i); if ( i == 0) { int j = 0; for (auto & p : *res) { ASSERT_EQ(p.get<0>(), val[j].first); ASSERT_EQ(p.get<1>(), val[j].second); j++; } } else { ASSERT_EQ((*res)[0].get<0>(), p.x()); ASSERT_EQ((*res)[0].get<1>(), p.y()); int32_t j = 1; for (auto & po : val) { ASSERT_EQ((*res)[j].get<0>(), po.first); ASSERT_EQ((*res)[j].get<1>(), po.second); j++; } } } } TEST_F(TestGeoFuncUnion, point_multiline) { int loop = 0; for (; loop < 2; loop++) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 5.0, 0.0 + 2 * loop); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); for (uint32_t i = 0; i < line_num; i++) { std::vector< std::pair > val1; val1.push_back(std::make_pair(0.0 + i, 0.0 + i)); val1.push_back(std::make_pair(5.0 + i, 0.0 + i)); create_line(data1, val1); } ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); if (loop == 0) { ASSERT_EQ(res->size(), 2); ASSERT_EQ((*res)[0].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[0]); ASSERT_EQ((*c_l)[0].get<0>(), 0.0); ASSERT_EQ((*c_l)[0].get<1>(), 0.0); ASSERT_EQ((*c_l)[1].get<0>(), 5.0); ASSERT_EQ((*c_l)[1].get<1>(), 0.0); ASSERT_EQ((*res)[1].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[1].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l1 = static_cast(&(*res)[1]); ASSERT_EQ((*c_l1)[0].get<0>(), 1.0); ASSERT_EQ((*c_l1)[0].get<1>(), 1.0); ASSERT_EQ((*c_l1)[1].get<0>(), 6.0); ASSERT_EQ((*c_l1)[1].get<1>(), 1.0); } else { ASSERT_EQ(res->size(), 3); ASSERT_EQ((*res)[0].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[0]); ASSERT_EQ((*c_l)[0].get<0>(), 0.0); ASSERT_EQ((*c_l)[0].get<1>(), 0.0); ASSERT_EQ((*c_l)[1].get<0>(), 5.0); ASSERT_EQ((*c_l)[1].get<1>(), 0.0); ASSERT_EQ((*res)[1].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[1].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l1 = static_cast(&(*res)[1]); ASSERT_EQ((*c_l1)[0].get<0>(), 1.0); ASSERT_EQ((*c_l1)[0].get<1>(), 1.0); ASSERT_EQ((*c_l1)[1].get<0>(), 6.0); ASSERT_EQ((*c_l1)[1].get<1>(), 1.0); ASSERT_EQ((*res)[2].type(), ObGeoType::POINT); ASSERT_EQ((*res)[2].crs(), ObGeoCRS::Cartesian); ObCartesianPoint *c_p = static_cast(&(*res)[2]); ASSERT_EQ((*c_p).get<0>(), 5.0); ASSERT_EQ((*c_p).get<1>(), 2.0); } } } TEST_F(TestGeoFuncUnion, point_multipolygon) { int loop = 0; for (; loop < 2; loop++) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); create_point(data, 1.0, 2.5 + 2 * loop); ObIWkbGeomPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); const ObWkbGeomMultiPolygon *geo2 = reinterpret_cast(multi_poly.val()); ASSERT_EQ(res->empty(), false); if (loop == 0) { ASSERT_EQ(res->size(), 2); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } } else { ASSERT_EQ(res->size(), 3); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } ASSERT_EQ((*res)[2].type(), ObGeoType::POINT); ASSERT_EQ((*res)[2].crs(), ObGeoCRS::Cartesian); ObCartesianPoint *c_p = static_cast(&(*res)[2]); ASSERT_EQ((*c_p).get<0>(), 1.0); ASSERT_EQ((*c_p).get<1>(), 4.5); } } } TEST_F(TestGeoFuncUnion, line_line) { line_geom_t line_bg1, line_bg2; mline_geom_t ml; bg::read_wkt("LINESTRING(1.0 2.0, 2.0 4.0)", line_bg1); bg::read_wkt("LINESTRING(1.5 3.0, 4.0 8.0)", line_bg2); bg::union_(line_bg1, line_bg2, ml); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 2.0)); val1.push_back(std::make_pair(2.0, 4.0)); create_line(data, val1); ObIWkbGeomLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.5, 3.0)); val.push_back(std::make_pair(4.0, 8.0)); create_line(data1, val); ObIWkbGeomLineString line1; line1.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &line1); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTILINESTRING); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultilinestring *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(true, is_geo_equal(ml, *res)); } TEST_F(TestGeoFuncUnion, line_polygon) { line_geom_t line_bg; bg::read_wkt("LINESTRING(1.0 4.0, 1.0 5.0)", line_bg); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 2.0)); val1.push_back(std::make_pair(1.0, 5.0)); create_line(data, val1); ObIWkbGeomLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data1, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 2); ASSERT_EQ((*res)[0].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_pl = static_cast(&(*res)[0]); const ObWkbGeomPolygon *geo2 = reinterpret_cast(poly.val()); ASSERT_EQ(true, is_geo_equal(*geo2, *c_pl)); ObCartesianLineString *c_l = static_cast(&(*res)[1]); ASSERT_EQ(true, is_geo_equal(line_bg, *c_l)); } TEST_F(TestGeoFuncUnion, line_multipoint) { mpoint_geom_t mp_bg{{{15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 2.0)); val1.push_back(std::make_pair(1.0, 5.0)); create_line(data, val1); ObIWkbGeomLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 3.0)); val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data1, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &multi_point); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 5); ASSERT_EQ((*res)[0].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[0]); const ObWkbGeomLineString *geo2 = reinterpret_cast(line.val()); ASSERT_EQ(true, is_geo_equal(*geo2, *c_l)); for (int i = 0; i < 4; i++) { ObCartesianPoint *c_p = static_cast(&(*res)[i + 1]); ASSERT_EQ(true, is_geo_equal(mp_bg[i], *c_p)); } } TEST_F(TestGeoFuncUnion, line_multiline) { line_geom_t line_bg{{1.0, 0.0}, {2.0, 0.0}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}; mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; mline_geom_t mls_res_bg; bg::union_(line_bg, mls_bg, mls_res_bg); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 0.0)); val1.push_back(std::make_pair(2.0, 0.0)); val1.push_back(std::make_pair(15.0, 0.0)); val1.push_back(std::make_pair(15.0, 10.0)); val1.push_back(std::make_pair(5.0, 10.0)); val1.push_back(std::make_pair(5.0, 1.0)); create_line(data, val1); ObIWkbGeomLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTILINESTRING); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultilinestring *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(true, is_geo_equal(*res, mls_res_bg)); } TEST_F(TestGeoFuncUnion, line_multipolygon) { line_geom_t line_bg{{1.0, 0.0}, {2.0, 0.0}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}; mpolygon_geom_t mpol_bg; boost::geometry::read_wkt("MULTIPOLYGON(((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0)), ((0.0 2.0, 2.0 2.0, 2.0 3.0, 0.0 3.0, 0.0 2.0)))", mpol_bg); mline_geom_t mline_bg; bg::difference(line_bg, mpol_bg, mline_bg); // std::cout << bg::dsv(mline_bg) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 0.0)); val1.push_back(std::make_pair(2.0, 0.0)); val1.push_back(std::make_pair(15.0, 0.0)); val1.push_back(std::make_pair(15.0, 10.0)); val1.push_back(std::make_pair(5.0, 10.0)); val1.push_back(std::make_pair(5.0, 1.0)); create_line(data, val1); ObIWkbGeomLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 3); const ObWkbGeomMultiPolygon *geo2 = reinterpret_cast(multi_poly.val()); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } ASSERT_EQ((*res)[i].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(mline_bg[0], *c_l)); } TEST_F(TestGeoFuncUnion, polygon_multipoint) { mpoint_geom_t mp_bg{{{1.0, 5.0}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 3.0)); val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data1, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &multi_point); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 6); ASSERT_EQ((*res)[0].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_pol = static_cast(&(*res)[0]); const ObWkbGeomPolygon *geo2 = reinterpret_cast(poly.val()); ASSERT_EQ(true, is_geo_equal(*geo2, *c_pol)); for (int i = 0; i < 5; i++) { ObCartesianPoint *c_p = static_cast(&(*res)[i + 1]); ASSERT_EQ(true, is_geo_equal(mp_bg[i], *c_p)); } } TEST_F(TestGeoFuncUnion, polygon_multiline) { mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; polygon_geom_t pol_bg; boost::geometry::read_wkt( "POLYGON((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0))", pol_bg); mline_geom_t mls_res; bg::difference(mls_bg, pol_bg, mls_res); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 3); ASSERT_EQ((*res)[0].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_pol = static_cast(&(*res)[0]); const ObWkbGeomPolygon *geo2 = reinterpret_cast(poly.val()); ASSERT_EQ(true, is_geo_equal(*geo2, *c_pol)); int i = 0; for (auto iter = mls_res.begin(); iter != mls_res.end(); iter++) { ObCartesianLineString *c_l = static_cast(&(*res)[i + 1]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } } TEST_F(TestGeoFuncUnion, polygon_multipolygon) { polygon_geom_t pol_bg; boost::geometry::read_wkt( "POLYGON((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0))", pol_bg); mpolygon_geom_t mpol_bg; boost::geometry::read_wkt("MULTIPOLYGON(((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0)), ((0.0 2.0, 2.0 2.0, 2.0 3.0, 0.0 3.0, 0.0 2.0)))", mpol_bg); mpolygon_geom_t mpol_res_bg; bg::union_(pol_bg, mpol_bg, mpol_res_bg); // std::cout << bg::dsv(mline_bg) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipolygon *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(mpol_res_bg, *res)); // std::cout << bg::dsv(*res) << std::endl; ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, poly.do_visit(poly_visitor)); ASSERT_EQ(poly_visitor.get_geometry()->type(), ObGeoType::POLYGON); ASSERT_EQ(poly_visitor.get_geometry()->crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *poly_tree1 = static_cast(poly_visitor.get_geometry()); ObGeoToTreeVisitor poly_visitor1(&allocator); ASSERT_EQ(OB_SUCCESS, multi_poly.do_visit(poly_visitor1)); ASSERT_EQ(poly_visitor1.get_geometry()->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(poly_visitor1.get_geometry()->crs(), ObGeoCRS::Cartesian); ObCartesianMultipolygon *poly_tree2 = static_cast(poly_visitor1.get_geometry()); ObGeoEvalCtx gis_tree_context(&allocator); gis_tree_context.ut_set_geo_count(2); gis_tree_context.ut_set_geo_arg(0, poly_tree1); gis_tree_context.ut_set_geo_arg(1, poly_tree2); ObGeometry *result_tree = NULL; ret = ObGeoFunc::geo_func::eval(gis_tree_context, result_tree); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result_tree != NULL); ObCartesianMultipolygon *res_tree = reinterpret_cast(result_tree); ASSERT_EQ(res_tree->empty(), false); ASSERT_EQ(res_tree->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(*res_tree, mpol_res_bg)); } TEST_F(TestGeoFuncUnion, multipoint_multipoint) { mpoint_geom_t mp_bg1{{{1.0, 5.0}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mpoint_geom_t mp_bg2{{{2.0, 5.0}, {15.0, 7.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 12.0}}}; mpoint_geom_t mp_bg_res; bg::union_(mp_bg1, mp_bg2, mp_bg_res); // std::cout << bg::dsv(mp_bg_res) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(2.0, 5.0)); val1.push_back(std::make_pair(15.0, 7.0)); val1.push_back(std::make_pair(15.0, 10.0)); val1.push_back(std::make_pair(5.0, 10.0)); val1.push_back(std::make_pair(5.0, 12.0)); create_multipoint(data1, val1); ObIWkbGeomMultiPoint multi_point1; multi_point1.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_point); gis_context.ut_set_geo_arg(1, &multi_point1); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOINT); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipoint *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mp_bg_res.size()); ASSERT_EQ(true, is_geo_equal(mp_bg_res, *res)); // std::cout << bg::dsv(*res) << std::endl; } TEST_F(TestGeoFuncUnion, multipoint_multiline) { mpoint_geom_t mp_bg{{{0.0, 0.5}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {20.0, 0.0}}}; mpoint_geom_t mp_bg_res; bg::difference(mp_bg, mls_bg, mp_bg_res); // std::cout << bg::dsv(mp_bg_res) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.5)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(20.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_point); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 5); const ObWkbGeomMultiLineString *geo2 = reinterpret_cast(multi_line.val()); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ObCartesianLineString *c_l = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } for (auto iter = mp_bg_res.begin(); iter != mp_bg_res.end(); iter++) { ObCartesianPoint *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } } TEST_F(TestGeoFuncUnion, multipoint_multipolygon) { mpoint_geom_t mp_bg{{{1.0, 0.0}, {2.0, 0.0}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mpolygon_geom_t mpol_bg; boost::geometry::read_wkt("MULTIPOLYGON(((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0)), ((0.0 2.0, 2.0 2.0, 2.0 3.0, 0.0 3.0, 0.0 2.0)))", mpol_bg); mpoint_geom_t mp_bg_res; bg::difference(mp_bg, mpol_bg, mp_bg_res); // std::cout << bg::dsv(mline_bg) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 0.0)); val1.push_back(std::make_pair(2.0, 0.0)); val1.push_back(std::make_pair(15.0, 0.0)); val1.push_back(std::make_pair(15.0, 10.0)); val1.push_back(std::make_pair(5.0, 10.0)); val1.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val1); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_point); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mp_bg_res.size() + polygon_num); const ObWkbGeomMultiPolygon *geo2 = reinterpret_cast(multi_poly.val()); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } for (auto iter = mp_bg_res.begin(); iter != mp_bg_res.end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POINT); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPoint *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } } TEST_F(TestGeoFuncUnion, multiline_multiline) { mline_geom_t mls1_bg{{{1.0, 0.0}, {2.0, 0.0}, {15.0, 0.0}}, {{15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mline_geom_t mls2_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; mline_geom_t mls_res_bg; bg::union_(mls1_bg, mls2_bg, mls_res_bg); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data, line_num)); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 0.0)); val1.push_back(std::make_pair(2.0, 0.0)); val1.push_back(std::make_pair(15.0, 0.0)); create_line(data, val1); std::vector< std::pair > val4; val4.push_back(std::make_pair(15.0, 10.0)); val4.push_back(std::make_pair(5.0, 10.0)); val4.push_back(std::make_pair(5.0, 1.0)); create_line(data, val4); ObIWkbGeomMultiLineString multi_line1; multi_line1.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line2; multi_line2.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_line1); gis_context.ut_set_geo_arg(1, &multi_line2); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTILINESTRING); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultilinestring *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mls_res_bg.size()); ASSERT_EQ(true, is_geo_equal(*res, mls_res_bg)); } TEST_F(TestGeoFuncUnion, multiline_multipolygon) { mline_geom_t mls_bg{{{1.0, 0.0}, {2.0, 0.0}, {15.0, 0.0}}, {{15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mpolygon_geom_t mpol_bg; boost::geometry::read_wkt("MULTIPOLYGON(((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0)), ((0.0 2.0, 2.0 2.0, 2.0 3.0, 0.0 3.0, 0.0 2.0)))", mpol_bg); mline_geom_t mline_bg; bg::difference(mls_bg, mpol_bg, mline_bg); // std::cout << bg::dsv(mline_bg) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data, line_num)); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 0.0)); val1.push_back(std::make_pair(2.0, 0.0)); val1.push_back(std::make_pair(15.0, 0.0)); create_line(data, val1); std::vector< std::pair > val2; val2.push_back(std::make_pair(15.0, 10.0)); val2.push_back(std::make_pair(5.0, 10.0)); val2.push_back(std::make_pair(5.0, 1.0)); create_line(data, val2); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_line); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), polygon_num + mline_bg.size()); const ObWkbGeomMultiPolygon *geo2 = reinterpret_cast(multi_poly.val()); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } for (auto iter = mline_bg.begin(); iter != mline_bg.end(); iter++) { ASSERT_EQ((*res)[i].type(), ObGeoType::LINESTRING); ASSERT_EQ((*res)[i].crs(), ObGeoCRS::Cartesian); ObCartesianLineString *c_l = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } } TEST_F(TestGeoFuncUnion, multipolygon_multipolygon) { mpolygon_geom_t mpol1_bg; boost::geometry::read_wkt( "MULTIPOLYGON(((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0)), ((0.0 2.0, 1.0 2.0, 1.0 6.0, 0.0 6.0, 0.0 2.0)))", mpol1_bg); mpolygon_geom_t mpol2_bg; boost::geometry::read_wkt("MULTIPOLYGON(((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0)), ((0.0 2.0, 2.0 2.0, 2.0 3.0, 0.0 3.0, 0.0 2.0)))", mpol2_bg); mpolygon_geom_t mpol_res_bg; bg::union_(mpol1_bg, mpol2_bg, mpol_res_bg); // std::cout << bg::dsv(mline_bg) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data)); ASSERT_EQ(OB_SUCCESS, append_type(data, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data, 1, 5, pol_val); } ObIWkbGeomMultiPolygon multi_poly1; multi_poly1.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 0.0 + 2 * i)); val.push_back(std::make_pair(2.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 1.0 + 2 * i)); val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeomMultiPolygon multi_poly2; multi_poly2.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_poly1); gis_context.ut_set_geo_arg(1, &multi_poly2); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipolygon *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(mpol_res_bg, *res)); // std::cout << bg::dsv(*res) << std::endl; } int mock_get_tenant_srs_item(ObIAllocator &allocator, uint64_t srs_id, const ObSrsItem *&srs_item) { int ret = OB_SUCCESS; ObGeographicRs rs; rs.rs_name.assign_ptr("ED50", strlen("ED50")); rs.datum_info.name.assign_ptr("European Datum 1950", strlen("European Datum 1950")); rs.datum_info.spheroid.name.assign_ptr("International 1924", strlen("International 1924")); rs.datum_info.spheroid.inverse_flattening = 297; rs.datum_info.spheroid.semi_major_axis = 6378388; rs.primem.longtitude = 0; rs.unit.conversion_factor = 0.017453292519943278; rs.axis.x.direction = ObAxisDirection::NORTH; rs.axis.y.direction = ObAxisDirection::EAST; rs.datum_info.towgs84.value[0] = -157.89; rs.datum_info.towgs84.value[1] = -17.16; rs.datum_info.towgs84.value[2] = -78.41; rs.datum_info.towgs84.value[3] = 2.118; rs.datum_info.towgs84.value[4] = 2.697; rs.datum_info.towgs84.value[5] = -1.434; rs.datum_info.towgs84.value[6] = -5.38; rs.authority.is_valid = false; ObSpatialReferenceSystemBase *srs_info; if (OB_FAIL(ObSpatialReferenceSystemBase::create_geographic_srs(&allocator, srs_id, &rs, srs_info))) { printf("faild to create geographical srs, ret=%d", ret); } ObSrsItem *tmp_srs_item = NULL; if (OB_ISNULL(tmp_srs_item = OB_NEWx(ObSrsItem, (&allocator), srs_info))) { ret = OB_ALLOCATE_MEMORY_FAILED; printf("fail to alloc memory for srs item, ret=%d", ret); } else { srs_item = tmp_srs_item; } return ret; } // union LL strategy TEST_F(TestGeoFuncUnion, line_line_geog) { ObArenaAllocator allocator(ObModIds::TEST); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); line_geog_t line_bg1, line_bg2; mline_geog_t ml; bg::read_wkt("LINESTRING(1.0 2.0, 2.0 4.0)", line_bg1); bg::read_wkt("LINESTRING(1.5 3.0, 4.0 8.0)", line_bg2); boost::geometry::srs::spheroid geog_sphere(srs->semi_major_axis(), srs->semi_minor_axis()); ObLlLaAaStrategy line_strategy(geog_sphere); bg::union_(line_bg1, line_bg2, ml, line_strategy); ObJsonBuffer data(&allocator); std::vector< std::pair > val1; val1.push_back(std::make_pair(1.0, 2.0)); val1.push_back(std::make_pair(2.0, 4.0)); create_line(data, val1); ObIWkbGeogLineString line; line.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.5, 3.0)); val.push_back(std::make_pair(4.0, 8.0)); create_line(data1, val); ObIWkbGeogLineString line1; line1.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator, srs); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &line); gis_context.ut_set_geo_arg(1, &line1); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTILINESTRING); ASSERT_EQ(result->crs(), ObGeoCRS::Geographic); ObGeographMultilinestring *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(true, is_geo_equal(ml, *res)); std::cout << bg::dsv(*res) << std::endl; } // union LL strategy TEST_F(TestGeoFuncUnion, polygon_multipolygon_geog) { ObArenaAllocator allocator(ObModIds::TEST); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); polygon_geog_t pol_bg; boost::geometry::read_wkt( "POLYGON((1.0 0.5, 2.0 0.5, 2.0 4.0, 1.0 4.0, 1.0 0.5))", pol_bg); mpolygon_geog_t mpol_bg; boost::geometry::read_wkt("MULTIPOLYGON(((1.0 0.5, 3.0 0.5, 3.0 1.0, 1.0 1.0, 1.0 0.5)), ((1.0 2.5, 3.0 2.5, 3.0 3.0, 1.0 3.0, 1.0 2.5)))", mpol_bg); boost::geometry::srs::spheroid geog_sphere(srs->semi_major_axis(), srs->semi_minor_axis()); ObLlLaAaStrategy line_strategy(geog_sphere); mpolygon_geog_t mpol_res_bg; bg::union_(pol_bg, mpol_bg, mpol_res_bg, line_strategy); std::cout << bg::dsv(mpol_res_bg) << std::endl; ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(1.0, 0.5)); pol_val.push_back(std::make_pair(2.0, 0.5)); pol_val.push_back(std::make_pair(2.0, 4.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(1.0, 0.5)); create_polygon(data, 1, 5, pol_val); ObIWkbGeogPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 0.5 + 2 * i)); val.push_back(std::make_pair(3.0, 0.5 + 2 * i)); val.push_back(std::make_pair(3.0, 1.0 + 2 * i)); val.push_back(std::make_pair(1.0, 1.0 + 2 * i)); val.push_back(std::make_pair(1.0, 0.5 + 2 * i)); create_polygon(data1, 1, 5, val); } ObIWkbGeogMultiPolygon multi_poly; multi_poly.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator, srs); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &multi_poly); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(result->crs(), ObGeoCRS::Geographic); ObGeographMultipolygon *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(mpol_res_bg, *res)); // std::cout << bg::dsv(*res) << std::endl; ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, poly.do_visit(poly_visitor)); ASSERT_EQ(poly_visitor.get_geometry()->type(), ObGeoType::POLYGON); ASSERT_EQ(poly_visitor.get_geometry()->crs(), ObGeoCRS::Geographic); ObGeographPolygon *poly_tree1 = static_cast(poly_visitor.get_geometry()); ObGeoToTreeVisitor poly_visitor1(&allocator); ASSERT_EQ(OB_SUCCESS, multi_poly.do_visit(poly_visitor1)); ASSERT_EQ(poly_visitor1.get_geometry()->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(poly_visitor1.get_geometry()->crs(), ObGeoCRS::Geographic); ObGeographMultipolygon *poly_tree2 = static_cast(poly_visitor1.get_geometry()); ObGeoEvalCtx gis_tree_context(&allocator, srs); gis_tree_context.ut_set_geo_count(2); gis_tree_context.ut_set_geo_arg(0, poly_tree1); gis_tree_context.ut_set_geo_arg(1, poly_tree2); ObGeometry *result_tree = NULL; ret = ObGeoFunc::geo_func::eval(gis_tree_context, result_tree); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result_tree != NULL); ObGeographMultipolygon *res_tree = reinterpret_cast(result_tree); ASSERT_EQ(res_tree->empty(), false); ASSERT_EQ(res_tree->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(*res_tree, mpol_res_bg)); } // difference PL strategy TEST_F(TestGeoFuncUnion, multipoint_multiline_geog) { ObArenaAllocator allocator(ObModIds::TEST); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); mpoint_geom_t mp_bg{{{0.0, 0.5}, {15.0, 0.0}, {15.0, 10.0}, {5.0, 10.0}, {5.0, 1.0}}}; mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {20.0, 0.0}}}; mpoint_geom_t mp_bg_res; boost::geometry::srs::spheroid geog_sphere(srs->semi_major_axis(), srs->semi_minor_axis()); ObPlPaStrategy point_strategy(geog_sphere); bg::difference(mp_bg, mls_bg, mp_bg_res, point_strategy); std::cout << bg::dsv(mp_bg_res) << std::endl; ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(0.0, 0.5)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(15.0, 10.0)); val.push_back(std::make_pair(5.0, 10.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val); ObIWkbGeogMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(20.0, 0.0)); create_line(data1, val3); ObIWkbGeogMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator, srs); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &multi_point); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Geographic); ObGeographGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), line_num + mp_bg_res.size()); const ObWkbGeogMultiLineString *geo2 = reinterpret_cast(multi_line.val()); int i = 0; for (auto iter = geo2->begin(); iter != geo2->end(); iter++) { ObGeographLineString *c_l = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } for (auto iter = mp_bg_res.begin(); iter != mp_bg_res.end(); iter++) { ObGeographPoint *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_p)); i++; } } // difference LL strategy TEST_F(TestGeoFuncUnion, polygon_multiline_geog) { ObArenaAllocator allocator(ObModIds::TEST); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); mline_geog_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; polygon_geog_t pol_bg; boost::geometry::read_wkt( "POLYGON((1.0 1.0, 2.0 1.0, 2.0 4.0, 1.0 4.0, 1.0 1.0))", pol_bg); mline_geog_t mls_res; boost::geometry::srs::spheroid geog_sphere(srs->semi_major_axis(), srs->semi_minor_axis()); ObLlLaAaStrategy line_strategy(geog_sphere); bg::difference(mls_bg, pol_bg, mls_res, line_strategy); std::cout << bg::dsv(mls_res) << std::endl; ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(1.0, 1.0)); pol_val.push_back(std::make_pair(2.0, 1.0)); pol_val.push_back(std::make_pair(2.0, 4.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(1.0, 1.0)); create_polygon(data, 1, 5, pol_val); ObIWkbGeogPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeogMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator, srs); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Geographic); ObGeographGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mls_res.size() + 1); ASSERT_EQ((*res)[0].type(), ObGeoType::POLYGON); ASSERT_EQ((*res)[0].crs(), ObGeoCRS::Geographic); ObGeographPolygon *c_pol = static_cast(&(*res)[0]); const ObWkbGeogPolygon *geo2 = reinterpret_cast(poly.val()); ASSERT_EQ(true, is_geo_equal(*geo2, *c_pol)); int i = 0; for (auto iter = mls_res.begin(); iter != mls_res.end(); iter++) { ObGeographLineString *c_l = static_cast(&(*res)[i + 1]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } } // disjoint pl strategy TEST_F(TestGeoFuncUnion, point_multiline_geog) { ObArenaAllocator allocator(ObModIds::TEST); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); mline_geog_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; point_geog_t p_bg(1.0, 1.0); boost::geometry::srs::spheroid geog_sphere(srs->semi_major_axis(), srs->semi_minor_axis()); ObPlPaStrategy point_strategy(geog_sphere); ASSERT_EQ(true, bg::disjoint(p_bg, mls_bg, point_strategy)); ObJsonBuffer data(&allocator); create_point(data, 1.0, 1.0); ObIWkbGeogPoint p; p.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeogMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator, srs); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &p); gis_context.ut_set_geo_arg(1, &multi_line); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::GEOMETRYCOLLECTION); ASSERT_EQ(result->crs(), ObGeoCRS::Geographic); ObGeographGeometrycollection *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), 3); int i = 0; for (auto iter = mls_bg.begin(); iter != mls_bg.end(); iter++) { ObGeographLineString *c_l = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(*iter, *c_l)); i++; } ObGeographPoint *c_p = static_cast(&(*res)[i]); ASSERT_EQ(true, is_geo_equal(p_bg, *c_p)); } TEST_F(TestGeoFuncUnion, polygon_polygon) { polygon_geom_t pol_bg1; boost::geometry::read_wkt( "POLYGON((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0))", pol_bg1); polygon_geom_t pol_bg2; boost::geometry::read_wkt("POLYGON((0.0 0.0, 2.0 0.0, 2.0 1.0, 0.0 1.0, 0.0 0.0))", pol_bg2); mpolygon_geom_t mpol_res_bg; bg::union_(pol_bg1, pol_bg2, mpol_res_bg); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 0.0)); pol_val.push_back(std::make_pair(1.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 4.0)); pol_val.push_back(std::make_pair(0.0, 0.0)); create_polygon(data, 1, 5, pol_val); ObIWkbGeomPolygon poly; poly.set_data(data.string()); ObJsonBuffer data1(&allocator); std::vector< std::pair > pol_val1; pol_val1.push_back(std::make_pair(0.0, 0.0)); pol_val1.push_back(std::make_pair(2.0, 0.0)); pol_val1.push_back(std::make_pair(2.0, 1.0)); pol_val1.push_back(std::make_pair(0.0, 1.0)); pol_val1.push_back(std::make_pair(0.0, 0.0)); create_polygon(data1, 1, 5, pol_val1); ObIWkbGeomPolygon poly1; poly1.set_data(data1.string()); ObGeoEvalCtx gis_context(&allocator); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &poly); gis_context.ut_set_geo_arg(1, &poly1); ObGeometry *result = NULL; int ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result != NULL); ASSERT_EQ(result->type(), ObGeoType::MULTIPOLYGON); ASSERT_EQ(result->crs(), ObGeoCRS::Cartesian); ObCartesianMultipolygon *res = reinterpret_cast(result); ASSERT_EQ(res->empty(), false); ASSERT_EQ(res->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(*res, mpol_res_bg)); ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, poly.do_visit(poly_visitor)); ASSERT_EQ(poly_visitor.get_geometry()->type(), ObGeoType::POLYGON); ASSERT_EQ(poly_visitor.get_geometry()->crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *poly_tree1 = static_cast(poly_visitor.get_geometry()); ObGeoToTreeVisitor poly_visitor1(&allocator); ASSERT_EQ(OB_SUCCESS, poly1.do_visit(poly_visitor1)); ASSERT_EQ(poly_visitor1.get_geometry()->type(), ObGeoType::POLYGON); ASSERT_EQ(poly_visitor1.get_geometry()->crs(), ObGeoCRS::Cartesian); ObCartesianPolygon *poly_tree2 = static_cast(poly_visitor1.get_geometry()); ObGeoEvalCtx gis_tree_context(&allocator); gis_tree_context.ut_set_geo_count(2); gis_tree_context.ut_set_geo_arg(0, poly_tree1); gis_tree_context.ut_set_geo_arg(1, poly_tree2); ObGeometry *result_tree = NULL; ret = ObGeoFunc::geo_func::eval(gis_tree_context, result_tree); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(result_tree != NULL); ObCartesianMultipolygon *res_tree = reinterpret_cast(result_tree); ASSERT_EQ(res_tree->empty(), false); ASSERT_EQ(res_tree->size(), mpol_res_bg.size()); ASSERT_EQ(true, is_geo_equal(*res_tree, mpol_res_bg)); } TEST_F(TestGeoFuncUnion, gc_union) { mpolygon_geom_t mpol_bg; boost::geometry::read_wkt( "MULTIPOLYGON(((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0)), ((0.0 2.0, 1.0 2.0, 1.0 6.0, 0.0 6.0, 0.0 2.0)))", mpol_bg); mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; mpoint_geom_t mp_bg{{{1.0, 5.0}, {15.0, 0.0}, {0.5, 2.6}, {1.5, 0.0}, {5.0, 1.0}}}; mpolygon_geom_t mpol_bg_tmp; mpolygon_geom_t *mpol_bg_res = &mpol_bg_tmp; mline_geom_t mls_bg_res; mpoint_geom_t mp_bg_res; for (auto & poly : mpol_bg) { mpolygon_geom_t tmp_res; bg::union_(poly, *mpol_bg_res, tmp_res); *mpol_bg_res = tmp_res; } bg::difference(mls_bg, *mpol_bg_res, mls_bg_res); mpoint_geom_t mp_bg_tmp; bg::difference(mp_bg, mls_bg_res, mp_bg_tmp); bg::difference(mp_bg_tmp, *mpol_bg_res, mp_bg_res); std::cout << "muli_poly: " << bg::dsv(*mpol_bg_res) << std::endl; std::cout << "muli_line: " << bg::dsv(mls_bg_res) << std::endl; std::cout << "muli_point: " << bg::dsv(mp_bg_res) << std::endl; ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(0.5, 2.6)); val.push_back(std::make_pair(1.5, 0.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObJsonBuffer data3(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data3)); ASSERT_EQ(OB_SUCCESS, append_type(data3, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data3, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data3, 1, 5, pol_val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data3.string()); ObGeoToTreeVisitor point_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_point.do_visit(point_visitor)); ObCartesianMultipoint *multi_point_tree = static_cast(point_visitor.get_geometry()); ObGeoToTreeVisitor line_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_line.do_visit(line_visitor)); ObCartesianMultilinestring *multi_line_tree = static_cast(line_visitor.get_geometry()); ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_poly.do_visit(poly_visitor)); ObCartesianMultipolygon *multi_poly_tree = static_cast(poly_visitor.get_geometry()); const ObSrsItem *srs = NULL; ASSERT_EQ(OB_SUCCESS, mock_get_tenant_srs_item(allocator, 4326, srs)); int ret = ObGeoFuncUtils::ob_geo_gc_union(allocator, *srs, multi_point_tree, multi_line_tree, multi_poly_tree); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(true, is_geo_equal(mp_bg_res, *multi_point_tree)); ASSERT_EQ(true, is_geo_equal(mls_bg_res, *multi_line_tree)); ASSERT_EQ(true, is_geo_equal(*mpol_bg_res, *multi_poly_tree)); } TEST_F(TestGeoFuncUnion, remove_duplicate_geo) { mpoint_geom_t mp_bg{{{1.0, 5.0}, {15.0, 0.0}, {0.5, 2.6}, {1.5, 0.0}, {5.0, 1.0}}}; mline_geom_t mls_bg{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}}, {{1.0, 0.0}, {2.0, 0.0}}}; mpolygon_geom_t mpol_bg; boost::geometry::read_wkt( "MULTIPOLYGON(((0.0 0.0, 1.0 0.0, 1.0 4.0, 0.0 4.0, 0.0 0.0)), ((0.0 2.0, 1.0 2.0, 1.0 6.0, 0.0 6.0, 0.0 2.0)))", mpol_bg); ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(0.5, 2.6)); val.push_back(std::make_pair(1.5, 0.0)); val.push_back(std::make_pair(5.0, 1.0)); val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(0.5, 2.6)); create_multipoint(data, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObGeoToTreeVisitor point_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_point.do_visit(point_visitor)); ObGeometry *multi_point_tree = point_visitor.get_geometry(); int ret = OB_SUCCESS; ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 3; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); std::vector< std::pair > val4; val4.push_back(std::make_pair(1.0, 0.0)); val4.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val4); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObGeoToTreeVisitor line_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_line.do_visit(line_visitor)); ObGeometry *multi_line_tree = line_visitor.get_geometry(); ObJsonBuffer data3(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data3)); ASSERT_EQ(OB_SUCCESS, append_type(data3, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 3; ASSERT_EQ(OB_SUCCESS, append_uint32(data3, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * (i % 2))); pol_val.push_back(std::make_pair(1.0, 0.0 + 2 * (i % 2))); pol_val.push_back(std::make_pair(1.0, 4.0 + 2 * (i % 2))); pol_val.push_back(std::make_pair(0.0, 4.0 + 2 * (i % 2))); pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * (i % 2))); create_polygon(data3, 1, 5, pol_val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data3.string()); ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_poly.do_visit(poly_visitor)); ObGeometry *multi_poly_tree = poly_visitor.get_geometry(); } TEST_F(TestGeoFuncUnion, gc_split) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer data(&allocator); std::vector< std::pair > val; val.push_back(std::make_pair(1.0, 5.0)); val.push_back(std::make_pair(15.0, 0.0)); val.push_back(std::make_pair(0.5, 2.6)); val.push_back(std::make_pair(1.5, 0.0)); val.push_back(std::make_pair(5.0, 1.0)); create_multipoint(data, val); ObIWkbGeomMultiPoint multi_point; multi_point.set_data(data.string()); ObJsonBuffer data1(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data1)); ASSERT_EQ(OB_SUCCESS, append_type(data1, ObGeoType::MULTILINESTRING)); uint32_t line_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data1, line_num)); std::vector< std::pair > val2; val2.push_back(std::make_pair(0.0, 0.0)); val2.push_back(std::make_pair(0.0, 1.0)); val2.push_back(std::make_pair(2.0, 1.0)); create_line(data1, val2); std::vector< std::pair > val3; val3.push_back(std::make_pair(1.0, 0.0)); val3.push_back(std::make_pair(2.0, 0.0)); create_line(data1, val3); ObIWkbGeomMultiLineString multi_line; multi_line.set_data(data1.string()); ObJsonBuffer data3(&allocator); ASSERT_EQ(OB_SUCCESS, append_bo(data3)); ASSERT_EQ(OB_SUCCESS, append_type(data3, ObGeoType::MULTIPOLYGON)); uint32_t polygon_num = 2; ASSERT_EQ(OB_SUCCESS, append_uint32(data3, polygon_num)); for (uint32_t i = 0; i < polygon_num; i++) { std::vector< std::pair > pol_val; pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 0.0 + 2 * i)); pol_val.push_back(std::make_pair(1.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 4.0 + 2 * i)); pol_val.push_back(std::make_pair(0.0, 0.0 + 2 * i)); create_polygon(data3, 1, 5, pol_val); } ObIWkbGeomMultiPolygon multi_poly; multi_poly.set_data(data3.string()); ObGeoToTreeVisitor point_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_point.do_visit(point_visitor)); ObCartesianMultipoint *multi_point_tree = static_cast(point_visitor.get_geometry()); ObGeoToTreeVisitor line_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_line.do_visit(line_visitor)); ObCartesianMultilinestring *multi_line_tree = static_cast(line_visitor.get_geometry()); ObGeoToTreeVisitor poly_visitor(&allocator); ASSERT_EQ(OB_SUCCESS, multi_poly.do_visit(poly_visitor)); ObCartesianMultipolygon *multi_poly_tree = static_cast(poly_visitor.get_geometry()); ObCartesianGeometrycollection gc(0, allocator); gc.push_back(*multi_point_tree); gc.push_back(*multi_line_tree); gc.push_back(*multi_poly_tree); ObCartesianMultipoint *res_multi_point = NULL; ObCartesianMultilinestring * res_multi_line = NULL; ObCartesianMultipolygon *res_multi_poly = NULL; int ret = ObGeoFuncUtils::ob_geo_gc_split(allocator, gc, res_multi_point, res_multi_line, res_multi_poly); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(true, is_geo_equal(*res_multi_point, *multi_point_tree)); ASSERT_EQ(true, is_geo_equal(*res_multi_line, *multi_line_tree)); ASSERT_EQ(true, is_geo_equal(*res_multi_poly, *multi_poly_tree)); } } // namespace common } // namespace oceanbase int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }