My Project
|
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