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/