30 #include "sql_class.h"
36 Field *Item_geometry_func::tmp_table_field(
TABLE *t_arg)
39 if ((result=
new Field_geom(max_length, maybe_null, item_name.ptr(), t_arg->s,
40 get_geometry_type())))
45 void Item_geometry_func::fix_length_and_dec()
47 collation.set(&my_charset_bin);
49 max_length= (uint32) 4294967295
U;
54 String *Item_func_geometry_from_text::val_str(
String *str)
56 DBUG_ASSERT(fixed == 1);
57 Geometry_buffer buffer;
59 String *wkt= args[0]->val_str_ascii(&arg_val);
61 if ((null_value= args[0]->null_value))
67 if ((arg_count == 2) && !args[1]->null_value)
68 srid= (uint32)args[1]->val_int();
70 str->set_charset(&my_charset_bin);
71 if (str->reserve(SRID_SIZE, 512))
75 if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
81 String *Item_func_geometry_from_wkb::val_str(
String *str)
83 DBUG_ASSERT(fixed == 1);
85 Geometry_buffer buffer;
90 srid= args[1]->val_int();
91 if ((null_value= args[1]->null_value))
95 wkb= args[0]->val_str(&tmp_value);
96 if ((null_value= args[0]->null_value))
106 if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY)
112 if (wkb->length() < 4 || srid == uint4korr(wkb->ptr()))
120 if ((null_value= str->copy(*wkb)))
122 str->write_at_position(0, srid);
126 str->set_charset(&my_charset_bin);
127 if (str->reserve(SRID_SIZE, 512))
135 (args[0]->null_value ||
136 !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str))))
144 DBUG_ASSERT(fixed == 1);
146 String *swkb= args[0]->val_str(&arg_val);
147 Geometry_buffer buffer;
148 Geometry *geom= NULL;
151 (args[0]->null_value ||
152 !(geom= Geometry::construct(&buffer, swkb)))))
156 if ((null_value= geom->as_wkt(str)))
163 void Item_func_as_wkt::fix_length_and_dec()
165 collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
166 max_length=MAX_BLOB_WIDTH;
173 DBUG_ASSERT(fixed == 1);
175 String *swkb= args[0]->val_str(&arg_val);
176 Geometry_buffer buffer;
179 (args[0]->null_value ||
180 !(Geometry::construct(&buffer, swkb)))))
183 str->copy(swkb->ptr() + SRID_SIZE, swkb->length() - SRID_SIZE,
189 String *Item_func_geometry_type::val_str_ascii(
String *str)
191 DBUG_ASSERT(fixed == 1);
192 String *swkb= args[0]->val_str(str);
193 Geometry_buffer buffer;
194 Geometry *geom= NULL;
197 (args[0]->null_value ||
198 !(geom= Geometry::construct(&buffer, swkb)))))
201 str->copy(geom->get_class_info()->m_name.str,
202 geom->get_class_info()->m_name.length,
208 Field::geometry_type Item_func_envelope::get_geometry_type()
const
210 return Field::GEOM_POLYGON;
216 DBUG_ASSERT(fixed == 1);
218 String *swkb= args[0]->val_str(&arg_val);
219 Geometry_buffer buffer;
220 Geometry *geom= NULL;
224 args[0]->null_value ||
225 !(geom= Geometry::construct(&buffer, swkb))))
228 srid= uint4korr(swkb->ptr());
229 str->set_charset(&my_charset_bin);
231 if (str->reserve(SRID_SIZE, 512))
234 return (null_value= geom->envelope(str)) ? 0 : str;
238 Field::geometry_type Item_func_centroid::get_geometry_type()
const
240 return Field::GEOM_POINT;
246 DBUG_ASSERT(fixed == 1);
248 String *swkb= args[0]->val_str(&arg_val);
249 Geometry_buffer buffer;
250 Geometry *geom= NULL;
253 if ((null_value= args[0]->null_value ||
254 !(geom= Geometry::construct(&buffer, swkb))))
257 str->set_charset(&my_charset_bin);
258 if (str->reserve(SRID_SIZE, 512))
261 srid= uint4korr(swkb->ptr());
264 return (null_value=
test(geom->centroid(str))) ? 0 : str;
274 DBUG_ASSERT(fixed == 1);
276 String *swkb= args[0]->val_str(&arg_val);
277 Geometry_buffer buffer;
278 Geometry *geom= NULL;
282 (args[0]->null_value ||
283 !(geom= Geometry::construct(&buffer, swkb)))))
286 srid= uint4korr(swkb->ptr());
287 str->set_charset(&my_charset_bin);
288 if (str->reserve(SRID_SIZE, 512))
292 switch (decomp_func) {
294 if (geom->start_point(str))
299 if (geom->end_point(str))
303 case SP_EXTERIORRING:
304 if (geom->exterior_ring(str))
319 String *Item_func_spatial_decomp_n::val_str(
String *str)
321 DBUG_ASSERT(fixed == 1);
323 String *swkb= args[0]->val_str(&arg_val);
324 long n= (long) args[1]->val_int();
325 Geometry_buffer buffer;
326 Geometry *geom= NULL;
330 (args[0]->null_value || args[1]->null_value ||
331 !(geom= Geometry::construct(&buffer, swkb)))))
334 str->set_charset(&my_charset_bin);
335 if (str->reserve(SRID_SIZE, 512))
337 srid= uint4korr(swkb->ptr());
340 switch (decomp_func_n)
343 if (geom->point_n(n,str))
348 if (geom->geometry_n(n,str))
352 case SP_INTERIORRINGN:
353 if (geom->interior_ring_n(n,str))
378 Field::geometry_type Item_func_point::get_geometry_type()
const
380 return Field::GEOM_POINT;
386 DBUG_ASSERT(fixed == 1);
387 double x= args[0]->val_real();
388 double y= args[1]->val_real();
391 if ((null_value= (args[0]->null_value ||
392 args[1]->null_value ||
393 str->
realloc(4 + 1 + 4 + SIZEOF_STORED_DOUBLE * 2))))
396 str->set_charset(&my_charset_bin);
399 str->q_append((
char)Geometry::wkb_ndr);
400 str->q_append((uint32)Geometry::wkb_point);
417 String *Item_func_spatial_collection::val_str(
String *str)
419 DBUG_ASSERT(fixed == 1);
424 str->set_charset(&my_charset_bin);
426 if (str->reserve(4 + 1 + 4 + 4, 512))
430 str->q_append((
char) Geometry::wkb_ndr);
431 str->q_append((uint32) coll_type);
432 str->q_append((uint32) arg_count);
434 for (i= 0; i < arg_count; ++
i)
436 String *res= args[
i]->val_str(&arg_value);
438 if (args[i]->null_value || ((len= res->length()) < WKB_HEADER_SIZE))
441 if (coll_type == Geometry::wkb_geometrycollection)
447 if (str->append(res->ptr() + 4, len - 4, (uint32) 512))
452 enum Geometry::wkbType wkb_type;
453 const uint data_offset= 4 + 1;
454 if (res->length() < data_offset +
sizeof(uint32))
456 const char *data= res->ptr() + data_offset;
463 wkb_type= (Geometry::wkbType) uint4korr(data);
466 if (wkb_type != item_type)
470 case Geometry::wkb_multipoint:
471 case Geometry::wkb_multilinestring:
472 case Geometry::wkb_multipolygon:
473 if (len < WKB_HEADER_SIZE ||
474 str->append(data-WKB_HEADER_SIZE, len+WKB_HEADER_SIZE, 512))
478 case Geometry::wkb_linestring:
479 if (len < POINT_DATA_SIZE || str->append(data, POINT_DATA_SIZE, 512))
482 case Geometry::wkb_polygon:
485 double x1, y1, x2, y2;
486 const char *org_data= data;
491 n_points= uint4korr(data);
494 if (n_points < 2 || len < 4 + n_points * POINT_DATA_SIZE)
498 data+= SIZEOF_STORED_DOUBLE;
500 data+= SIZEOF_STORED_DOUBLE;
502 data+= (n_points - 2) * POINT_DATA_SIZE;
505 float8get(y2, data + SIZEOF_STORED_DOUBLE);
507 if ((x1 != x2) || (y1 != y2) ||
508 str->append(org_data, len, 512))
518 if (str->length() > current_thd->variables.max_allowed_packet)
520 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
521 ER_WARN_ALLOWED_PACKET_OVERFLOWED,
522 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
523 func_name(), current_thd->variables.max_allowed_packet);
540 const char *Item_func_spatial_mbr_rel::func_name()
const
542 switch (spatial_rel) {
543 case SP_CONTAINS_FUNC:
544 return "mbrcontains";
549 case SP_DISJOINT_FUNC:
550 return "mbrdisjoint";
551 case SP_INTERSECTS_FUNC:
552 return "mbrintersects";
553 case SP_TOUCHES_FUNC:
555 case SP_CROSSES_FUNC:
557 case SP_OVERLAPS_FUNC:
558 return "mbroverlaps";
561 return "mbrsp_unknown";
566 longlong Item_func_spatial_mbr_rel::val_int()
568 DBUG_ASSERT(fixed == 1);
569 String *res1= args[0]->val_str(&cmp.value1);
570 String *res2= args[1]->val_str(&cmp.value2);
571 Geometry_buffer buffer1, buffer2;
576 (args[0]->null_value ||
577 args[1]->null_value ||
578 !(g1= Geometry::construct(&buffer1, res1)) ||
579 !(g2= Geometry::construct(&buffer2, res2)) ||
580 g1->get_mbr(&mbr1) ||
581 g2->get_mbr(&mbr2))))
584 switch (spatial_rel) {
585 case SP_CONTAINS_FUNC:
586 return mbr1.contains(&mbr2);
588 return mbr1.within(&mbr2);
590 return mbr1.equals(&mbr2);
591 case SP_DISJOINT_FUNC:
592 return mbr1.disjoint(&mbr2);
593 case SP_INTERSECTS_FUNC:
594 return mbr1.intersects(&mbr2);
595 case SP_TOUCHES_FUNC:
596 return mbr1.touches(&mbr2);
597 case SP_OVERLAPS_FUNC:
598 return mbr1.overlaps(&mbr2);
599 case SP_CROSSES_FUNC:
610 Item_func_spatial_rel::Item_func_spatial_rel(
Item *a,
Item *b,
611 enum Functype sp_rel) :
614 spatial_rel = sp_rel;
618 Item_func_spatial_rel::~Item_func_spatial_rel()
623 const char *Item_func_spatial_rel::func_name()
const
625 switch (spatial_rel) {
626 case SP_CONTAINS_FUNC:
627 return "st_contains";
632 case SP_DISJOINT_FUNC:
633 return "st_disjoint";
634 case SP_INTERSECTS_FUNC:
635 return "st_intersects";
636 case SP_TOUCHES_FUNC:
638 case SP_CROSSES_FUNC:
640 case SP_OVERLAPS_FUNC:
641 return "st_overlaps";
652 double &ex,
double &ey,
double &vx,
double &vy,
659 e_sqrlen= ex * ex + ey * ey;
660 return (ex * vx + ey * vy) / e_sqrlen;
664 static double distance_to_line(
double ex,
double ey,
double vx,
double vy,
667 return fabs(vx * ey - vy * ex) / sqrt(e_sqrlen);
674 double x= a->x - b->x;
675 double y= a->y - b->y;
676 return sqrt(x * x + y * y);
684 static int calc_distance(
double *result,
Gcalc_heap *collector, uint obj2_si,
690 Gcalc_scan_events ev;
691 double t, distance, cur_distance;
692 double ex, ey, vx, vy, e_sqrlen;
694 DBUG_ENTER(
"calc_distance");
698 while (scan_it->more_points())
702 evpos= scan_it->get_event_position();
703 ev= scan_it->get_event();
704 cur_point= evpos->pi;
710 if (ev == scev_intersection)
712 if ((evpos->get_next()->pi->shape >= obj2_si) !=
713 (cur_point->shape >= obj2_si))
726 if (ev & (scev_point | scev_end | scev_two_ends))
727 goto calculate_distance;
729 goto calculate_distance;
735 DBUG_ASSERT(ev & (scev_thread | scev_two_threads | scev_single_point));
740 gcalc_shape_info si= pit.point()->get_shape();
741 if ((func->get_shape_kind(si) == Gcalc_function::shape_polygon))
742 func->invert_state(si);
744 func->invert_state(evpos->get_shape());
754 if (cur_point->shape >= obj2_si)
756 cur_point_edge= !cur_point->is_bottom();
758 for (dist_point= collector->get_first(); dist_point; dist_point= dist_point->get_next())
761 if (dist_point->shape < obj2_si)
765 if (dist_point->left)
767 t= count_edge_t(dist_point, dist_point->left, cur_point,
768 ex, ey, vx, vy, e_sqrlen);
769 if ((t > 0.0) && (t < 1.0))
771 cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
772 if (distance > cur_distance)
773 distance= cur_distance;
778 t= count_edge_t(cur_point, cur_point->left, dist_point,
779 ex, ey, vx, vy, e_sqrlen);
780 if ((t > 0.0) && (t < 1.0))
782 cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
783 if (distance > cur_distance)
784 distance= cur_distance;
787 cur_distance= distance_points(cur_point, dist_point);
788 if (distance > cur_distance)
789 distance= cur_distance;
802 #define GIS_ZERO 0.00000000001
804 int Item_func_spatial_rel::func_touches()
806 double distance= GIS_ZERO;
812 String *res1= args[0]->val_str(&tmp_value1);
813 String *res2= args[1]->val_str(&tmp_value2);
814 Geometry_buffer buffer1, buffer2;
818 DBUG_ENTER(
"Item_func_spatial_rel::func_touches");
819 DBUG_ASSERT(fixed == 1);
821 if ((null_value= (args[0]->null_value || args[1]->null_value ||
822 !(g1= Geometry::construct(&buffer1, res1)) ||
823 !(g2= Geometry::construct(&buffer2, res2)))))
826 if ((g1->get_class_info()->m_type_id == Geometry::wkb_point) &&
827 (g2->get_class_info()->m_type_id == Geometry::wkb_point))
830 if (((Gis_point *) g1)->get_xy(&p1) ||
831 ((Gis_point *) g2)->get_xy(&p2))
835 DBUG_RETURN((e.x * e.x + e.y * e.y) < GIS_ZERO);
838 if (func.reserve_op_buffer(1))
840 func.add_operation(Gcalc_function::op_intersection, 2);
842 if (g1->store_shapes(&trn))
844 obj2_si= func.get_nshapes();
846 if (g2->store_shapes(&trn) || func.alloc_states())
853 collector.prepare_operation();
854 scan_it.init(&collector);
856 if (calc_distance(&distance, &collector, obj2_si, &func, &scan_it))
858 if (distance > GIS_ZERO)
862 scan_it.init(&collector);
866 while (scan_it.more_trapezoids())
874 gcalc_shape_info si= ti.lb()->get_shape();
875 if ((func.get_shape_kind(si) == Gcalc_function::shape_polygon))
877 func.invert_state(si);
878 cur_func= func.count();
882 double area= scan_it.get_h() *
883 ((ti.rb()->x - ti.lb()->x) + (ti.rt()->x - ti.lt()->x));
905 int Item_func_spatial_rel::func_equals()
917 while ((cur_pi= cur_pi->get_next()))
919 d= fabs(pi_s1->x - cur_pi->x) + fabs(pi_s1->y - cur_pi->y);
922 if (!pi_s2 && pi_s1->shape != cur_pi->shape)
934 longlong Item_func_spatial_rel::val_int()
936 DBUG_ENTER(
"Item_func_spatial_rel::val_int");
937 DBUG_ASSERT(fixed == 1);
940 Geometry_buffer buffer1, buffer2;
945 if (spatial_rel == SP_TOUCHES_FUNC)
946 DBUG_RETURN(func_touches());
948 res1= args[0]->val_str(&tmp_value1);
949 res2= args[1]->val_str(&tmp_value2);
952 if (func.reserve_op_buffer(1))
955 switch (spatial_rel) {
956 case SP_CONTAINS_FUNC:
958 func.add_operation(Gcalc_function::op_backdifference, 2);
962 func.add_operation(Gcalc_function::op_difference, 2);
966 case SP_DISJOINT_FUNC:
968 func.add_operation(Gcalc_function::op_intersection, 2);
970 case SP_INTERSECTS_FUNC:
971 func.add_operation(Gcalc_function::op_intersection, 2);
973 case SP_OVERLAPS_FUNC:
974 func.add_operation(Gcalc_function::op_backdifference, 2);
976 case SP_CROSSES_FUNC:
977 func.add_operation(Gcalc_function::op_intersection, 2);
986 (args[0]->null_value || args[1]->null_value ||
987 !(g1= Geometry::construct(&buffer1, res1)) ||
988 !(g2= Geometry::construct(&buffer2, res2)) ||
989 g1->store_shapes(&trn) || g2->store_shapes(&trn))))
996 collector.prepare_operation();
997 scan_it.init(&collector);
999 if (spatial_rel == SP_EQUALS_FUNC ||
1000 spatial_rel == SP_WITHIN_FUNC ||
1001 spatial_rel == SP_CONTAINS_FUNC)
1003 result= (g1->get_class_info()->m_type_id == g1->get_class_info()->m_type_id) &&
1005 if (spatial_rel == SP_EQUALS_FUNC ||
1010 if (func.alloc_states())
1013 result= func.find_function(scan_it) ^ mask;
1019 DBUG_RETURN(result);
1023 Item_func_spatial_operation::~Item_func_spatial_operation()
1028 String *Item_func_spatial_operation::val_str(
String *str_value)
1030 DBUG_ENTER(
"Item_func_spatial_operation::val_str");
1031 DBUG_ASSERT(fixed == 1);
1032 String *res1= args[0]->val_str(&tmp_value1);
1033 String *res2= args[1]->val_str(&tmp_value2);
1034 Geometry_buffer buffer1, buffer2;
1039 if (func.reserve_op_buffer(1))
1041 func.add_operation(spatial_op, 2);
1044 if (args[0]->null_value || args[1]->null_value ||
1045 !(g1= Geometry::construct(&buffer1, res1)) ||
1046 !(g2= Geometry::construct(&buffer2, res2)) ||
1047 g1->store_shapes(&trn) || g2->store_shapes(&trn))
1054 collector.prepare_operation();
1055 if (func.alloc_states())
1058 operation.init(&func);
1060 if (operation.count_all(&collector) ||
1061 operation.get_result(&res_receiver))
1065 str_value->set_charset(&my_charset_bin);
1066 if (str_value->reserve(SRID_SIZE, 512))
1068 str_value->length(0);
1069 str_value->q_append(srid);
1071 if (!Geometry::create_from_opresult(&buffer1, str_value, res_receiver))
1079 res_receiver.reset();
1080 DBUG_RETURN(null_value ? 0 : str_value);
1084 const char *Item_func_spatial_operation::func_name()
const
1086 switch (spatial_op) {
1087 case Gcalc_function::op_intersection:
1088 return "st_intersection";
1089 case Gcalc_function::op_difference:
1090 return "st_difference";
1091 case Gcalc_function::op_union:
1093 case Gcalc_function::op_symdifference:
1094 return "st_symdifference";
1097 return "sp_unknown";
1102 static const int SINUSES_CALCULATED= 32;
1103 static double n_sinus[SINUSES_CALCULATED+1]=
1106 0.04906767432741802,
1141 static void get_n_sincos(
int n,
double *sinus,
double *cosinus)
1143 DBUG_ASSERT(n > 0 && n < SINUSES_CALCULATED*2+1);
1144 if (n < (SINUSES_CALCULATED + 1))
1147 *cosinus= n_sinus[SINUSES_CALCULATED -
n];
1151 n-= SINUSES_CALCULATED;
1152 *sinus= n_sinus[SINUSES_CALCULATED -
n];
1153 *cosinus= -n_sinus[
n];
1161 double ax,
double ay)
1163 double n_sin, n_cos;
1165 for (
int n = 1; n < (SINUSES_CALCULATED * 2 - 1); n++)
1167 get_n_sincos(n, &n_sin, &n_cos);
1168 x_n= ax * n_cos - ay * n_sin;
1169 y_n= ax * n_sin + ay * n_cos;
1170 if (trn->add_point(st, x_n + x, y_n + y))
1180 double ax,
double ay,
double bx,
double by,
double d,
1183 double ab= ax * bx + ay * by;
1184 double cosab= ab / (d * d) + GIS_ZERO;
1185 double n_sin, n_cos;
1192 get_n_sincos(n++, &n_sin, &n_cos);
1196 x_n= ax * n_cos - ay * n_sin;
1197 y_n= ax * n_sin + ay * n_cos;
1198 if (trn->add_point(st, x_n + x, y_n + y))
1211 static void calculate_perpendicular(
1212 double x1,
double y1,
double x2,
double y2,
double d,
1213 double *ex,
double *ey,
1214 double *px,
double *py)
1219 q= d / sqrt((*ex) * (*ex) + (*ey) * (*ey));
1228 return add_point_buffer(st, x, y);
1233 double x3,
double y3,
bool round_p1,
bool round_p2)
1235 DBUG_PRINT(
"info", (
"Item_func_buffer::Transporter::add_edge_buffer: "
1236 "(%g,%g)(%g,%g)(%g,%g) p1=%d p2=%d",
1237 x1, y1, x2, y2, x3, y3, (
int) round_p1, (
int) round_p2));
1240 double e1_x, e1_y, e2_x, e2_y, p1_x, p1_y, p2_x, p2_y;
1244 bool empty_gap1, empty_gap2;
1248 if (trn.start_simple_poly(&dummy))
1251 calculate_perpendicular(x1, y1, x2, y2, m_d, &e1_x, &e1_y, &p1_x, &p1_y);
1252 calculate_perpendicular(x3, y3, x2, y2, m_d, &e2_x, &e2_y, &p2_x, &p2_y);
1254 e1e2= e1_x * e2_y - e2_x * e1_y;
1260 x_n= x2 + p2_x * cos1 - p2_y * sin1;
1261 y_n= y2 + p2_y * cos1 + p2_x * sin1;
1262 if (fill_gap(&trn, &dummy, x2, y2, -p1_x,-p1_y, p2_x,p2_y, m_d, &empty_gap1) ||
1263 trn.add_point(&dummy, x2 + p2_x, y2 + p2_y) ||
1264 trn.add_point(&dummy, x_n, y_n))
1269 x_n= x2 - p2_x * cos1 - p2_y * sin1;
1270 y_n= y2 - p2_y * cos1 + p2_x * sin1;
1271 if (trn.add_point(&dummy, x_n, y_n) ||
1272 trn.add_point(&dummy, x2 - p2_x, y2 - p2_y) ||
1273 fill_gap(&trn, &dummy, x2, y2, -p2_x, -p2_y, p1_x, p1_y, m_d, &empty_gap2))
1277 if ((!empty_gap2 && trn.add_point(&dummy, x2 + p1_x, y2 + p1_y)) ||
1278 trn.add_point(&dummy, x1 + p1_x, y1 + p1_y))
1281 if (round_p1 && fill_half_circle(&trn, &dummy, x1, y1, p1_x, p1_y))
1284 if (trn.add_point(&dummy, x1 - p1_x, y1 - p1_y) ||
1285 (!empty_gap1 && trn.add_point(&dummy, x2 - p1_x, y2 - p1_y)))
1287 return trn.complete_simple_poly(&dummy);
1295 double e1_x, e1_y, p1_x, p1_y;
1298 if (trn.start_simple_poly(&dummy))
1301 calculate_perpendicular(x1, y1, x2, y2, m_d, &e1_x, &e1_y, &p1_x, &p1_y);
1303 if (trn.add_point(&dummy, x1 + p1_x, y1 + p1_y) ||
1304 trn.add_point(&dummy, x1 - p1_x, y1 - p1_y) ||
1305 trn.add_point(&dummy, x2 - p1_x, y2 - p1_y) ||
1306 fill_half_circle(&trn, &dummy, x2, y2, -p1_x, -p1_y) ||
1307 trn.add_point(&dummy, x2 + p1_x, y2 + p1_y))
1309 return trn.complete_simple_poly(&dummy);
1320 if (trn.start_simple_poly(&dummy))
1322 if (trn.add_point(&dummy, x - m_d, y) ||
1323 fill_half_circle(&trn, &dummy, x, y, -m_d, 0.0) ||
1324 trn.add_point(&dummy, x + m_d, y) ||
1325 fill_half_circle(&trn, &dummy, x, y, m_d, 0.0))
1327 return trn.complete_simple_poly(&dummy);
1334 if (m_fn->reserve_op_buffer(2))
1336 st->m_last_shape_pos= m_fn->get_next_operation_pos();
1337 m_fn->add_operation(m_buffer_op, 0);
1347 if (m_fn->reserve_op_buffer(2))
1349 st->m_last_shape_pos= m_fn->get_next_operation_pos();
1350 m_fn->add_operation(m_buffer_op, 0);
1351 return Gcalc_operation_transporter::start_poly(st);
1357 if (Gcalc_operation_transporter::complete_poly(st))
1359 m_fn->add_operands_to_op(st->m_last_shape_pos, st->m_nshapes);
1367 return Gcalc_operation_transporter::start_ring(st);
1374 if (m_npoints && x == x2 && y == y2)
1384 else if (m_npoints == 2)
1389 else if (add_edge_buffer(st, x, y, (m_npoints == 3) && line_started(),
false))
1397 return line_started() ? 0 : Gcalc_operation_transporter::add_point(st, x, y);
1407 if (add_point_buffer(st, x2, y2))
1410 else if (m_npoints == 2)
1412 if (add_edge_buffer(st, x1, y1,
true,
true))
1415 else if (line_started())
1417 if (add_last_edge_buffer(st))
1426 if (x2 != x00 || y2 != y00)
1428 if (add_edge_buffer(st, x00, y00,
false,
false))
1435 if (add_edge_buffer(st, x01, y01,
false,
false))
1448 int_complete_line();
1450 m_fn->add_operands_to_op(st->m_last_shape_pos, st->m_nshapes);
1457 return complete(st) ||
1458 Gcalc_operation_transporter::complete_ring(st);
1466 st->m_last_shape_pos= m_fn->get_next_operation_pos();
1467 return Gcalc_operation_transporter::start_collection(st, n_objects);
1473 Gcalc_operation_transporter::complete_collection(st);
1474 m_fn->set_operands_to_op(st->m_last_shape_pos, st->m_nshapes);
1491 if (st_item->m_nshapes)
1492 st_collection->m_nshapes++;
1499 DBUG_ENTER(
"Item_func_buffer::val_str");
1500 DBUG_ASSERT(fixed == 1);
1501 String *obj= args[0]->val_str(&tmp_value);
1502 double dist= args[1]->val_real();
1503 Geometry_buffer buffer;
1506 String *str_result= NULL;
1511 if (args[0]->null_value || args[1]->null_value ||
1512 !(g= Geometry::construct(&buffer, obj)))
1520 if (fabs(dist) < GIS_ZERO)
1527 if (g->store_shapes(&trn, &st))
1534 if (st.m_nshapes == 0)
1542 str_value->length(0);
1546 collector.prepare_operation();
1547 if (func.alloc_states())
1549 operation.init(&func);
1551 if (operation.count_all(&collector) ||
1552 operation.get_result(&res_receiver))
1555 str_value->set_charset(&my_charset_bin);
1556 if (str_value->reserve(SRID_SIZE, 512))
1558 str_value->length(0);
1559 str_value->q_append(srid);
1561 if (!Geometry::create_from_opresult(&buffer, str_value, res_receiver))
1565 str_result= str_value;
1569 res_receiver.reset();
1570 DBUG_RETURN(str_result);
1574 longlong Item_func_isempty::val_int()
1576 DBUG_ASSERT(fixed == 1);
1578 String *swkb= args[0]->val_str(&tmp);
1579 Geometry_buffer buffer;
1581 null_value= args[0]->null_value ||
1582 !(Geometry::construct(&buffer, swkb));
1583 return null_value ? 1 : 0;
1587 longlong Item_func_issimple::val_int()
1589 String *swkb= args[0]->val_str(&tmp);
1590 Geometry_buffer buffer;
1595 DBUG_ENTER(
"Item_func_issimple::val_int");
1596 DBUG_ASSERT(fixed == 1);
1598 if ((null_value= args[0]->null_value) ||
1599 !(g= Geometry::construct(&buffer, swkb)))
1603 if (g->get_class_info()->m_type_id == Geometry::wkb_point)
1606 if (g->store_shapes(&trn))
1613 collector.prepare_operation();
1614 scan_it.init(&collector);
1616 while (scan_it.more_points())
1621 if (scan_it.get_event() == scev_intersection)
1631 DBUG_RETURN(result);
1639 longlong Item_func_isclosed::val_int()
1641 DBUG_ASSERT(fixed == 1);
1643 String *swkb= args[0]->val_str(&tmp);
1644 Geometry_buffer buffer;
1648 null_value= (!swkb ||
1649 args[0]->null_value ||
1651 Geometry::construct(&buffer, swkb)) ||
1652 geom->is_closed(&isclosed));
1654 return (longlong) isclosed;
1662 longlong Item_func_dimension::val_int()
1664 DBUG_ASSERT(fixed == 1);
1666 String *swkb= args[0]->val_str(&value);
1667 Geometry_buffer buffer;
1670 null_value= (!swkb ||
1671 args[0]->null_value ||
1672 !(geom= Geometry::construct(&buffer, swkb)) ||
1673 geom->dimension(&dim));
1674 return (longlong) dim;
1678 longlong Item_func_numinteriorring::val_int()
1680 DBUG_ASSERT(fixed == 1);
1682 String *swkb= args[0]->val_str(&value);
1683 Geometry_buffer buffer;
1686 null_value= (!swkb ||
1687 !(geom= Geometry::construct(&buffer, swkb)) ||
1688 geom->num_interior_ring(&num));
1689 return (longlong) num;
1693 longlong Item_func_numgeometries::val_int()
1695 DBUG_ASSERT(fixed == 1);
1697 String *swkb= args[0]->val_str(&value);
1698 Geometry_buffer buffer;
1701 null_value= (!swkb ||
1702 !(geom= Geometry::construct(&buffer, swkb)) ||
1703 geom->num_geometries(&num));
1704 return (longlong) num;
1708 longlong Item_func_numpoints::val_int()
1710 DBUG_ASSERT(fixed == 1);
1712 String *swkb= args[0]->val_str(&value);
1713 Geometry_buffer buffer;
1716 null_value= (!swkb ||
1717 args[0]->null_value ||
1718 !(geom= Geometry::construct(&buffer, swkb)) ||
1719 geom->num_points(&num));
1720 return (longlong) num;
1724 double Item_func_x::val_real()
1726 DBUG_ASSERT(fixed == 1);
1728 String *swkb= args[0]->val_str(&value);
1729 Geometry_buffer buffer;
1732 null_value= (!swkb ||
1733 !(geom= Geometry::construct(&buffer, swkb)) ||
1739 double Item_func_y::val_real()
1741 DBUG_ASSERT(fixed == 1);
1743 String *swkb= args[0]->val_str(&value);
1744 Geometry_buffer buffer;
1747 null_value= (!swkb ||
1748 !(geom= Geometry::construct(&buffer,
1749 swkb->ptr(), swkb->length())) ||
1755 double Item_func_area::val_real()
1757 DBUG_ASSERT(fixed == 1);
1759 String *swkb= args[0]->val_str(&value);
1760 Geometry_buffer buffer;
1763 null_value= (!swkb ||
1764 !(geom= Geometry::construct(&buffer, swkb)) ||
1769 double Item_func_glength::val_real()
1771 DBUG_ASSERT(fixed == 1);
1773 String *swkb= args[0]->val_str(&value);
1774 Geometry_buffer buffer;
1777 null_value= (!swkb ||
1778 !(geom= Geometry::construct(&buffer, swkb)) ||
1779 geom->geom_length(&res));
1783 longlong Item_func_srid::val_int()
1785 DBUG_ASSERT(fixed == 1);
1786 String *swkb= args[0]->val_str(&value);
1787 Geometry_buffer buffer;
1789 null_value= (!swkb ||
1790 !Geometry::construct(&buffer, swkb));
1794 return (longlong) (uint4korr(swkb->ptr()));
1798 double Item_func_distance::val_real()
1800 bool cur_point_edge;
1803 Gcalc_scan_events ev;
1804 double t, distance, cur_distance;
1805 double ex, ey, vx, vy, e_sqrlen;
1809 DBUG_ENTER(
"Item_func_distance::val_real");
1810 DBUG_ASSERT(fixed == 1);
1811 String *res1= args[0]->val_str(&tmp_value1);
1812 String *res2= args[1]->val_str(&tmp_value2);
1813 Geometry_buffer buffer1, buffer2;
1816 if ((null_value= (args[0]->null_value || args[1]->null_value ||
1817 !(g1= Geometry::construct(&buffer1, res1)) ||
1818 !(g2= Geometry::construct(&buffer2, res2)))))
1821 if ((g1->get_class_info()->m_type_id == Geometry::wkb_point) &&
1822 (g2->get_class_info()->m_type_id == Geometry::wkb_point))
1825 if (((Gis_point *) g1)->get_xy(&p1) ||
1826 ((Gis_point *) g2)->get_xy(&p2))
1830 DBUG_RETURN(sqrt(ex * ex + ey * ey));
1833 if (func.reserve_op_buffer(1))
1835 func.add_operation(Gcalc_function::op_intersection, 2);
1837 if (g1->store_shapes(&trn))
1839 obj2_si= func.get_nshapes();
1840 if (g2->store_shapes(&trn) || func.alloc_states())
1847 collector.prepare_operation();
1848 scan_it.init(&collector);
1851 while (scan_it.more_points())
1855 evpos= scan_it.get_event_position();
1856 ev= scan_it.get_event();
1857 cur_point= evpos->pi;
1863 if (ev == scev_intersection)
1865 if ((evpos->get_next()->pi->shape >= obj2_si) !=
1866 (cur_point->shape >= obj2_si))
1879 if (ev & (scev_point | scev_end | scev_two_ends))
1880 goto count_distance;
1887 DBUG_ASSERT(ev & (scev_thread | scev_two_threads | scev_single_point));
1892 gcalc_shape_info si= pit.point()->get_shape();
1893 if ((func.get_shape_kind(si) == Gcalc_function::shape_polygon))
1894 func.invert_state(si);
1896 func.invert_state(evpos->get_shape());
1906 if (cur_point->shape >= obj2_si)
1908 cur_point_edge= !cur_point->is_bottom();
1910 for (dist_point= collector.get_first(); dist_point; dist_point= dist_point->get_next())
1913 if (dist_point->shape < obj2_si)
1917 if (dist_point->left)
1919 t= count_edge_t(dist_point, dist_point->left, cur_point,
1920 ex, ey, vx, vy, e_sqrlen);
1921 if ((t>0.0) && (t<1.0))
1923 cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
1924 if (distance > cur_distance)
1925 distance= cur_distance;
1930 t= count_edge_t(cur_point, cur_point->left, dist_point,
1931 ex, ey, vx, vy, e_sqrlen);
1932 if ((t>0.0) && (t<1.0))
1934 cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
1935 if (distance > cur_distance)
1936 distance= cur_distance;
1939 cur_distance= distance_points(cur_point, dist_point);
1940 if (distance > cur_distance)
1941 distance= cur_distance;
1948 DBUG_RETURN(distance);
1956 longlong Item_func_gis_debug::val_int()
1958 int val= args[0]->val_int();
1959 if (!args[0]->null_value)
1960 current_thd->set_gis_debug(val);
1961 return current_thd->get_gis_debug();