同步操作将从 nwsuafzq/MySQLAdvisor 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; version 2 of the License.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free Software Foundation,51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */#ifndef _spatial_h#define _spatial_h#include "sql_string.h" /* String, LEX_STRING */#include <my_compiler.h>#ifdef HAVE_SPATIAL#include <algorithm>const uint SRID_SIZE= 4;const uint SIZEOF_STORED_DOUBLE= 8;const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2);const uint WKB_HEADER_SIZE= 1+4;const uint32 GET_SIZE_ERROR= ((uint32) -1);/**Point with coordinates X and Y.*/class point_xy{public:double x;double y;point_xy() { }point_xy(double x_arg, double y_arg): x(x_arg), y(y_arg) { }/**Distance to another point.*/double distance(point_xy p){return sqrt(pow(x - p.x, 2) + pow(y - p.y, 2));}/**Compare to another point.Return true if equal, false if not equal.*/bool eq(point_xy p){return (x == p.x) && (y == p.y);}};typedef struct wkb_header_st{uchar byte_order;uint32 wkb_type;} wkb_header;/***************************** MBR *******************************//*It's ok that a lot of the functions are inline as these are only used oncein MySQL*/struct MBR{double xmin, ymin, xmax, ymax;MBR(){xmin= ymin= DBL_MAX;xmax= ymax= -DBL_MAX;}MBR(const double xmin_arg, const double ymin_arg,const double xmax_arg, const double ymax_arg):xmin(xmin_arg), ymin(ymin_arg), xmax(xmax_arg), ymax(ymax_arg){}MBR(const point_xy &min, const point_xy &max):xmin(min.x), ymin(min.y), xmax(max.x), ymax(max.y){}inline void add_xy(double x, double y){/* Not using "else" for proper one point MBR calculation */if (x < xmin)xmin= x;if (x > xmax)xmax= x;if (y < ymin)ymin= y;if (y > ymax)ymax= y;}void add_xy(point_xy p){add_xy(p.x, p.y);}void add_xy(const char *px, const char *py){double x, y;float8get(x, px);float8get(y, py);add_xy(x,y);}void add_mbr(const MBR *mbr){if (mbr->xmin < xmin)xmin= mbr->xmin;if (mbr->xmax > xmax)xmax= mbr->xmax;if (mbr->ymin < ymin)ymin= mbr->ymin;if (mbr->ymax > ymax)ymax= mbr->ymax;}int equals(const MBR *mbr){/* The following should be safe, even if we compare doubles */return ((mbr->xmin == xmin) && (mbr->ymin == ymin) &&(mbr->xmax == xmax) && (mbr->ymax == ymax));}int disjoint(const MBR *mbr){/* The following should be safe, even if we compare doubles */return ((mbr->xmin > xmax) || (mbr->ymin > ymax) ||(mbr->xmax < xmin) || (mbr->ymax < ymin));}int intersects(const MBR *mbr){return !disjoint(mbr);}int touches(const MBR *mbr){/* The following should be safe, even if we compare doubles */return ((mbr->xmin == xmax || mbr->xmax == xmin) &&((mbr->ymin >= ymin && mbr->ymin <= ymax) ||(mbr->ymax >= ymin && mbr->ymax <= ymax))) ||((mbr->ymin == ymax || mbr->ymax == ymin) &&((mbr->xmin >= xmin && mbr->xmin <= xmax) ||(mbr->xmax >= xmin && mbr->xmax <= xmax)));}int within(const MBR *mbr){/* The following should be safe, even if we compare doubles */return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) &&(mbr->xmax >= xmax) && (mbr->ymax >= ymax));}int contains(const MBR *mbr){/* The following should be safe, even if we compare doubles */return ((mbr->xmin >= xmin) && (mbr->ymin >= ymin) &&(mbr->xmax <= xmax) && (mbr->ymax <= ymax));}bool inner_point(double x, double y) const{/* The following should be safe, even if we compare doubles */return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>y);}/**The dimension maps to an integer as:- Polygon -> 2- Horizontal or vertical line -> 1- Point -> 0- Invalid MBR -> -1*/int dimension() const{int d= 0;if (xmin > xmax)return -1;else if (xmin < xmax)d++;if (ymin > ymax)return -1;else if (ymin < ymax)d++;return d;}int overlaps(const MBR *mbr){/*overlaps() requires that some point inside *this is also inside*mbr, and that both geometries and their intersection are of thesame dimension.*/int d = dimension();if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))return 0;using std::min;using std::max;MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),min(xmax, mbr->xmax), min(ymax, mbr->ymax));return (d == intersection.dimension());}};/***************************** Geometry *******************************/struct Geometry_buffer;class Geometry{public:Geometry() {} /* Remove gcc warning */virtual ~Geometry() {} /* Remove gcc warning */static void *operator new(size_t size, void *buffer){return buffer;}static void operator delete(void *ptr, void *buffer){}static void operator delete(void *buffer){}static String bad_geometry_data;enum wkbType{wkb_point= 1,wkb_linestring= 2,wkb_polygon= 3,wkb_multipoint= 4,wkb_multilinestring= 5,wkb_multipolygon= 6,wkb_geometrycollection= 7,wkb_last=7};enum wkbByteOrder{wkb_xdr= 0, /* Big Endian */wkb_ndr= 1 /* Little Endian */};/**Constant storage for WKB.Encapsulation and the available methods make it impossibleto update the members of wkb_container once it is initialized.The only allowed modification method is set(),which fully replaces the previous buffer.*/class wkb_container{protected:const char *m_data;const char *m_data_end;public:wkb_container() { }wkb_container(const char *data, const char *data_end){set(data, data_end);}void set(const char *data, const char *data_end){m_data= data;m_data_end= data_end;}const char *data() const{return m_data;}const char *data_end() const{return m_data_end;}uint32 length() const{return (uint32) (m_data_end - m_data);}/**Check if there's enough data remaining as requested.@arg data_amount data requested@return true if not enough data*/inline bool no_data(size_t data_amount) const{return (m_data + data_amount > m_data_end);}/**Check if there're enough points remaining as requested.Need to perform the calculation in logical units, since multiplicationcan overflow the size data type.@arg expected_points number of points expected@arg extra_point_space extra space for each point element in the array@return true if there are not enough points*/inline bool not_enough_points(uint32 expected_points,uint32 extra_point_space= 0) const{return (m_data_end < m_data ||expected_points > ((m_data_end - m_data) /(POINT_DATA_SIZE + extra_point_space)));}};/**WKB parser, designed to traverse through WKB data frombeginning of the buffer towards the end using a setof scan_xxx(), get_xxx() and skip_xxx() routines,with safety tests to avoid going beyond the buffer end.*/class wkb_parser: public wkb_container{/* Low level routines to get data of various types */void get_uint4(uint32 *number){*number= uint4korr(m_data); //GIS-TODO: byte order}void get_float8(double *x){float8get(*x, m_data); //GIS-TODO: byte order}public:wkb_parser(const char *data, const char *data_end):wkb_container(data, data_end) { }wkb_parser(const wkb_container *container):wkb_container(*container) { }/* Routines to skip non-interesting data */void skip_unsafe(size_t nbytes){DBUG_ASSERT(!no_data(nbytes));m_data+= nbytes;}bool skip(size_t nbytes){if (no_data(nbytes))return true;m_data+= nbytes;return false;}bool skip_wkb_header(){return skip(WKB_HEADER_SIZE);}bool skip_coord(){return skip(SIZEOF_STORED_DOUBLE);}/* Routines to scan wkb header information */bool scan_wkb_header(wkb_header *header){if (no_data(WKB_HEADER_SIZE))return true;header->byte_order= (uchar) (*m_data);m_data++;get_uint4(&header->wkb_type);m_data+= 4;return false;}/* Routines to scan uint4 information */bool scan_uint4(uint32 *number){if (no_data(4))return true;get_uint4(number);m_data+= 4;return false;}bool scan_non_zero_uint4(uint32 *number){return (scan_uint4(number) || 0 == *number);}bool scan_n_points_and_check_data(uint32 *n_points,uint32 extra_point_space= 0){return scan_non_zero_uint4(n_points) ||not_enough_points(*n_points, extra_point_space);}/* Routines to scan coordinate information */void scan_xy_unsafe(point_xy *p){DBUG_ASSERT(!no_data(POINT_DATA_SIZE));get_float8(&p->x);m_data+= SIZEOF_STORED_DOUBLE;get_float8(&p->y);m_data+= SIZEOF_STORED_DOUBLE;}bool scan_xy(point_xy *p){if (no_data(SIZEOF_STORED_DOUBLE * 2))return true;scan_xy_unsafe(p);return false;}bool scan_coord(double *x){if (no_data(SIZEOF_STORED_DOUBLE))return true;get_float8(x);m_data+= SIZEOF_STORED_DOUBLE;return false;}};/** Callback which creates Geometry objects on top of a given placement. */typedef Geometry *(*create_geom_t)(char *);class Class_info{public:LEX_STRING m_name;int m_type_id;create_geom_t m_create_func;Class_info(const char *name, int type_id, create_geom_t create_func);};virtual const Class_info *get_class_info() const=0;virtual uint32 get_data_size() const=0;virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0;/* returns the length of the wkb that was read */virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,String *res)=0;virtual uint init_from_opresult(String *bin,const char *opres, uint opres_length){ return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; }virtual bool get_data_as_wkt(String *txt, wkb_parser *wkb) const=0;virtual bool get_mbr(MBR *mbr, wkb_parser *wkb) const=0;bool get_mbr(MBR *mbr){wkb_parser wkb(&m_wkb_data);return get_mbr(mbr, &wkb);}virtual bool dimension(uint32 *dim, wkb_parser *wkb) const{*dim= feature_dimension();uint32 length;if ((length= get_data_size()) == GET_SIZE_ERROR)return true;wkb->skip(length);return false;}bool dimension(uint32 *dim){wkb_parser wkb(&m_wkb_data);return dimension(dim, &wkb);}virtual uint32 feature_dimension() const= 0;virtual int get_x(double *x) const { return -1; }virtual int get_y(double *y) const { return -1; }virtual int geom_length(double *len) const { return -1; }/**Calculate area of a Geometry.This default implementation returns 0 for the types that have zero area:Point, LineString, MultiPoint, MultiLineString.The over geometry types (Polygon, MultiPolygon, GeometryCollection)override the default method.*/virtual bool area(double *ar, wkb_parser *wkb) const{uint32 data_size= get_data_size();if (data_size == GET_SIZE_ERROR || wkb->no_data(data_size))return true;wkb->skip_unsafe(data_size);*ar= 0;return false;}bool area(double *ar) const{wkb_parser wkb(&m_wkb_data);return area(ar, &wkb);}virtual int is_closed(int *closed) const { return -1; }virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; }virtual int num_points(uint32 *n_points) const { return -1; }virtual int num_geometries(uint32 *num) const { return -1; }virtual int start_point(String *point) const { return -1; }virtual int end_point(String *point) const { return -1; }virtual int exterior_ring(String *ring) const { return -1; }virtual int centroid(String *point) const { return -1; }virtual int point_n(uint32 num, String *result) const { return -1; }virtual int interior_ring_n(uint32 num, String *result) const { return -1; }virtual int geometry_n(uint32 num, String *result) const { return -1; }public:static Geometry *construct(Geometry_buffer *buffer,const char *data, uint32 data_len);static Geometry *construct(Geometry_buffer *buffer, const String *str){return construct(buffer, str->ptr(), str->length());}bool as_wkt(String *wkt, wkb_parser *wkb){uint32 len= (uint) get_class_info()->m_name.length;if (wkt->reserve(len + 2, 512))return true;wkt->qs_append(get_class_info()->m_name.str, len);wkt->qs_append('(');if (get_data_as_wkt(wkt, wkb))return true;wkt->qs_append(')');return false;}bool as_wkt(String *wkt){wkb_parser wkb(&m_wkb_data);return as_wkt(wkt, &wkb);}inline void set_data_ptr(const char *data, uint32 data_len){m_wkb_data.set(data, data + data_len);}inline void set_data_ptr(const wkb_container *wkb){m_wkb_data= *wkb;}bool envelope(String *result) const;static Class_info *ci_collection[wkb_last+1];protected:static Class_info *find_class(int type_id){return ((type_id < wkb_point) || (type_id > wkb_last)) ?NULL : ci_collection[type_id];}static Class_info *find_class(const char *name, uint32 len);void append_points(String *txt, uint32 n_points,wkb_parser *wkb, uint32 offset) const;bool create_point(String *result, wkb_parser *wkb) const;bool create_point(String *result, point_xy p) const;bool get_mbr_for_points(MBR *mbr, wkb_parser *wkb, uint offset) const;wkb_container m_wkb_data;};/***************************** Point *******************************/class Gis_point: public Geometry{public:Gis_point() {} /* Remove gcc warning */virtual ~Gis_point() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;int get_xy(point_xy *p) const{wkb_parser wkb(&m_wkb_data);return wkb.scan_xy(p);}int get_x(double *x) const{wkb_parser wkb(&m_wkb_data);return wkb.scan_coord(x);}int get_y(double *y) const{wkb_parser wkb(&m_wkb_data);return wkb.skip_coord() || wkb.scan_coord(y);}uint32 feature_dimension() const { return 0; }const Class_info *get_class_info() const;};/***************************** LineString *******************************/class Gis_line_string: public Geometry{// Maximum number of points in LineString that can fit into Stringstatic const uint32 max_n_points=(uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /POINT_DATA_SIZE;public:Gis_line_string() {} /* Remove gcc warning */virtual ~Gis_line_string() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;int geom_length(double *len) const;int is_closed(int *closed) const;int num_points(uint32 *n_points) const;int start_point(String *point) const;int end_point(String *point) const;int point_n(uint32 n, String *result) const;uint32 feature_dimension() const { return 1; }const Class_info *get_class_info() const;};/***************************** Polygon *******************************/class Gis_polygon: public Geometry{public:Gis_polygon() {} /* Remove gcc warning */virtual ~Gis_polygon() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);uint init_from_opresult(String *bin, const char *opres, uint opres_length);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;bool area(double *ar, wkb_parser *wkb) const;int exterior_ring(String *result) const;int num_interior_ring(uint32 *n_int_rings) const;int interior_ring_n(uint32 num, String *result) const;bool centroid_xy(point_xy *p) const;int centroid(String *result) const;uint32 feature_dimension() const { return 2; }const Class_info *get_class_info() const;};/***************************** MultiPoint *******************************/class Gis_multi_point: public Geometry{// Maximum number of points in MultiPoint that can fit into Stringstatic const uint32 max_n_points=(uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /(WKB_HEADER_SIZE + POINT_DATA_SIZE);public:Gis_multi_point() {} /* Remove gcc warning */virtual ~Gis_multi_point() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);uint init_from_opresult(String *bin, const char *opres, uint opres_length);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;int num_geometries(uint32 *num) const;int geometry_n(uint32 num, String *result) const;uint32 feature_dimension() const { return 0; }const Class_info *get_class_info() const;};/***************************** MultiLineString *******************************/class Gis_multi_line_string: public Geometry{public:Gis_multi_line_string() {} /* Remove gcc warning */virtual ~Gis_multi_line_string() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);uint init_from_opresult(String *bin, const char *opres, uint opres_length);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;int num_geometries(uint32 *num) const;int geometry_n(uint32 num, String *result) const;int geom_length(double *len) const;int is_closed(int *closed) const;uint32 feature_dimension() const { return 1; }const Class_info *get_class_info() const;};/***************************** MultiPolygon *******************************/class Gis_multi_polygon: public Geometry{public:Gis_multi_polygon() {} /* Remove gcc warning */virtual ~Gis_multi_polygon() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;int num_geometries(uint32 *num) const;int geometry_n(uint32 num, String *result) const;bool area(double *ar, wkb_parser *wkb) const;int centroid(String *result) const;uint32 feature_dimension() const { return 2; }const Class_info *get_class_info() const;uint init_from_opresult(String *bin, const char *opres, uint opres_length);};/*********************** GeometryCollection *******************************/class Gis_geometry_collection: public Geometry{public:Gis_geometry_collection() {} /* Remove gcc warning */virtual ~Gis_geometry_collection() {} /* Remove gcc warning */uint32 get_data_size() const;bool init_from_wkt(Gis_read_stream *trs, String *wkb);uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);uint init_from_opresult(String *bin, const char *opres, uint opres_length);bool get_data_as_wkt(String *txt, wkb_parser *wkb) const;bool get_mbr(MBR *mbr, wkb_parser *wkb) const;bool area(double *ar, wkb_parser *wkb) const;int num_geometries(uint32 *num) const;int geometry_n(uint32 num, String *result) const;bool dimension(uint32 *dim, wkb_parser *wkb) const;uint32 feature_dimension() const{DBUG_ASSERT(0);return 0;}const Class_info *get_class_info() const;};struct Geometry_buffer : publicmy_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {};#endif /*HAVE_SPATAIAL*/#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。