[Commits] Rev 3607: 'lighter' ST_ConvexHull implemented. in file:///home/hf/wmar/5.3-gis/

holyfoot at askmonty.org holyfoot at askmonty.org
Fri Nov 30 15:18:26 EET 2012


At file:///home/hf/wmar/5.3-gis/

------------------------------------------------------------
revno: 3607
revision-id: holyfoot at askmonty.org-20121130131015-xwhrq2xh2o2i3w0k
parent: holyfoot at askmonty.org-20121130123942-pwg3uk90ycwahu4b
committer: Alexey Botchkov <holyfoot at askmonty.org>
branch nick: 5.3-gis
timestamp: Fri 2012-11-30 17:10:15 +0400
message:
  'lighter' ST_ConvexHull implemented.
-------------- next part --------------
=== modified file 'sql/item_geofunc.cc'
--- a/sql/item_geofunc.cc	2012-11-30 12:39:42 +0000
+++ b/sql/item_geofunc.cc	2012-11-30 13:10:15 +0000
@@ -396,6 +396,116 @@ int Item_func_convexhull::add_node_to_li
 }
 
 
+#ifndef HEAVY_CONVEX_HULL
+String *Item_func_convexhull::val_str(String *str_value)
+{
+  Geometry_buffer buffer;
+  Geometry *geom= NULL;
+  MBR mbr;
+  const char *c_end;
+  Gcalc_operation_transporter trn(&func, &collector);
+  uint32 srid= 0;
+  ch_node *left_first, *left_cur, *right_first, *right_cur;
+  Gcalc_heap::Info *cur_pi;
+  
+  DBUG_ENTER("Item_func_convexhull::val_str");
+  DBUG_ASSERT(fixed == 1);
+  String *swkb= args[0]->val_str(&tmp_value);
+
+  if ((null_value=
+       args[0]->null_value ||
+       !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))
+    DBUG_RETURN(0);
+  
+  geom->get_mbr(&mbr, &c_end);
+  collector.set_extent(mbr.xmin, mbr.xmax, mbr.ymin, mbr.ymax);
+  if ((null_value= geom->store_shapes(&trn)))
+  {
+    str_value= 0;
+    goto mem_error;
+  }
+
+  collector.prepare_operation();
+  if (!(cur_pi= collector.get_first()))
+    goto build_result; /* An EMPTY GEOMETRY */
+
+  if (!cur_pi->get_next())
+  {
+    /* Single point. */
+    if (res_receiver.single_point(cur_pi->x, cur_pi->y))
+      goto mem_error;
+    goto build_result;
+  }
+
+  left_cur= left_first= new_ch_node();
+  right_cur= right_first= new_ch_node();
+  right_first->prev= left_first->prev= 0;
+  right_first->pi= left_first->pi= cur_pi;
+
+  while ((cur_pi= cur_pi->get_next()))
+  {
+    /* Handle left part of the hull, then the right part. */
+    if (add_node_to_line(&left_cur, 1, cur_pi))
+      goto mem_error;
+    if (add_node_to_line(&right_cur, -1, cur_pi))
+      goto mem_error;
+  }
+
+  left_cur->next= 0;
+  if (left_first->get_next()->get_next() == NULL &&
+      right_cur->prev->prev == NULL)
+  {
+    /* We only have 2 nodes in the result, so we create a polyline. */
+    if (res_receiver.start_shape(Gcalc_function::shape_line) ||
+        res_receiver.add_point(left_first->pi->x, left_first->pi->y) ||
+        res_receiver.add_point(left_cur->pi->x, left_cur->pi->y) ||
+        res_receiver.complete_shape())
+
+      goto mem_error;
+
+    goto build_result;
+  }
+
+  if (res_receiver.start_shape(Gcalc_function::shape_polygon))
+    goto mem_error;
+
+  while (left_first)
+  {
+    if (res_receiver.add_point(left_first->pi->x, left_first->pi->y))
+      goto mem_error;
+    left_first= left_first->get_next();
+  }
+
+  /* Skip last point in the right part as it coincides */
+  /* with the last one in the left.                    */
+  right_cur= right_cur->prev;
+  while (right_cur->prev)
+  {
+    if (res_receiver.add_point(right_cur->pi->x, right_cur->pi->y))
+      goto mem_error;
+    right_cur= right_cur->prev;
+  }
+  res_receiver.complete_shape();
+
+build_result:
+  str_value->set_charset(&my_charset_bin);
+  if (str_value->reserve(SRID_SIZE, 512))
+    goto mem_error;
+  str_value->length(0);
+  str_value->q_append(srid);
+
+  if (!Geometry::create_from_opresult(&buffer, str_value, res_receiver))
+    goto mem_error;
+
+mem_error:
+  collector.reset();
+  func.reset();
+  res_receiver.reset();
+  res_heap.reset();
+  DBUG_RETURN(str_value);
+}
+
+#else /*HEAVY_CONVEX_HULL*/
 String *Item_func_convexhull::val_str(String *str_value)
 {
   Geometry_buffer buffer;
@@ -540,6 +650,7 @@ skip_point:;
   res_heap.reset();
   DBUG_RETURN(str_value);
 }
+#endif /*HEAVY_CONVEX_HULL*/
 
 
 /*

=== modified file 'sql/item_geofunc.h'
--- a/sql/item_geofunc.h	2012-11-23 13:48:57 +0000
+++ b/sql/item_geofunc.h	2012-11-30 13:10:15 +0000
@@ -102,6 +102,7 @@ class Item_func_centroid: public Item_ge
   Field::geometry_type get_geometry_type() const;
 };
 
+// #define HEAVY_CONVEX_HULL
 class Item_func_convexhull: public Item_geometry_func
 {
   class ch_node: public Gcalc_dyn_list::Item
@@ -119,7 +120,9 @@ class Item_func_convexhull: public Item_
 
   Gcalc_result_receiver res_receiver;
   String tmp_value;
+#ifdef HEAVY_CONVEX_HULL
   Gcalc_scan_iterator scan_it;
+#endif /*HEAVY_CONVEX_HULL*/
   ch_node *new_ch_node() { return (ch_node *) res_heap.new_item(); }
   int add_node_to_line(ch_node **p_cur, int dir, const Gcalc_heap::Info *pi);
 public:



More information about the commits mailing list