spatial.h | spatial.h | |||
---|---|---|---|---|
/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reser ved. | /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reser ved. | |||
This program is free software; you can redistribute it and/or modify | This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; version 2 of the License. | the Free Software Foundation; version 2 of the License. | |||
This program is distributed in the hope that it will be useful, | This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | GNU General Public License for more details. | |||
skipping to change at line 30 | skipping to change at line 30 | |||
#include <my_compiler.h> | #include <my_compiler.h> | |||
#ifdef HAVE_SPATIAL | #ifdef HAVE_SPATIAL | |||
#include "gcalc_tools.h" | #include "gcalc_tools.h" | |||
#include <algorithm> | #include <algorithm> | |||
const uint SRID_SIZE= 4; | const uint SRID_SIZE= 4; | |||
const uint SIZEOF_STORED_DOUBLE= 8; | const uint SIZEOF_STORED_DOUBLE= 8; | |||
const uint POINT_DATA_SIZE= SIZEOF_STORED_DOUBLE*2; | const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2); | |||
const uint WKB_HEADER_SIZE= 1+4; | const uint WKB_HEADER_SIZE= 1+4; | |||
const uint32 GET_SIZE_ERROR= ((uint32) -1); | const uint32 GET_SIZE_ERROR= ((uint32) -1); | |||
struct st_point_2d | /** | |||
Point with coordinates X and Y. | ||||
*/ | ||||
class point_xy | ||||
{ | { | |||
public: | ||||
double x; | double x; | |||
double y; | 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); | ||||
} | ||||
}; | }; | |||
struct st_linear_ring | typedef struct wkb_header_st | |||
{ | { | |||
uint32 n_points; | uchar byte_order; | |||
st_point_2d points; | uint32 wkb_type; | |||
}; | } wkb_header; | |||
/***************************** MBR *******************************/ | /***************************** MBR *******************************/ | |||
/* | /* | |||
It's ok that a lot of the functions are inline as these are only used onc e | It's ok that a lot of the functions are inline as these are only used onc e | |||
in MySQL | in MySQL | |||
*/ | */ | |||
struct MBR | struct MBR | |||
{ | { | |||
skipping to change at line 68 | skipping to change at line 89 | |||
{ | { | |||
xmin= ymin= DBL_MAX; | xmin= ymin= DBL_MAX; | |||
xmax= ymax= -DBL_MAX; | xmax= ymax= -DBL_MAX; | |||
} | } | |||
MBR(const double xmin_arg, const double ymin_arg, | MBR(const double xmin_arg, const double ymin_arg, | |||
const double xmax_arg, const double ymax_arg) | const double xmax_arg, const double ymax_arg) | |||
:xmin(xmin_arg), ymin(ymin_arg), xmax(xmax_arg), ymax(ymax_arg) | :xmin(xmin_arg), ymin(ymin_arg), xmax(xmax_arg), ymax(ymax_arg) | |||
{} | {} | |||
MBR(const st_point_2d &min, const st_point_2d &max) | MBR(const point_xy &min, const point_xy &max) | |||
:xmin(min.x), ymin(min.y), xmax(max.x), ymax(max.y) | :xmin(min.x), ymin(min.y), xmax(max.x), ymax(max.y) | |||
{} | {} | |||
inline void add_xy(double x, double y) | inline void add_xy(double x, double y) | |||
{ | { | |||
/* Not using "else" for proper one point MBR calculation */ | /* Not using "else" for proper one point MBR calculation */ | |||
if (x < xmin) | if (x < xmin) | |||
xmin= x; | xmin= x; | |||
if (x > xmax) | if (x > xmax) | |||
xmax= x; | xmax= x; | |||
if (y < ymin) | if (y < ymin) | |||
ymin= y; | ymin= y; | |||
if (y > ymax) | if (y > ymax) | |||
ymax= y; | ymax= y; | |||
} | } | |||
void add_xy(point_xy p) | ||||
{ | ||||
add_xy(p.x, p.y); | ||||
} | ||||
void add_xy(const char *px, const char *py) | void add_xy(const char *px, const char *py) | |||
{ | { | |||
double x, y; | double x, y; | |||
float8get(x, px); | float8get(x, px); | |||
float8get(y, py); | float8get(y, py); | |||
add_xy(x,y); | add_xy(x,y); | |||
} | } | |||
void add_mbr(const MBR *mbr) | void add_mbr(const MBR *mbr) | |||
{ | { | |||
if (mbr->xmin < xmin) | if (mbr->xmin < xmin) | |||
skipping to change at line 237 | skipping to change at line 262 | |||
wkb_multipolygon= 6, | wkb_multipolygon= 6, | |||
wkb_geometrycollection= 7, | wkb_geometrycollection= 7, | |||
wkb_last=7 | wkb_last=7 | |||
}; | }; | |||
enum wkbByteOrder | enum wkbByteOrder | |||
{ | { | |||
wkb_xdr= 0, /* Big Endian */ | wkb_xdr= 0, /* Big Endian */ | |||
wkb_ndr= 1 /* Little Endian */ | wkb_ndr= 1 /* Little Endian */ | |||
}; | }; | |||
/** | ||||
Constant storage for WKB. | ||||
Encapsulation and the available methods make it impossible | ||||
to 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 multiplicatio | ||||
n | ||||
can overflow the size data type. | ||||
@arg expected_points number of points expected | ||||
@arg extra_point_space extra space for each point element in the arra | ||||
y | ||||
@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 from | ||||
beginning of the buffer towards the end using a set | ||||
of 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. */ | /** Callback which creates Geometry objects on top of a given placement. */ | |||
typedef Geometry *(*create_geom_t)(char *); | typedef Geometry *(*create_geom_t)(char *); | |||
class Class_info | class Class_info | |||
{ | { | |||
public: | public: | |||
LEX_STRING m_name; | LEX_STRING m_name; | |||
int m_type_id; | int m_type_id; | |||
create_geom_t m_create_func; | create_geom_t m_create_func; | |||
Class_info(const char *name, int type_id, create_geom_t create_func); | Class_info(const char *name, int type_id, create_geom_t create_func); | |||
skipping to change at line 259 | skipping to change at line 454 | |||
virtual const Class_info *get_class_info() const=0; | virtual const Class_info *get_class_info() const=0; | |||
virtual uint32 get_data_size() const=0; | virtual uint32 get_data_size() const=0; | |||
virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0; | virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0; | |||
/* returns the length of the wkb that was read */ | /* returns the length of the wkb that was read */ | |||
virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, | virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, | |||
String *res)=0; | String *res)=0; | |||
virtual uint init_from_opresult(String *bin, | virtual uint init_from_opresult(String *bin, | |||
const char *opres, uint opres_length) | const char *opres, uint opres_length) | |||
{ return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; } | { return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; } | |||
virtual bool get_data_as_wkt(String *txt, const char **end) const=0; | virtual bool get_data_as_wkt(String *txt, wkb_parser *wkb) const=0; | |||
virtual bool get_mbr(MBR *mbr, const char **end) const=0; | virtual bool get_mbr(MBR *mbr, wkb_parser *wkb) const=0; | |||
virtual bool dimension(uint32 *dim, const char **end) 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_x(double *x) const { return -1; } | |||
virtual int get_y(double *y) const { return -1; } | virtual int get_y(double *y) const { return -1; } | |||
virtual int geom_length(double *len) const { return -1; } | virtual int geom_length(double *len) const { return -1; } | |||
/** | /** | |||
Calculate area of a Geometry. | Calculate area of a Geometry. | |||
This default implementation returns 0 for the types that have zero area : | This default implementation returns 0 for the types that have zero area : | |||
Point, LineString, MultiPoint, MultiLineString. | Point, LineString, MultiPoint, MultiLineString. | |||
The over geometry types (Polygon, MultiPolygon, GeometryCollection) | The over geometry types (Polygon, MultiPolygon, GeometryCollection) | |||
override the default method. | override the default method. | |||
*/ | */ | |||
virtual int area(double *ar, const char **end_of_data) const | virtual bool area(double *ar, wkb_parser *wkb) const | |||
{ | { | |||
uint32 data_size= get_data_size(); | uint32 data_size= get_data_size(); | |||
if (data_size == GET_SIZE_ERROR || no_data(m_data, data_size)) | if (data_size == GET_SIZE_ERROR || wkb->no_data(data_size)) | |||
return 1; | return true; | |||
*end_of_data= m_data + data_size; | wkb->skip_unsafe(data_size); | |||
*ar= 0; | *ar= 0; | |||
return 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 is_closed(int *closed) const { return -1; } | |||
virtual int num_interior_ring(uint32 *n_int_rings) 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_points(uint32 *n_points) const { return -1; } | |||
virtual int num_geometries(uint32 *num) const { return -1; } | virtual int num_geometries(uint32 *num) const { return -1; } | |||
virtual int start_point(String *point) const { return -1; } | virtual int start_point(String *point) const { return -1; } | |||
virtual int end_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 exterior_ring(String *ring) const { return -1; } | |||
virtual int centroid(String *point) const { return -1; } | virtual int centroid(String *point) const { return -1; } | |||
virtual int point_n(uint32 num, String *result) const { return -1; } | virtual int point_n(uint32 num, String *result) const { return -1; } | |||
skipping to change at line 302 | skipping to change at line 521 | |||
virtual int store_shapes(Gcalc_shape_transporter *trn, | virtual int store_shapes(Gcalc_shape_transporter *trn, | |||
Gcalc_shape_status *st) const=0; | Gcalc_shape_status *st) const=0; | |||
int store_shapes(Gcalc_shape_transporter *trn) const | int store_shapes(Gcalc_shape_transporter *trn) const | |||
{ | { | |||
Gcalc_shape_status dummy; | Gcalc_shape_status dummy; | |||
return store_shapes(trn, &dummy); | return store_shapes(trn, &dummy); | |||
} | } | |||
public: | public: | |||
static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); | static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); | |||
static Geometry *scan_header_and_create(wkb_parser *wkb, Geometry_buffer | ||||
*buffer) | ||||
{ | ||||
Geometry *geom; | ||||
wkb_header header; | ||||
if (wkb->scan_wkb_header(&header) || | ||||
!(geom= create_by_typeid(buffer, header.wkb_type))) | ||||
return NULL; | ||||
geom->set_data_ptr(wkb); | ||||
return geom; | ||||
} | ||||
static Geometry *construct(Geometry_buffer *buffer, | static Geometry *construct(Geometry_buffer *buffer, | |||
const char *data, uint32 data_len); | const char *data, uint32 data_len); | |||
static Geometry *construct(Geometry_buffer *buffer, const String *str) | ||||
{ | ||||
return construct(buffer, str->ptr(), str->length()); | ||||
} | ||||
static Geometry *create_from_wkt(Geometry_buffer *buffer, | static Geometry *create_from_wkt(Geometry_buffer *buffer, | |||
Gis_read_stream *trs, String *wkt, | Gis_read_stream *trs, String *wkt, | |||
bool init_stream=1); | bool init_stream=1); | |||
static Geometry *create_from_wkb(Geometry_buffer *buffer, | static Geometry *create_from_wkb(Geometry_buffer *buffer, | |||
const char *wkb, uint32 len, String *res ); | const char *wkb, uint32 len, String *res ); | |||
static int create_from_opresult(Geometry_buffer *g_buf, | static int create_from_opresult(Geometry_buffer *g_buf, | |||
String *res, Gcalc_result_receiver &rr); | String *res, Gcalc_result_receiver &rr); | |||
int as_wkt(String *wkt, const char **end) | bool as_wkt(String *wkt, wkb_parser *wkb) | |||
{ | { | |||
uint32 len= (uint) get_class_info()->m_name.length; | uint32 len= (uint) get_class_info()->m_name.length; | |||
if (wkt->reserve(len + 2, 512)) | if (wkt->reserve(len + 2, 512)) | |||
return 1; | return true; | |||
wkt->qs_append(get_class_info()->m_name.str, len); | wkt->qs_append(get_class_info()->m_name.str, len); | |||
wkt->qs_append('('); | wkt->qs_append('('); | |||
if (get_data_as_wkt(wkt, end)) | if (get_data_as_wkt(wkt, wkb)) | |||
return 1; | return true; | |||
wkt->qs_append(')'); | wkt->qs_append(')'); | |||
return 0; | 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) | inline void set_data_ptr(const char *data, uint32 data_len) | |||
{ | { | |||
m_data= data; | m_wkb_data.set(data, data + data_len); | |||
m_data_end= data + data_len; | ||||
} | } | |||
inline void shift_wkb_header() | inline void set_data_ptr(const wkb_container *wkb) | |||
{ | { | |||
m_data+= WKB_HEADER_SIZE; | m_wkb_data= *wkb; | |||
} | } | |||
bool envelope(String *result) const; | bool envelope(String *result) const; | |||
static Class_info *ci_collection[wkb_last+1]; | static Class_info *ci_collection[wkb_last+1]; | |||
protected: | protected: | |||
static Class_info *find_class(int type_id) | static Class_info *find_class(int type_id) | |||
{ | { | |||
return ((type_id < wkb_point) || (type_id > wkb_last)) ? | return ((type_id < wkb_point) || (type_id > wkb_last)) ? | |||
NULL : ci_collection[type_id]; | NULL : ci_collection[type_id]; | |||
} | } | |||
static Class_info *find_class(const char *name, uint32 len); | static Class_info *find_class(const char *name, uint32 len); | |||
const char *append_points(String *txt, uint32 n_points, | void append_points(String *txt, uint32 n_points, | |||
const char *data, uint32 offset) const; | wkb_parser *wkb, uint32 offset) const; | |||
bool create_point(String *result, const char *data) const; | bool create_point(String *result, wkb_parser *wkb) const; | |||
bool create_point(String *result, double x, double y) const; | bool create_point(String *result, point_xy p) const; | |||
const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset) | bool get_mbr_for_points(MBR *mbr, wkb_parser *wkb, uint offset) const; | |||
const; | wkb_container m_wkb_data; | |||
inline bool no_data(const char *cur_data, uint32 data_amount) const | ||||
{ | ||||
return (cur_data + data_amount > m_data_end); | ||||
} | ||||
const char *m_data; | ||||
const char *m_data_end; | ||||
/** | /** | |||
Store shapes of a collection: | Store shapes of a collection: | |||
GeometryCollection, MultiPoint, MultiLineString or MultiPolygon. | GeometryCollection, MultiPoint, MultiLineString or MultiPolygon. | |||
In case when collection is GeometryCollection, NULL should be passed as | In case when collection is GeometryCollection, NULL should be passed as | |||
"collection_item" argument. Proper collection item objects will be | "collection_item" argument. Proper collection item objects will be | |||
created inside collection_store_shapes, according to the geometry type of | created inside collection_store_shapes, according to the geometry type of | |||
every item in the collection. | every item in the collection. | |||
For MultiPoint, MultiLineString or MultiPolygon, an address of a | For MultiPoint, MultiLineString or MultiPolygon, an address of a | |||
skipping to change at line 382 | skipping to change at line 613 | |||
int collection_store_shapes(Gcalc_shape_transporter *trn, | int collection_store_shapes(Gcalc_shape_transporter *trn, | |||
Gcalc_shape_status *st, | Gcalc_shape_status *st, | |||
Geometry *collection_item) const; | Geometry *collection_item) const; | |||
/** | /** | |||
Calculate area of a collection: | Calculate area of a collection: | |||
GeometryCollection, MultiPoint, MultiLineString or MultiPolygon. | GeometryCollection, MultiPoint, MultiLineString or MultiPolygon. | |||
The meaning of the "collection_item" is the same to | The meaning of the "collection_item" is the same to | |||
the similar argument in collection_store_shapes(). | the similar argument in collection_store_shapes(). | |||
*/ | */ | |||
int collection_area(double *ar, const char **end_of_data, Geometry *it) c onst; | bool collection_area(double *ar, wkb_parser *wkb, Geometry *it) const; | |||
/** | /** | |||
Initialize a collection from an operation result. | Initialize a collection from an operation result. | |||
Share between: GeometryCollection, MultiLineString, MultiPolygon. | Share between: GeometryCollection, MultiLineString, MultiPolygon. | |||
The meaning of the "collection_item" is the same to | The meaning of the "collection_item" is the same to | |||
the similare agument in collection_store_shapes(). | the similare agument in collection_store_shapes(). | |||
*/ | */ | |||
uint collection_init_from_opresult(String *bin, | uint collection_init_from_opresult(String *bin, | |||
const char *opres, uint opres_length, | const char *opres, uint opres_length, | |||
Geometry *collection_item); | Geometry *collection_item); | |||
skipping to change at line 406 | skipping to change at line 637 | |||
/***************************** Point *******************************/ | /***************************** Point *******************************/ | |||
class Gis_point: public Geometry | class Gis_point: public Geometry | |||
{ | { | |||
public: | public: | |||
Gis_point() {} /* Remove gcc warning */ | Gis_point() {} /* Remove gcc warning */ | |||
virtual ~Gis_point() {} /* Remove gcc warning */ | virtual ~Gis_point() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int get_xy(double *x, double *y) const | int get_xy(point_xy *p) const | |||
{ | { | |||
const char *data= m_data; | wkb_parser wkb(&m_wkb_data); | |||
if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) | return wkb.scan_xy(p); | |||
return 1; | ||||
float8get(*x, data); | ||||
float8get(*y, data + SIZEOF_STORED_DOUBLE); | ||||
return 0; | ||||
} | } | |||
int get_x(double *x) const | int get_x(double *x) const | |||
{ | { | |||
if (no_data(m_data, SIZEOF_STORED_DOUBLE)) | wkb_parser wkb(&m_wkb_data); | |||
return 1; | return wkb.scan_coord(x); | |||
float8get(*x, m_data); | ||||
return 0; | ||||
} | } | |||
int get_y(double *y) const | int get_y(double *y) const | |||
{ | { | |||
const char *data= m_data; | wkb_parser wkb(&m_wkb_data); | |||
if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1; | return wkb.skip_coord() || wkb.scan_coord(y); | |||
float8get(*y, data + SIZEOF_STORED_DOUBLE); | ||||
return 0; | ||||
} | ||||
bool dimension(uint32 *dim, const char **end) const | ||||
{ | ||||
*dim= 0; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | } | |||
uint32 feature_dimension() const { return 0; } | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
/***************************** LineString *******************************/ | /***************************** LineString *******************************/ | |||
class Gis_line_string: public Geometry | class Gis_line_string: public Geometry | |||
{ | { | |||
// Maximum number of points in LineString that can fit into String | // Maximum number of points in LineString that can fit into String | |||
static const uint32 max_n_points= | static const uint32 max_n_points= | |||
(uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | |||
POINT_DATA_SIZE; | POINT_DATA_SIZE; | |||
public: | public: | |||
Gis_line_string() {} /* Remove gcc warning */ | Gis_line_string() {} /* Remove gcc warning */ | |||
virtual ~Gis_line_string() {} /* Remove gcc warning */ | virtual ~Gis_line_string() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int geom_length(double *len) const; | int geom_length(double *len) const; | |||
int is_closed(int *closed) const; | int is_closed(int *closed) const; | |||
int num_points(uint32 *n_points) const; | int num_points(uint32 *n_points) const; | |||
int start_point(String *point) const; | int start_point(String *point) const; | |||
int end_point(String *point) const; | int end_point(String *point) const; | |||
int point_n(uint32 n, String *result) const; | int point_n(uint32 n, String *result) const; | |||
bool dimension(uint32 *dim, const char **end) const | uint32 feature_dimension() const { return 1; } | |||
{ | ||||
*dim= 1; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
/***************************** Polygon *******************************/ | /***************************** Polygon *******************************/ | |||
class Gis_polygon: public Geometry | class Gis_polygon: public Geometry | |||
{ | { | |||
public: | public: | |||
Gis_polygon() {} /* Remove gcc warning */ | Gis_polygon() {} /* Remove gcc warning */ | |||
virtual ~Gis_polygon() {} /* Remove gcc warning */ | virtual ~Gis_polygon() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int area(double *ar, const char **end) const; | bool area(double *ar, wkb_parser *wkb) const; | |||
int exterior_ring(String *result) const; | int exterior_ring(String *result) const; | |||
int num_interior_ring(uint32 *n_int_rings) const; | int num_interior_ring(uint32 *n_int_rings) const; | |||
int interior_ring_n(uint32 num, String *result) const; | int interior_ring_n(uint32 num, String *result) const; | |||
int centroid_xy(double *x, double *y) const; | bool centroid_xy(point_xy *p) const; | |||
int centroid(String *result) const; | int centroid(String *result) const; | |||
bool dimension(uint32 *dim, const char **end) const | uint32 feature_dimension() const { return 2; } | |||
{ | ||||
*dim= 2; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
/***************************** MultiPoint *******************************/ | /***************************** MultiPoint *******************************/ | |||
class Gis_multi_point: public Geometry | class Gis_multi_point: public Geometry | |||
{ | { | |||
// Maximum number of points in MultiPoint that can fit into String | // Maximum number of points in MultiPoint that can fit into String | |||
static const uint32 max_n_points= | static const uint32 max_n_points= | |||
(uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | |||
(WKB_HEADER_SIZE + POINT_DATA_SIZE); | (WKB_HEADER_SIZE + POINT_DATA_SIZE); | |||
public: | public: | |||
Gis_multi_point() {} /* Remove gcc warning */ | Gis_multi_point() {} /* Remove gcc warning */ | |||
virtual ~Gis_multi_point() {} /* Remove gcc warning */ | virtual ~Gis_multi_point() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int num_geometries(uint32 *num) const; | int num_geometries(uint32 *num) const; | |||
int geometry_n(uint32 num, String *result) const; | int geometry_n(uint32 num, String *result) const; | |||
bool dimension(uint32 *dim, const char **end) const | uint32 feature_dimension() const { return 0; } | |||
{ | ||||
*dim= 0; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
/***************************** MultiLineString **************************** ***/ | /***************************** MultiLineString **************************** ***/ | |||
class Gis_multi_line_string: public Geometry | class Gis_multi_line_string: public Geometry | |||
{ | { | |||
public: | public: | |||
Gis_multi_line_string() {} /* Remove gcc warning */ | Gis_multi_line_string() {} /* Remove gcc warning */ | |||
virtual ~Gis_multi_line_string() {} /* Remove gcc warning */ | virtual ~Gis_multi_line_string() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int num_geometries(uint32 *num) const; | int num_geometries(uint32 *num) const; | |||
int geometry_n(uint32 num, String *result) const; | int geometry_n(uint32 num, String *result) const; | |||
int geom_length(double *len) const; | int geom_length(double *len) const; | |||
int is_closed(int *closed) const; | int is_closed(int *closed) const; | |||
bool dimension(uint32 *dim, const char **end) const | uint32 feature_dimension() const { return 1; } | |||
{ | ||||
*dim= 1; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
/***************************** MultiPolygon ******************************* / | /***************************** MultiPolygon ******************************* / | |||
class Gis_multi_polygon: public Geometry | class Gis_multi_polygon: public Geometry | |||
{ | { | |||
public: | public: | |||
Gis_multi_polygon() {} /* Remove gcc warning */ | Gis_multi_polygon() {} /* Remove gcc warning */ | |||
virtual ~Gis_multi_polygon() {} /* Remove gcc warning */ | virtual ~Gis_multi_polygon() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int num_geometries(uint32 *num) const; | int num_geometries(uint32 *num) const; | |||
int geometry_n(uint32 num, String *result) const; | int geometry_n(uint32 num, String *result) const; | |||
int area(double *ar, const char **end) const; | bool area(double *ar, wkb_parser *wkb) const; | |||
int centroid(String *result) const; | int centroid(String *result) const; | |||
bool dimension(uint32 *dim, const char **end) const | uint32 feature_dimension() const { return 2; } | |||
{ | ||||
*dim= 2; | ||||
*end= 0; /* No default end */ | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | |||
}; | }; | |||
/*********************** GeometryCollection ******************************* / | /*********************** GeometryCollection ******************************* / | |||
class Gis_geometry_collection: public Geometry | class Gis_geometry_collection: public Geometry | |||
{ | { | |||
public: | public: | |||
Gis_geometry_collection() {} /* Remove gcc warning */ | Gis_geometry_collection() {} /* Remove gcc warning */ | |||
virtual ~Gis_geometry_collection() {} /* Remove gcc warning */ | virtual ~Gis_geometry_collection() {} /* Remove gcc warning */ | |||
uint32 get_data_size() const; | uint32 get_data_size() const; | |||
bool init_from_wkt(Gis_read_stream *trs, String *wkb); | bool init_from_wkt(Gis_read_stream *trs, String *wkb); | |||
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *re s); | |||
uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | uint init_from_opresult(String *bin, const char *opres, uint opres_length ); | |||
bool get_data_as_wkt(String *txt, const char **end) const; | bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; | |||
bool get_mbr(MBR *mbr, const char **end) const; | bool get_mbr(MBR *mbr, wkb_parser *wkb) const; | |||
int area(double *ar, const char **end) const; | bool area(double *ar, wkb_parser *wkb) const; | |||
int num_geometries(uint32 *num) const; | int num_geometries(uint32 *num) const; | |||
int geometry_n(uint32 num, String *result) const; | int geometry_n(uint32 num, String *result) const; | |||
bool dimension(uint32 *dim, const char **end) const; | bool dimension(uint32 *dim, wkb_parser *wkb) const; | |||
uint32 feature_dimension() const | ||||
{ | ||||
DBUG_ASSERT(0); | ||||
return 0; | ||||
} | ||||
int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) co nst; | |||
const Class_info *get_class_info() const; | const Class_info *get_class_info() const; | |||
}; | }; | |||
struct Geometry_buffer : public | struct Geometry_buffer : public | |||
my_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {}; | my_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {}; | |||
#endif /*HAVE_SPATAIAL*/ | #endif /*HAVE_SPATAIAL*/ | |||
#endif | #endif | |||
End of changes. 47 change blocks. | ||||
112 lines changed or deleted | 310 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |