My Project
item_geofunc.h
00001 #ifndef ITEM_GEOFUNC_INCLUDED
00002 #define ITEM_GEOFUNC_INCLUDED
00003 
00004 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; version 2 of the License.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software Foundation,
00017    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
00018 
00019 
00020 /* This file defines all spatial functions */
00021 
00022 #ifdef HAVE_SPATIAL
00023 
00024 #include "gcalc_slicescan.h"
00025 
00026 class Item_geometry_func: public Item_str_func
00027 {
00028 public:
00029   Item_geometry_func() :Item_str_func() {}
00030   Item_geometry_func(Item *a) :Item_str_func(a) {}
00031   Item_geometry_func(Item *a,Item *b) :Item_str_func(a,b) {}
00032   Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
00033   Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
00034   void fix_length_and_dec();
00035   enum_field_types field_type() const  { return MYSQL_TYPE_GEOMETRY; }
00036   Field *tmp_table_field(TABLE *t_arg);
00037   bool is_null() { (void) val_int(); return null_value; }
00038 };
00039 
00040 class Item_func_geometry_from_text: public Item_geometry_func
00041 {
00042 public:
00043   Item_func_geometry_from_text(Item *a) :Item_geometry_func(a) {}
00044   Item_func_geometry_from_text(Item *a, Item *srid) :Item_geometry_func(a, srid) {}
00045   const char *func_name() const { return "st_geometryfromtext"; }
00046   String *val_str(String *);
00047 };
00048 
00049 class Item_func_geometry_from_wkb: public Item_geometry_func
00050 {
00051   String tmp_value;
00052 public:
00053   Item_func_geometry_from_wkb(Item *a): Item_geometry_func(a) {}
00054   Item_func_geometry_from_wkb(Item *a, Item *srid): Item_geometry_func(a, srid) {}
00055   const char *func_name() const { return "st_geometryfromwkb"; }
00056   String *val_str(String *);
00057 };
00058 
00059 class Item_func_as_wkt: public Item_str_ascii_func
00060 {
00061 public:
00062   Item_func_as_wkt(Item *a): Item_str_ascii_func(a) {}
00063   const char *func_name() const { return "st_astext"; }
00064   String *val_str_ascii(String *);
00065   void fix_length_and_dec();
00066 };
00067 
00068 class Item_func_as_wkb: public Item_geometry_func
00069 {
00070 public:
00071   Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
00072   const char *func_name() const { return "st_aswkb"; }
00073   String *val_str(String *);
00074   enum_field_types field_type() const  { return MYSQL_TYPE_BLOB; }
00075 };
00076 
00077 class Item_func_geometry_type: public Item_str_ascii_func
00078 {
00079 public:
00080   Item_func_geometry_type(Item *a): Item_str_ascii_func(a) {}
00081   String *val_str_ascii(String *);
00082   const char *func_name() const { return "st_geometrytype"; }
00083   void fix_length_and_dec() 
00084   {
00085     // "GeometryCollection" is the longest
00086     fix_length_and_charset(20, default_charset());
00087     maybe_null= 1;
00088   };
00089 };
00090 
00091 class Item_func_centroid: public Item_geometry_func
00092 {
00093 public:
00094   Item_func_centroid(Item *a): Item_geometry_func(a) {}
00095   const char *func_name() const { return "st_centroid"; }
00096   String *val_str(String *);
00097   Field::geometry_type get_geometry_type() const;
00098 };
00099 
00100 class Item_func_envelope: public Item_geometry_func
00101 {
00102 public:
00103   Item_func_envelope(Item *a): Item_geometry_func(a) {}
00104   const char *func_name() const { return "st_envelope"; }
00105   String *val_str(String *);
00106   Field::geometry_type get_geometry_type() const;
00107 };
00108 
00109 class Item_func_point: public Item_geometry_func
00110 {
00111 public:
00112   Item_func_point(Item *a, Item *b): Item_geometry_func(a, b) {}
00113   Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {}
00114   const char *func_name() const { return "st_point"; }
00115   String *val_str(String *);
00116   Field::geometry_type get_geometry_type() const;
00117 };
00118 
00119 class Item_func_spatial_decomp: public Item_geometry_func
00120 {
00121   enum Functype decomp_func;
00122 public:
00123   Item_func_spatial_decomp(Item *a, Item_func::Functype ft) :
00124         Item_geometry_func(a) { decomp_func = ft; }
00125   const char *func_name() const 
00126   { 
00127     switch (decomp_func)
00128     {
00129       case SP_STARTPOINT:
00130         return "st_startpoint";
00131       case SP_ENDPOINT:
00132         return "st_endpoint";
00133       case SP_EXTERIORRING:
00134         return "st_exteriorring";
00135       default:
00136         DBUG_ASSERT(0);  // Should never happened
00137         return "spatial_decomp_unknown"; 
00138     }
00139   }
00140   String *val_str(String *);
00141 };
00142 
00143 class Item_func_spatial_decomp_n: public Item_geometry_func
00144 {
00145   enum Functype decomp_func_n;
00146 public:
00147   Item_func_spatial_decomp_n(Item *a, Item *b, Item_func::Functype ft):
00148         Item_geometry_func(a, b) { decomp_func_n = ft; }
00149   const char *func_name() const 
00150   { 
00151     switch (decomp_func_n)
00152     {
00153       case SP_POINTN:
00154         return "st_pointn";
00155       case SP_GEOMETRYN:
00156         return "st_geometryn";
00157       case SP_INTERIORRINGN:
00158         return "st_interiorringn";
00159       default:
00160         DBUG_ASSERT(0);  // Should never happened
00161         return "spatial_decomp_n_unknown"; 
00162     }
00163   }
00164   String *val_str(String *);
00165 };
00166 
00167 class Item_func_spatial_collection: public Item_geometry_func
00168 {
00169   String tmp_value;
00170   enum Geometry::wkbType coll_type; 
00171   enum Geometry::wkbType item_type;
00172 public:
00173   Item_func_spatial_collection(
00174      List<Item> &list, enum Geometry::wkbType ct, enum Geometry::wkbType it):
00175   Item_geometry_func(list)
00176   {
00177     coll_type=ct;
00178     item_type=it;
00179   }
00180   String *val_str(String *);
00181   void fix_length_and_dec()
00182   {
00183     Item_geometry_func::fix_length_and_dec();
00184     for (unsigned int i= 0; i < arg_count; ++i)
00185     {
00186       if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
00187       {
00188         String str;
00189         args[i]->print(&str, QT_ORDINARY);
00190         str.append('\0');
00191         my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
00192                  str.ptr());
00193       }
00194     }
00195   }
00196  
00197   const char *func_name() const { return "st_multipoint"; }
00198 };
00199 
00200 
00201 /*
00202   Spatial relations
00203 */
00204 
00205 class Item_func_spatial_mbr_rel: public Item_bool_func2
00206 {
00207   enum Functype spatial_rel;
00208 public:
00209   Item_func_spatial_mbr_rel(Item *a,Item *b, enum Functype sp_rel) :
00210     Item_bool_func2(a,b) { spatial_rel = sp_rel; }
00211   longlong val_int();
00212   enum Functype functype() const 
00213   { 
00214     return spatial_rel;
00215   }
00216   enum Functype rev_functype() const
00217   {
00218     switch (spatial_rel)
00219     {
00220       case SP_CONTAINS_FUNC:
00221         return SP_WITHIN_FUNC;
00222       case SP_WITHIN_FUNC:
00223         return SP_CONTAINS_FUNC;
00224       default:
00225         return spatial_rel;
00226     }
00227   }
00228 
00229   const char *func_name() const;
00230   virtual inline void print(String *str, enum_query_type query_type)
00231   {
00232     Item_func::print(str, query_type);
00233   }
00234   void fix_length_and_dec() { maybe_null= 1; }
00235   bool is_null() { (void) val_int(); return null_value; }
00236 };
00237 
00238 
00239 class Item_func_spatial_rel: public Item_bool_func2
00240 {
00241   enum Functype spatial_rel;
00242   Gcalc_heap collector;
00243   Gcalc_scan_iterator scan_it;
00244   Gcalc_function func;
00245   String tmp_value1,tmp_value2;
00246 public:
00247   Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel);
00248   virtual ~Item_func_spatial_rel();
00249   longlong val_int();
00250   enum Functype functype() const 
00251   { 
00252     return spatial_rel;
00253   }
00254   enum Functype rev_functype() const
00255   {
00256     switch (spatial_rel)
00257     {
00258       case SP_CONTAINS_FUNC:
00259         return SP_WITHIN_FUNC;
00260       case SP_WITHIN_FUNC:
00261         return SP_CONTAINS_FUNC;
00262       default:
00263         return spatial_rel;
00264     }
00265   }
00266 
00267   const char *func_name() const;
00268   virtual inline void print(String *str, enum_query_type query_type)
00269   {
00270     Item_func::print(str, query_type);
00271   }
00272 
00273   void fix_length_and_dec() { maybe_null= 1; }
00274   bool is_null() { (void) val_int(); return null_value; }
00275 protected:
00276   int func_touches();
00277   int func_equals();
00278 };
00279 
00280 
00281 /*
00282   Spatial operations
00283 */
00284 
00285 class Item_func_spatial_operation: public Item_geometry_func
00286 {
00287 public:
00288   Gcalc_function::op_type spatial_op;
00289   Gcalc_heap collector;
00290   Gcalc_function func;
00291 
00292   Gcalc_result_receiver res_receiver;
00293   Gcalc_operation_reducer operation;
00294   String tmp_value1,tmp_value2;
00295 public:
00296   Item_func_spatial_operation(Item *a,Item *b, Gcalc_function::op_type sp_op) :
00297     Item_geometry_func(a, b), spatial_op(sp_op)
00298   {}
00299   virtual ~Item_func_spatial_operation();
00300   String *val_str(String *);
00301   const char *func_name() const;
00302   virtual inline void print(String *str, enum_query_type query_type)
00303   {
00304     Item_func::print(str, query_type);
00305   }
00306 };
00307 
00308 
00309 class Item_func_buffer: public Item_geometry_func
00310 {
00311 protected:
00312   class Transporter : public Gcalc_operation_transporter
00313   {
00314     int m_npoints;
00315     double m_d;
00316     Gcalc_function::op_type m_buffer_op;
00317     double x1,y1,x2,y2;
00318     double x00,y00,x01,y01;
00319     int add_edge_buffer(Gcalc_shape_status *st,
00320                         double x3, double y3, bool round_p1, bool round_p2);
00321     int add_last_edge_buffer(Gcalc_shape_status *st);
00322     int add_point_buffer(Gcalc_shape_status *st, double x, double y);
00323     int complete(Gcalc_shape_status *st);
00324   public:
00325     Transporter(Gcalc_function *fn, Gcalc_heap *heap, double d) :
00326       Gcalc_operation_transporter(fn, heap), m_npoints(0), m_d(d)
00327     {
00328       m_buffer_op= d > 0.0 ? Gcalc_function::op_union :
00329                              Gcalc_function::op_difference;
00330     }
00331     int single_point(Gcalc_shape_status *st, double x, double y);
00332     int start_line(Gcalc_shape_status *st);
00333     int complete_line(Gcalc_shape_status *st);
00334     int start_poly(Gcalc_shape_status *st);
00335     int complete_poly(Gcalc_shape_status *st);
00336     int start_ring(Gcalc_shape_status *st);
00337     int complete_ring(Gcalc_shape_status *st);
00338     int add_point(Gcalc_shape_status *st, double x, double y);
00339     int start_collection(Gcalc_shape_status *st, int nshapes);
00340     int complete_collection(Gcalc_shape_status *st);
00341     int collection_add_item(Gcalc_shape_status *st_collection,
00342                             Gcalc_shape_status *st_item);
00343 
00344     bool skip_point() const
00345     { return m_buffer_op == Gcalc_function::op_difference; }
00346     bool skip_line_string() const
00347     { return m_buffer_op == Gcalc_function::op_difference; }
00348     bool skip_poly() const
00349     { return false; }
00350   };
00351   Gcalc_heap collector;
00352   Gcalc_function func;
00353 
00354   Gcalc_result_receiver res_receiver;
00355   Gcalc_operation_reducer operation;
00356   String tmp_value;
00357 
00358 public:
00359   Item_func_buffer(Item *obj, Item *distance):
00360     Item_geometry_func(obj, distance) {}
00361   const char *func_name() const { return "st_buffer"; }
00362   String *val_str(String *);
00363 };
00364 
00365 
00366 class Item_func_isempty: public Item_bool_func
00367 {
00368 public:
00369   Item_func_isempty(Item *a): Item_bool_func(a) {}
00370   longlong val_int();
00371   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
00372   const char *func_name() const { return "st_isempty"; }
00373   void fix_length_and_dec() { maybe_null= 1; }
00374 };
00375 
00376 class Item_func_issimple: public Item_bool_func
00377 {
00378   Gcalc_heap collector;
00379   Gcalc_function func;
00380   Gcalc_scan_iterator scan_it;
00381   String tmp;
00382 public:
00383   Item_func_issimple(Item *a): Item_bool_func(a) {}
00384   longlong val_int();
00385   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
00386   const char *func_name() const { return "st_issimple"; }
00387   void fix_length_and_dec() { maybe_null= 1; }
00388 };
00389 
00390 class Item_func_isclosed: public Item_bool_func
00391 {
00392 public:
00393   Item_func_isclosed(Item *a): Item_bool_func(a) {}
00394   longlong val_int();
00395   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
00396   const char *func_name() const { return "st_isclosed"; }
00397   void fix_length_and_dec() { maybe_null= 1; }
00398 };
00399 
00400 class Item_func_dimension: public Item_int_func
00401 {
00402   String value;
00403 public:
00404   Item_func_dimension(Item *a): Item_int_func(a) {}
00405   longlong val_int();
00406   const char *func_name() const { return "st_dimension"; }
00407   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
00408 };
00409 
00410 class Item_func_x: public Item_real_func
00411 {
00412   String value;
00413 public:
00414   Item_func_x(Item *a): Item_real_func(a) {}
00415   double val_real();
00416   const char *func_name() const { return "st_x"; }
00417   void fix_length_and_dec() 
00418   { 
00419     Item_real_func::fix_length_and_dec();
00420     maybe_null= 1; 
00421   }
00422 };
00423 
00424 
00425 class Item_func_y: public Item_real_func
00426 {
00427   String value;
00428 public:
00429   Item_func_y(Item *a): Item_real_func(a) {}
00430   double val_real();
00431   const char *func_name() const { return "st_y"; }
00432   void fix_length_and_dec() 
00433   { 
00434     Item_real_func::fix_length_and_dec();
00435     maybe_null= 1; 
00436   }
00437 };
00438 
00439 
00440 class Item_func_numgeometries: public Item_int_func
00441 {
00442   String value;
00443 public:
00444   Item_func_numgeometries(Item *a): Item_int_func(a) {}
00445   longlong val_int();
00446   const char *func_name() const { return "st_numgeometries"; }
00447   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
00448 };
00449 
00450 
00451 class Item_func_numinteriorring: public Item_int_func
00452 {
00453   String value;
00454 public:
00455   Item_func_numinteriorring(Item *a): Item_int_func(a) {}
00456   longlong val_int();
00457   const char *func_name() const { return "st_numinteriorrings"; }
00458   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
00459 };
00460 
00461 
00462 class Item_func_numpoints: public Item_int_func
00463 {
00464   String value;
00465 public:
00466   Item_func_numpoints(Item *a): Item_int_func(a) {}
00467   longlong val_int();
00468   const char *func_name() const { return "st_numpoints"; }
00469   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
00470 };
00471 
00472 
00473 class Item_func_area: public Item_real_func
00474 {
00475   String value;
00476 public:
00477   Item_func_area(Item *a): Item_real_func(a) {}
00478   double val_real();
00479   const char *func_name() const { return "st_area"; }
00480   void fix_length_and_dec() 
00481   { 
00482     Item_real_func::fix_length_and_dec();
00483     maybe_null= 1; 
00484   }
00485 };
00486 
00487 
00488 class Item_func_glength: public Item_real_func
00489 {
00490   String value;
00491 public:
00492   Item_func_glength(Item *a): Item_real_func(a) {}
00493   double val_real();
00494   const char *func_name() const { return "st_length"; }
00495   void fix_length_and_dec() 
00496   { 
00497     Item_real_func::fix_length_and_dec();
00498     maybe_null= 1; 
00499   }
00500 };
00501 
00502 
00503 class Item_func_srid: public Item_int_func
00504 {
00505   String value;
00506 public:
00507   Item_func_srid(Item *a): Item_int_func(a) {}
00508   longlong val_int();
00509   const char *func_name() const { return "srid"; }
00510   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
00511 };
00512 
00513 
00514 class Item_func_distance: public Item_real_func
00515 {
00516   String tmp_value1;
00517   String tmp_value2;
00518   Gcalc_heap collector;
00519   Gcalc_function func;
00520   Gcalc_scan_iterator scan_it;
00521 public:
00522   Item_func_distance(Item *a, Item *b): Item_real_func(a, b) {}
00523   double val_real();
00524   const char *func_name() const { return "st_distance"; }
00525 };
00526 
00527 
00528 #ifndef DBUG_OFF
00529 class Item_func_gis_debug: public Item_int_func
00530 {
00531 public:
00532   Item_func_gis_debug(Item *a) :Item_int_func(a) { null_value= false; }
00533   const char *func_name() const  { return "st_gis_debug"; }
00534   longlong val_int();
00535 };
00536 #endif
00537 
00538 
00539 #define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
00540 
00541 #else /*HAVE_SPATIAL*/
00542 
00543 #define GEOM_NEW(thd, obj_constructor) NULL
00544 
00545 #endif /*HAVE_SPATIAL*/
00546 #endif /*ITEM_GEOFUNC_INCLUDED*/
00547 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines