My Project
|
00001 /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software Foundation, 00014 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 00015 00016 #ifndef _spatial_h 00017 #define _spatial_h 00018 00019 #include "sql_string.h" /* String, LEX_STRING */ 00020 #include <my_compiler.h> 00021 00022 #ifdef HAVE_SPATIAL 00023 00024 #include "gcalc_tools.h" 00025 00026 #include <algorithm> 00027 00028 const uint SRID_SIZE= 4; 00029 const uint SIZEOF_STORED_DOUBLE= 8; 00030 const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2); 00031 const uint WKB_HEADER_SIZE= 1+4; 00032 const uint32 GET_SIZE_ERROR= ((uint32) -1); 00033 00034 00038 class point_xy 00039 { 00040 public: 00041 double x; 00042 double y; 00043 point_xy() { } 00044 point_xy(double x_arg, double y_arg): x(x_arg), y(y_arg) { } 00048 double distance(point_xy p) 00049 { 00050 return sqrt(pow(x - p.x, 2) + pow(y - p.y, 2)); 00051 } 00056 bool eq(point_xy p) 00057 { 00058 return (x == p.x) && (y == p.y); 00059 } 00060 }; 00061 00062 typedef struct wkb_header_st 00063 { 00064 uchar byte_order; 00065 uint32 wkb_type; 00066 } wkb_header; 00067 00068 00069 /***************************** MBR *******************************/ 00070 00071 00072 /* 00073 It's ok that a lot of the functions are inline as these are only used once 00074 in MySQL 00075 */ 00076 00077 struct MBR 00078 { 00079 double xmin, ymin, xmax, ymax; 00080 00081 MBR() 00082 { 00083 xmin= ymin= DBL_MAX; 00084 xmax= ymax= -DBL_MAX; 00085 } 00086 00087 MBR(const double xmin_arg, const double ymin_arg, 00088 const double xmax_arg, const double ymax_arg) 00089 :xmin(xmin_arg), ymin(ymin_arg), xmax(xmax_arg), ymax(ymax_arg) 00090 {} 00091 00092 MBR(const point_xy &min, const point_xy &max) 00093 :xmin(min.x), ymin(min.y), xmax(max.x), ymax(max.y) 00094 {} 00095 00096 inline void add_xy(double x, double y) 00097 { 00098 /* Not using "else" for proper one point MBR calculation */ 00099 if (x < xmin) 00100 xmin= x; 00101 if (x > xmax) 00102 xmax= x; 00103 if (y < ymin) 00104 ymin= y; 00105 if (y > ymax) 00106 ymax= y; 00107 } 00108 void add_xy(point_xy p) 00109 { 00110 add_xy(p.x, p.y); 00111 } 00112 void add_xy(const char *px, const char *py) 00113 { 00114 double x, y; 00115 float8get(x, px); 00116 float8get(y, py); 00117 add_xy(x,y); 00118 } 00119 void add_mbr(const MBR *mbr) 00120 { 00121 if (mbr->xmin < xmin) 00122 xmin= mbr->xmin; 00123 if (mbr->xmax > xmax) 00124 xmax= mbr->xmax; 00125 if (mbr->ymin < ymin) 00126 ymin= mbr->ymin; 00127 if (mbr->ymax > ymax) 00128 ymax= mbr->ymax; 00129 } 00130 00131 int equals(const MBR *mbr) 00132 { 00133 /* The following should be safe, even if we compare doubles */ 00134 return ((mbr->xmin == xmin) && (mbr->ymin == ymin) && 00135 (mbr->xmax == xmax) && (mbr->ymax == ymax)); 00136 } 00137 00138 int disjoint(const MBR *mbr) 00139 { 00140 /* The following should be safe, even if we compare doubles */ 00141 return ((mbr->xmin > xmax) || (mbr->ymin > ymax) || 00142 (mbr->xmax < xmin) || (mbr->ymax < ymin)); 00143 } 00144 00145 int intersects(const MBR *mbr) 00146 { 00147 return !disjoint(mbr); 00148 } 00149 00150 int touches(const MBR *mbr) 00151 { 00152 /* The following should be safe, even if we compare doubles */ 00153 return ((mbr->xmin == xmax || mbr->xmax == xmin) && 00154 ((mbr->ymin >= ymin && mbr->ymin <= ymax) || 00155 (mbr->ymax >= ymin && mbr->ymax <= ymax))) || 00156 ((mbr->ymin == ymax || mbr->ymax == ymin) && 00157 ((mbr->xmin >= xmin && mbr->xmin <= xmax) || 00158 (mbr->xmax >= xmin && mbr->xmax <= xmax))); 00159 } 00160 00161 int within(const MBR *mbr) 00162 { 00163 /* The following should be safe, even if we compare doubles */ 00164 return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && 00165 (mbr->xmax >= xmax) && (mbr->ymax >= ymax)); 00166 } 00167 00168 int contains(const MBR *mbr) 00169 { 00170 /* The following should be safe, even if we compare doubles */ 00171 return ((mbr->xmin >= xmin) && (mbr->ymin >= ymin) && 00172 (mbr->xmax <= xmax) && (mbr->ymax <= ymax)); 00173 } 00174 00175 bool inner_point(double x, double y) const 00176 { 00177 /* The following should be safe, even if we compare doubles */ 00178 return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>y); 00179 } 00180 00188 int dimension() const 00189 { 00190 int d= 0; 00191 00192 if (xmin > xmax) 00193 return -1; 00194 else if (xmin < xmax) 00195 d++; 00196 00197 if (ymin > ymax) 00198 return -1; 00199 else if (ymin < ymax) 00200 d++; 00201 00202 return d; 00203 } 00204 00205 int overlaps(const MBR *mbr) 00206 { 00207 /* 00208 overlaps() requires that some point inside *this is also inside 00209 *mbr, and that both geometries and their intersection are of the 00210 same dimension. 00211 */ 00212 int d = dimension(); 00213 00214 if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr)) 00215 return 0; 00216 00217 using std::min; 00218 using std::max; 00219 MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin), 00220 min(xmax, mbr->xmax), min(ymax, mbr->ymax)); 00221 00222 return (d == intersection.dimension()); 00223 } 00224 }; 00225 00226 00227 /***************************** Geometry *******************************/ 00228 00229 struct Geometry_buffer; 00230 00231 class Geometry 00232 { 00233 public: 00234 Geometry() {} /* Remove gcc warning */ 00235 virtual ~Geometry() {} /* Remove gcc warning */ 00236 static void *operator new(size_t size, void *buffer) 00237 { 00238 return buffer; 00239 } 00240 00241 static void operator delete(void *ptr, void *buffer) 00242 {} 00243 00244 static void operator delete(void *buffer) 00245 {} 00246 00247 static String bad_geometry_data; 00248 00249 enum wkbType 00250 { 00251 wkb_point= 1, 00252 wkb_linestring= 2, 00253 wkb_polygon= 3, 00254 wkb_multipoint= 4, 00255 wkb_multilinestring= 5, 00256 wkb_multipolygon= 6, 00257 wkb_geometrycollection= 7, 00258 wkb_last=7 00259 }; 00260 enum wkbByteOrder 00261 { 00262 wkb_xdr= 0, /* Big Endian */ 00263 wkb_ndr= 1 /* Little Endian */ 00264 }; 00265 00273 class wkb_container 00274 { 00275 protected: 00276 const char *m_data; 00277 const char *m_data_end; 00278 public: 00279 wkb_container() { } 00280 wkb_container(const char *data, const char *data_end) 00281 { 00282 set(data, data_end); 00283 } 00284 void set(const char *data, const char *data_end) 00285 { 00286 m_data= data; 00287 m_data_end= data_end; 00288 } 00289 const char *data() const 00290 { 00291 return m_data; 00292 } 00293 const char *data_end() const 00294 { 00295 return m_data_end; 00296 } 00297 uint32 length() const 00298 { 00299 return (uint32) (m_data_end - m_data); 00300 } 00308 inline bool no_data(size_t data_amount) const 00309 { 00310 return (m_data + data_amount > m_data_end); 00311 } 00312 00324 inline bool not_enough_points(uint32 expected_points, 00325 uint32 extra_point_space= 0) const 00326 { 00327 return (m_data_end < m_data || 00328 expected_points > ((m_data_end - m_data) / 00329 (POINT_DATA_SIZE + extra_point_space))); 00330 } 00331 }; 00332 00339 class wkb_parser: public wkb_container 00340 { 00341 /* Low level routines to get data of various types */ 00342 void get_uint4(uint32 *number) 00343 { 00344 *number= uint4korr(m_data); //GIS-TODO: byte order 00345 } 00346 void get_float8(double *x) 00347 { 00348 float8get(*x, m_data); //GIS-TODO: byte order 00349 } 00350 public: 00351 wkb_parser(const char *data, const char *data_end): 00352 wkb_container(data, data_end) { } 00353 wkb_parser(const wkb_container *container): 00354 wkb_container(*container) { } 00355 00356 /* Routines to skip non-interesting data */ 00357 void skip_unsafe(size_t nbytes) 00358 { 00359 DBUG_ASSERT(!no_data(nbytes)); 00360 m_data+= nbytes; 00361 } 00362 bool skip(size_t nbytes) 00363 { 00364 if (no_data(nbytes)) 00365 return true; 00366 m_data+= nbytes; 00367 return false; 00368 } 00369 bool skip_wkb_header() 00370 { 00371 return skip(WKB_HEADER_SIZE); 00372 } 00373 bool skip_coord() 00374 { 00375 return skip(SIZEOF_STORED_DOUBLE); 00376 } 00377 00378 /* Routines to scan wkb header information */ 00379 bool scan_wkb_header(wkb_header *header) 00380 { 00381 if (no_data(WKB_HEADER_SIZE)) 00382 return true; 00383 header->byte_order= (uchar) (*m_data); 00384 m_data++; 00385 get_uint4(&header->wkb_type); 00386 m_data+= 4; 00387 return false; 00388 } 00389 00390 /* Routines to scan uint4 information */ 00391 bool scan_uint4(uint32 *number) 00392 { 00393 if (no_data(4)) 00394 return true; 00395 get_uint4(number); 00396 m_data+= 4; 00397 return false; 00398 } 00399 bool scan_non_zero_uint4(uint32 *number) 00400 { 00401 return (scan_uint4(number) || 0 == *number); 00402 } 00403 bool scan_n_points_and_check_data(uint32 *n_points, 00404 uint32 extra_point_space= 0) 00405 { 00406 return scan_non_zero_uint4(n_points) || 00407 not_enough_points(*n_points, extra_point_space); 00408 } 00409 00410 /* Routines to scan coordinate information */ 00411 void scan_xy_unsafe(point_xy *p) 00412 { 00413 DBUG_ASSERT(!no_data(POINT_DATA_SIZE)); 00414 get_float8(&p->x); 00415 m_data+= SIZEOF_STORED_DOUBLE; 00416 get_float8(&p->y); 00417 m_data+= SIZEOF_STORED_DOUBLE; 00418 } 00419 bool scan_xy(point_xy *p) 00420 { 00421 if (no_data(SIZEOF_STORED_DOUBLE * 2)) 00422 return true; 00423 scan_xy_unsafe(p); 00424 return false; 00425 } 00426 bool scan_coord(double *x) 00427 { 00428 if (no_data(SIZEOF_STORED_DOUBLE)) 00429 return true; 00430 get_float8(x); 00431 m_data+= SIZEOF_STORED_DOUBLE; 00432 return false; 00433 } 00434 }; 00435 00437 typedef Geometry *(*create_geom_t)(char *); 00438 00439 class Class_info 00440 { 00441 public: 00442 LEX_STRING m_name; 00443 int m_type_id; 00444 create_geom_t m_create_func; 00445 Class_info(const char *name, int type_id, create_geom_t create_func); 00446 }; 00447 00448 virtual const Class_info *get_class_info() const=0; 00449 virtual uint32 get_data_size() const=0; 00450 virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0; 00451 /* returns the length of the wkb that was read */ 00452 virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, 00453 String *res)=0; 00454 virtual uint init_from_opresult(String *bin, 00455 const char *opres, uint opres_length) 00456 { return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; } 00457 00458 virtual bool get_data_as_wkt(String *txt, wkb_parser *wkb) const=0; 00459 virtual bool get_mbr(MBR *mbr, wkb_parser *wkb) const=0; 00460 bool get_mbr(MBR *mbr) 00461 { 00462 wkb_parser wkb(&m_wkb_data); 00463 return get_mbr(mbr, &wkb); 00464 } 00465 virtual bool dimension(uint32 *dim, wkb_parser *wkb) const 00466 { 00467 *dim= feature_dimension(); 00468 uint32 length; 00469 if ((length= get_data_size()) == GET_SIZE_ERROR) 00470 return true; 00471 wkb->skip(length); 00472 return false; 00473 } 00474 bool dimension(uint32 *dim) 00475 { 00476 wkb_parser wkb(&m_wkb_data); 00477 return dimension(dim, &wkb); 00478 } 00479 virtual uint32 feature_dimension() const= 0; 00480 virtual int get_x(double *x) const { return -1; } 00481 virtual int get_y(double *y) const { return -1; } 00482 virtual int geom_length(double *len) const { return -1; } 00490 virtual bool area(double *ar, wkb_parser *wkb) const 00491 { 00492 uint32 data_size= get_data_size(); 00493 if (data_size == GET_SIZE_ERROR || wkb->no_data(data_size)) 00494 return true; 00495 wkb->skip_unsafe(data_size); 00496 *ar= 0; 00497 return false; 00498 } 00499 bool area(double *ar) const 00500 { 00501 wkb_parser wkb(&m_wkb_data); 00502 return area(ar, &wkb); 00503 } 00504 virtual int is_closed(int *closed) const { return -1; } 00505 virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; } 00506 virtual int num_points(uint32 *n_points) const { return -1; } 00507 virtual int num_geometries(uint32 *num) const { return -1; } 00508 virtual int start_point(String *point) const { return -1; } 00509 virtual int end_point(String *point) const { return -1; } 00510 virtual int exterior_ring(String *ring) const { return -1; } 00511 virtual int centroid(String *point) const { return -1; } 00512 virtual int point_n(uint32 num, String *result) const { return -1; } 00513 virtual int interior_ring_n(uint32 num, String *result) const { return -1; } 00514 virtual int geometry_n(uint32 num, String *result) const { return -1; } 00515 virtual int store_shapes(Gcalc_shape_transporter *trn, 00516 Gcalc_shape_status *st) const=0; 00517 int store_shapes(Gcalc_shape_transporter *trn) const 00518 { 00519 Gcalc_shape_status dummy; 00520 return store_shapes(trn, &dummy); 00521 } 00522 00523 public: 00524 static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); 00525 static Geometry *scan_header_and_create(wkb_parser *wkb, Geometry_buffer *buffer) 00526 { 00527 Geometry *geom; 00528 wkb_header header; 00529 00530 if (wkb->scan_wkb_header(&header) || 00531 !(geom= create_by_typeid(buffer, header.wkb_type))) 00532 return NULL; 00533 geom->set_data_ptr(wkb); 00534 return geom; 00535 } 00536 00537 static Geometry *construct(Geometry_buffer *buffer, 00538 const char *data, uint32 data_len); 00539 static Geometry *construct(Geometry_buffer *buffer, const String *str) 00540 { 00541 return construct(buffer, str->ptr(), str->length()); 00542 } 00543 static Geometry *create_from_wkt(Geometry_buffer *buffer, 00544 Gis_read_stream *trs, String *wkt, 00545 bool init_stream=1); 00546 static Geometry *create_from_wkb(Geometry_buffer *buffer, 00547 const char *wkb, uint32 len, String *res); 00548 static int create_from_opresult(Geometry_buffer *g_buf, 00549 String *res, Gcalc_result_receiver &rr); 00550 bool as_wkt(String *wkt, wkb_parser *wkb) 00551 { 00552 uint32 len= (uint) get_class_info()->m_name.length; 00553 if (wkt->reserve(len + 2, 512)) 00554 return true; 00555 wkt->qs_append(get_class_info()->m_name.str, len); 00556 wkt->qs_append('('); 00557 if (get_data_as_wkt(wkt, wkb)) 00558 return true; 00559 wkt->qs_append(')'); 00560 return false; 00561 } 00562 bool as_wkt(String *wkt) 00563 { 00564 wkb_parser wkb(&m_wkb_data); 00565 return as_wkt(wkt, &wkb); 00566 } 00567 00568 inline void set_data_ptr(const char *data, uint32 data_len) 00569 { 00570 m_wkb_data.set(data, data + data_len); 00571 } 00572 00573 inline void set_data_ptr(const wkb_container *wkb) 00574 { 00575 m_wkb_data= *wkb; 00576 } 00577 00578 bool envelope(String *result) const; 00579 static Class_info *ci_collection[wkb_last+1]; 00580 00581 protected: 00582 static Class_info *find_class(int type_id) 00583 { 00584 return ((type_id < wkb_point) || (type_id > wkb_last)) ? 00585 NULL : ci_collection[type_id]; 00586 } 00587 static Class_info *find_class(const char *name, uint32 len); 00588 void append_points(String *txt, uint32 n_points, 00589 wkb_parser *wkb, uint32 offset) const; 00590 bool create_point(String *result, wkb_parser *wkb) const; 00591 bool create_point(String *result, point_xy p) const; 00592 bool get_mbr_for_points(MBR *mbr, wkb_parser *wkb, uint offset) const; 00593 wkb_container m_wkb_data; 00607 int collection_store_shapes(Gcalc_shape_transporter *trn, 00608 Gcalc_shape_status *st, 00609 Geometry *collection_item) const; 00617 bool collection_area(double *ar, wkb_parser *wkb, Geometry *it) const; 00618 00625 uint collection_init_from_opresult(String *bin, 00626 const char *opres, uint opres_length, 00627 Geometry *collection_item); 00628 00629 }; 00630 00631 00632 /***************************** Point *******************************/ 00633 00634 class Gis_point: public Geometry 00635 { 00636 public: 00637 Gis_point() {} /* Remove gcc warning */ 00638 virtual ~Gis_point() {} /* Remove gcc warning */ 00639 uint32 get_data_size() const; 00640 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00641 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00642 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00643 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00644 00645 int get_xy(point_xy *p) const 00646 { 00647 wkb_parser wkb(&m_wkb_data); 00648 return wkb.scan_xy(p); 00649 } 00650 int get_x(double *x) const 00651 { 00652 wkb_parser wkb(&m_wkb_data); 00653 return wkb.scan_coord(x); 00654 } 00655 int get_y(double *y) const 00656 { 00657 wkb_parser wkb(&m_wkb_data); 00658 return wkb.skip_coord() || wkb.scan_coord(y); 00659 } 00660 uint32 feature_dimension() const { return 0; } 00661 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00662 const Class_info *get_class_info() const; 00663 }; 00664 00665 00666 /***************************** LineString *******************************/ 00667 00668 class Gis_line_string: public Geometry 00669 { 00670 // Maximum number of points in LineString that can fit into String 00671 static const uint32 max_n_points= 00672 (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / 00673 POINT_DATA_SIZE; 00674 public: 00675 Gis_line_string() {} /* Remove gcc warning */ 00676 virtual ~Gis_line_string() {} /* Remove gcc warning */ 00677 uint32 get_data_size() const; 00678 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00679 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00680 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00681 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00682 int geom_length(double *len) const; 00683 int is_closed(int *closed) const; 00684 int num_points(uint32 *n_points) const; 00685 int start_point(String *point) const; 00686 int end_point(String *point) const; 00687 int point_n(uint32 n, String *result) const; 00688 uint32 feature_dimension() const { return 1; } 00689 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00690 const Class_info *get_class_info() const; 00691 }; 00692 00693 00694 /***************************** Polygon *******************************/ 00695 00696 class Gis_polygon: public Geometry 00697 { 00698 public: 00699 Gis_polygon() {} /* Remove gcc warning */ 00700 virtual ~Gis_polygon() {} /* Remove gcc warning */ 00701 uint32 get_data_size() const; 00702 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00703 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00704 uint init_from_opresult(String *bin, const char *opres, uint opres_length); 00705 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00706 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00707 bool area(double *ar, wkb_parser *wkb) const; 00708 int exterior_ring(String *result) const; 00709 int num_interior_ring(uint32 *n_int_rings) const; 00710 int interior_ring_n(uint32 num, String *result) const; 00711 bool centroid_xy(point_xy *p) const; 00712 int centroid(String *result) const; 00713 uint32 feature_dimension() const { return 2; } 00714 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00715 const Class_info *get_class_info() const; 00716 }; 00717 00718 00719 /***************************** MultiPoint *******************************/ 00720 00721 class Gis_multi_point: public Geometry 00722 { 00723 // Maximum number of points in MultiPoint that can fit into String 00724 static const uint32 max_n_points= 00725 (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / 00726 (WKB_HEADER_SIZE + POINT_DATA_SIZE); 00727 public: 00728 Gis_multi_point() {} /* Remove gcc warning */ 00729 virtual ~Gis_multi_point() {} /* Remove gcc warning */ 00730 uint32 get_data_size() const; 00731 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00732 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00733 uint init_from_opresult(String *bin, const char *opres, uint opres_length); 00734 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00735 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00736 int num_geometries(uint32 *num) const; 00737 int geometry_n(uint32 num, String *result) const; 00738 uint32 feature_dimension() const { return 0; } 00739 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00740 const Class_info *get_class_info() const; 00741 }; 00742 00743 00744 /***************************** MultiLineString *******************************/ 00745 00746 class Gis_multi_line_string: public Geometry 00747 { 00748 public: 00749 Gis_multi_line_string() {} /* Remove gcc warning */ 00750 virtual ~Gis_multi_line_string() {} /* Remove gcc warning */ 00751 uint32 get_data_size() const; 00752 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00753 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00754 uint init_from_opresult(String *bin, const char *opres, uint opres_length); 00755 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00756 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00757 int num_geometries(uint32 *num) const; 00758 int geometry_n(uint32 num, String *result) const; 00759 int geom_length(double *len) const; 00760 int is_closed(int *closed) const; 00761 uint32 feature_dimension() const { return 1; } 00762 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00763 const Class_info *get_class_info() const; 00764 }; 00765 00766 00767 /***************************** MultiPolygon *******************************/ 00768 00769 class Gis_multi_polygon: public Geometry 00770 { 00771 public: 00772 Gis_multi_polygon() {} /* Remove gcc warning */ 00773 virtual ~Gis_multi_polygon() {} /* Remove gcc warning */ 00774 uint32 get_data_size() const; 00775 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00776 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00777 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00778 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00779 int num_geometries(uint32 *num) const; 00780 int geometry_n(uint32 num, String *result) const; 00781 bool area(double *ar, wkb_parser *wkb) const; 00782 int centroid(String *result) const; 00783 uint32 feature_dimension() const { return 2; } 00784 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00785 const Class_info *get_class_info() const; 00786 uint init_from_opresult(String *bin, const char *opres, uint opres_length); 00787 }; 00788 00789 00790 /*********************** GeometryCollection *******************************/ 00791 00792 class Gis_geometry_collection: public Geometry 00793 { 00794 public: 00795 Gis_geometry_collection() {} /* Remove gcc warning */ 00796 virtual ~Gis_geometry_collection() {} /* Remove gcc warning */ 00797 uint32 get_data_size() const; 00798 bool init_from_wkt(Gis_read_stream *trs, String *wkb); 00799 uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); 00800 uint init_from_opresult(String *bin, const char *opres, uint opres_length); 00801 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const; 00802 bool get_mbr(MBR *mbr, wkb_parser *wkb) const; 00803 bool area(double *ar, wkb_parser *wkb) const; 00804 int num_geometries(uint32 *num) const; 00805 int geometry_n(uint32 num, String *result) const; 00806 bool dimension(uint32 *dim, wkb_parser *wkb) const; 00807 uint32 feature_dimension() const 00808 { 00809 DBUG_ASSERT(0); 00810 return 0; 00811 } 00812 int store_shapes(Gcalc_shape_transporter *trn, Gcalc_shape_status *st) const; 00813 const Class_info *get_class_info() const; 00814 }; 00815 00816 struct Geometry_buffer : public 00817 my_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {}; 00818 00819 #endif /*HAVE_SPATAIAL*/ 00820 #endif