My Project
spatial.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines