251 lines
11 KiB
C++
251 lines
11 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
* This file contains implementation for ob_geo_expr_utils.
|
|
*/
|
|
|
|
#ifndef OCEANBASE_SQL_OB_GEO_EXPR_UTILS_H_
|
|
#define OCEANBASE_SQL_OB_GEO_EXPR_UTILS_H_
|
|
|
|
#include "lib/allocator/ob_allocator.h"
|
|
#include "lib/string/ob_string.h"
|
|
#include "lib/geo/ob_geo.h"
|
|
#include "lib/geo/ob_geo_utils.h"
|
|
#include "lib/geo/ob_geo_common.h"
|
|
#include "sql/engine/expr/ob_expr.h" // for ObExpr
|
|
#include "sql/session/ob_sql_session_info.h"
|
|
#include "sql/engine/ob_exec_context.h"
|
|
#include "share/ob_i_sql_expression.h" // for ObExprCtx
|
|
#include "observer/omt/ob_tenant_srs.h"
|
|
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
|
|
namespace common
|
|
{
|
|
class ObCachedGeom;
|
|
}
|
|
namespace sql
|
|
{
|
|
struct ObGeoUnit
|
|
{
|
|
const char *name;
|
|
double factor;
|
|
};
|
|
|
|
const ObGeoUnit OB_GEO_UNITS[] = {
|
|
// order by unit s, asc
|
|
{ "British chain (Benoit 1895 A)", 20.1167824 },
|
|
{ "British chain (Benoit 1895 B)", 20.116782494375872 },
|
|
{ "British chain (Sears 1922 truncated)", 20.116756 },
|
|
{ "British chain (Sears 1922)", 20.116765121552632 },
|
|
{ "British foot (1865)", 0.30480083333333335 },
|
|
{ "British foot (1936)", 0.3048007491 },
|
|
{ "British foot (Benoit 1895 A)", 0.3047997333333333 },
|
|
{ "British foot (Benoit 1895 B)", 0.30479973476327077 },
|
|
{ "British foot (Sears 1922 truncated)", 0.30479933333333337 },
|
|
{ "British foot (Sears 1922)", 0.3047994715386762 },
|
|
{ "British link (Benoit 1895 A)", 0.201167824 },
|
|
{ "British link (Benoit 1895 B)", 0.2011678249437587 },
|
|
{ "British link (Sears 1922 truncated)", 0.20116756 },
|
|
{ "British link (Sears 1922)", 0.2011676512155263 },
|
|
{ "British yard (Benoit 1895 A)", 0.9143992 },
|
|
{ "British yard (Benoit 1895 B)", 0.9143992042898124 },
|
|
{ "British yard (Sears 1922 truncated)", 0.914398 },
|
|
{ "British yard (Sears 1922)", 0.9143984146160288 },
|
|
{ "centimetre", 0.01 },
|
|
{ "chain", 20.1168 },
|
|
{ "Clarke's chain", 20.1166195164 },
|
|
{ "Clarke's foot", 0.3047972654 },
|
|
{ "Clarke's link", 0.201166195164 },
|
|
{ "Clarke's yard", 0.9143917962 },
|
|
{ "cm", 0.01 },
|
|
{ "fathom", 1.8288 },
|
|
{ "foot", 0.3048 },
|
|
{ "German legal metre", 1.0000135965 },
|
|
{ "Gold Coast foot", 0.3047997101815088 },
|
|
{ "Indian foot", 0.30479951024814694 },
|
|
{ "Indian foot (1937)", 0.30479841 },
|
|
{ "Indian foot (1962)", 0.3047996 },
|
|
{ "Indian foot (1975)", 0.3047995 },
|
|
{ "Indian yard", 0.9143985307444408 },
|
|
{ "Indian yard (1937)", 0.91439523 },
|
|
{ "Indian yard (1962)", 0.9143988 },
|
|
{ "Indian yard (1975)", 0.9143985 },
|
|
{ "kilometre", 1000 },
|
|
{ "km", 1000 },
|
|
{ "link", 0.201168 },
|
|
{ "metre", 1 },
|
|
{ "millimetre", 0.001 },
|
|
{ "nautical mile", 1852 },
|
|
{ "Statute mile", 1609.344 },
|
|
{ "US survey chain", 20.11684023368047 },
|
|
{ "US survey foot", 0.30480060960121924 },
|
|
{ "US survey link", 0.2011684023368047 },
|
|
{ "US survey mile", 1609.3472186944375 },
|
|
{ "yard", 0.9144 }
|
|
};
|
|
|
|
class ObGeoConstParamCache;
|
|
enum class ObGeoAxisOrder
|
|
{
|
|
LONG_LAT = 0,
|
|
LAT_LONG = 1,
|
|
SRID_DEFINED = 2,
|
|
INVALID = 3,
|
|
};
|
|
|
|
class ObGeoExprUtils
|
|
{
|
|
public:
|
|
ObGeoExprUtils();
|
|
virtual ~ObGeoExprUtils() = default;
|
|
static int get_srs_item(uint64_t tenant_id,
|
|
omt::ObSrsCacheGuard &srs_guard,
|
|
const uint32_t srid,
|
|
const common::ObSrsItem *&srs);
|
|
static int get_srs_item(ObEvalCtx &ctx,
|
|
omt::ObSrsCacheGuard &srs_guard,
|
|
const common::ObString &wkb,
|
|
const common::ObSrsItem *&srs,
|
|
bool use_little_bo = false,
|
|
const char *func_name = NULL);
|
|
static int build_geometry(common::ObIAllocator &allocator,
|
|
const common::ObString &wkb,
|
|
common::ObGeometry *&geo,
|
|
const common::ObSrsItem *srs,
|
|
const char *func_name,
|
|
uint8_t build_flag = ObGeoBuildFlag::GEO_DEFAULT);
|
|
static int construct_geometry(common::ObIAllocator &allocator,
|
|
const common::ObString &wkb,
|
|
omt::ObSrsCacheGuard &srs_guard,
|
|
const common::ObSrsItem *&srs,
|
|
common::ObGeometry *&geo,
|
|
const char *func_name,
|
|
bool has_srid = true);
|
|
static int check_coordinate_range(const common::ObSrsItem *srs,
|
|
common::ObGeometry *geo,
|
|
const char *func_name,
|
|
const bool is_param = false,
|
|
const bool is_normalized = false);
|
|
static int parse_axis_order(const common::ObString option_str,
|
|
const char *func_name,
|
|
ObGeoAxisOrder &axis_order);
|
|
static int check_need_reverse(ObGeoAxisOrder axis_order,
|
|
bool &need_reverse);
|
|
static int correct_coordinate_range(const common::ObSrsItem *srs_item,
|
|
common::ObGeometry *geo,
|
|
const char *func_name);
|
|
static int check_empty(common::ObGeometry *geo,
|
|
bool &is_empty);
|
|
static int parse_srid(const common::ObString &srid_str,
|
|
uint32_t &srid);
|
|
static int get_box_bestsrid(common::ObGeogBox *geo_box1,
|
|
common::ObGeogBox *geo_box2,
|
|
int32 &bestsrid);
|
|
static int normalize_wkb(const common::ObSrsItem *srs,
|
|
common::ObString &wkb,
|
|
common::ObArenaAllocator &allocator,
|
|
common::ObGeometry *&geo);
|
|
static int normalize_wkb(common::ObString &proj4text,
|
|
common::ObGeometry *geo); // for st_transform
|
|
static int denormalize_wkb(common::ObString &proj4text,
|
|
common::ObGeometry *geo); // for st_transform
|
|
static int geo_to_wkb(common::ObGeometry &geo,
|
|
const ObExpr &expr,
|
|
ObEvalCtx &ctx,
|
|
const common::ObSrsItem *srs_item,
|
|
common::ObString &res_wkb,
|
|
uint32_t srs_id = 0);
|
|
static int geo_to_wkb(common::ObGeometry &geo,
|
|
common::ObExprCtx &expr_ctx,
|
|
const common::ObSrsItem *srs_item,
|
|
common::ObString &res_wkb,
|
|
uint32_t srs_id = 0);
|
|
static int geo_to_2d_wkb(common::ObGeometry &geo,
|
|
const ObExpr &expr,
|
|
ObEvalCtx &ctx,
|
|
const common::ObSrsItem *srs_item,
|
|
common::ObString &res_wkb,
|
|
uint32_t srs_id = 0);
|
|
static int geo_to_3d_wkb(common::ObGeometry &geo,
|
|
const ObExpr &expr,
|
|
ObEvalCtx &ctx,
|
|
const common::ObSrsItem *srs_item,
|
|
common::ObString &res_wkb,
|
|
uint32_t srs_id = 0);
|
|
static void geo_func_error_handle(int ret, const char* func_name);
|
|
static int zoom_in_geos_for_relation(common::ObGeometry &geo1, common::ObGeometry &geo2,
|
|
bool is_geo1_cached = false, bool is_geo2_cached = false);
|
|
|
|
static int pack_geo_res(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res, const ObString &str);
|
|
static int reverse_coordinate(ObGeometry *geo, const char *func_name);
|
|
static int length_unit_conversion(const ObString &unit_str, const ObSrsItem *srs, double in_num, double &out_num);
|
|
static int get_input_geometry(ObIAllocator &allocator, ObDatum *gis_datum, ObEvalCtx &ctx, ObExpr *gis_arg,
|
|
omt::ObSrsCacheGuard &srs_guard, const char *func_name,
|
|
const ObSrsItem *&srs, ObGeometry *&geo);
|
|
static int make_valid_polygon_inner(
|
|
ObCartesianPolygon &poly, ObIAllocator &allocator, ObGeometry *&valid_poly);
|
|
static int union_polygons(
|
|
ObIAllocator &allocator, const ObGeometry &poly, ObGeometry *&polygons_union);
|
|
static int make_valid_polygon(ObGeometry *poly, ObIAllocator &allocator, ObGeometry *&valid_poly);
|
|
static int create_3D_empty_collection(ObIAllocator &allocator, uint32_t srid, bool is_3d, bool is_geog, ObGeometry *&geo);
|
|
static ObGeoConstParamCache* get_geo_constParam_cache(const uint64_t& id, ObExecContext *exec_ctx);
|
|
static void expr_get_const_param_cache(ObGeoConstParamCache* const_param_cache, ObGeometry *&geo, uint32_t& srid, bool& is_geo_cached, int cache_idx);
|
|
static int expr_prepare_build_geometry(ObIAllocator &allocator, const ObDatum &datum, const ObExpr &gis_arg, ObString& wkb, ObGeoType& type, uint32_t& srid);
|
|
static int check_box_intersects(ObGeometry &geo1, ObGeometry &geo2, ObIAllocator &allocator,
|
|
ObGeoConstParamCache* const_param_cache,
|
|
bool is_geo1_cached, bool is_geo2_cached, bool& box_intersects);
|
|
static int get_intersects_res(ObGeometry &geo1, ObGeometry &geo2,
|
|
ObExpr *gis_arg1, ObExpr *gis_arg2,
|
|
ObGeoConstParamCache* const_param_cache,
|
|
const ObSrsItem *srs,
|
|
ObArenaAllocator& temp_allocator, bool& res);
|
|
private:
|
|
static int ob_geo_find_unit(const ObGeoUnit *units, const ObString &name, double &factor);
|
|
static int init_box_by_geo(ObGeometry &geo, ObIAllocator &allocator, ObGeogBox *&box_ptr);
|
|
static void init_boxes_by_cache(ObGeogBox *&box_ptr1, ObGeogBox& box1,
|
|
ObGeogBox *&box_ptr2, ObGeogBox& box2,
|
|
ObGeoConstParamCache* const_param_cache,
|
|
bool is_geo1_cached, bool is_geo2_cached);
|
|
static void init_box_by_cache(ObGeogBox *&box_ptr, ObGeogBox& box, ObCachedGeom* cache);
|
|
};
|
|
|
|
class ObGeoConstParamCache : public ObExprOperatorCtx {
|
|
|
|
public:
|
|
ObGeoConstParamCache(common::ObIAllocator *allocator) :
|
|
ObExprOperatorCtx(),
|
|
allocator_(allocator),
|
|
param1_(nullptr),
|
|
cached_param1_(nullptr),
|
|
param2_(nullptr),
|
|
cached_param2_(nullptr) {}
|
|
~ObGeoConstParamCache();
|
|
|
|
ObGeometry *get_const_param_cache(int arg_idx);
|
|
ObCachedGeom *get_cached_geo(int arg_idx);
|
|
int add_const_param_cache(int arg_idx, const common::ObGeometry &cache);
|
|
void add_cached_geo(int arg_idx, common::ObCachedGeom *cache);
|
|
void set_allocator(common::ObIAllocator *allocator);
|
|
common::ObIAllocator* get_allocator() { return allocator_; }
|
|
|
|
private:
|
|
common::ObIAllocator *allocator_;
|
|
common::ObGeometry * param1_; // ObGeometry * param1_ 与 ObCachedGeom *cached_param1_的区别
|
|
common::ObCachedGeom *cached_param1_;
|
|
common::ObGeometry * param2_;
|
|
common::ObCachedGeom *cached_param2_;
|
|
};
|
|
|
|
} // sql
|
|
} // oceanbase
|
|
#endif // OCEANBASE_SQL_OB_GEO_EXPR_UTILS_H_
|