#At file:///home/hf/work/mysql_common/gis-bugfix/ based on revid:holyfoot@stripped
2663 Alexey Botchkov 2009-11-24
Bug#46372 buffer of linestring returns multipolygon in certain cases
mistake in the algorithm - dx_dy parameter should be just dx if
dy is 0.
per-file comments:
sql/gcalc_slicescan.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
GET_DX_DY fixed
sql/gcalc_slicescan.h
Bug#46372 buffer of linestring returns multipolygon in certain cases
some debugging features added
sql/item_geofunc.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
debugging code added
modified:
sql/gcalc_slicescan.cc
sql/gcalc_slicescan.h
sql/item_geofunc.cc
=== modified file 'sql/gcalc_slicescan.cc'
--- a/sql/gcalc_slicescan.cc 2009-05-12 15:19:33 +0000
+++ b/sql/gcalc_slicescan.cc 2009-11-24 16:35:34 +0000
@@ -4,6 +4,79 @@
#include "gcalc_slicescan.h"
+#ifdef GCALC_DBUG
+void gcalc_dbug_env_struct::start_line()
+{
+ if (recfile)
+ {
+ fprintf(recfile, "LINESTRING(");
+ first_point= 1;
+ }
+}
+
+
+void gcalc_dbug_env_struct::start_ring()
+{
+ if (recfile)
+ {
+ fprintf(recfile, "RING(");
+ first_point= 1;
+ }
+}
+
+
+void gcalc_dbug_env_struct::complete()
+{
+ if (recfile)
+ {
+ fprintf(recfile, ")\n");
+ fflush(recfile);
+ }
+}
+
+
+void gcalc_dbug_env_struct::add_point(double x, double y)
+{
+ if (recfile)
+ {
+ if (!first_point)
+ fprintf(recfile, ", ");
+ else
+ first_point=0;
+ fprintf(recfile, "%.15g %.15g", x, y);
+ }
+}
+
+
+void gcalc_dbug_env_struct::start_newfile(const char *filename)
+{
+ recfile= fopen(filename, "w");
+}
+
+
+void gcalc_dbug_env_struct::start_append(const char *filename)
+{
+ recfile= fopen(filename, "a");
+}
+
+
+void gcalc_dbug_env_struct::stop_recording()
+{
+ fclose(recfile);
+ recfile= NULL;
+}
+
+gcalc_dbug_env_struct::~gcalc_dbug_env_struct()
+{
+ if (recfile)
+ fclose(recfile);
+}
+
+static gcalc_dbug_env_struct gcalc_dbug_usual_env;
+gcalc_dbug_env_struct *gcalc_dbug_cur_env= &gcalc_dbug_usual_env;
+
+#endif /*GCLAC_DBUG*/
+
#define PH_DATA_OFFSET 8
#define coord_to_float(d) ((double) d)
@@ -167,8 +240,9 @@ inline int GET_DX_DY(double *dxdy,
const gcalc_heap::info *p0, const gcalc_heap::info *p1)
{
double dy= p1->y - p0->y;
+ *dxdy= p1->x - p0->x;
return (dy == 0.0) ||
- (*dxdy= (p1->x - p0->x)/dy)>DBL_MAX ||
+ (*dxdy/= dy)>DBL_MAX ||
(*dxdy)<-DBL_MAX;
}
=== modified file 'sql/gcalc_slicescan.h'
--- a/sql/gcalc_slicescan.h 2009-05-13 07:03:17 +0000
+++ b/sql/gcalc_slicescan.h 2009-11-24 16:35:34 +0000
@@ -1,6 +1,41 @@
#ifndef gcalc_slicescan_h
#define gcalc_slicescan_h
+/* #define GCALC_DBUG */
+
+#ifdef GCALC_DBUG
+class gcalc_dbug_env_struct
+{
+ FILE *recfile;
+ bool first_point;
+public:
+ gcalc_dbug_env_struct() : recfile(NULL) {}
+ virtual void start_ring();
+ virtual void start_line();
+ virtual void add_point(double x, double y);
+ virtual void complete();
+
+ void start_newfile(const char *filename);
+ void start_append(const char *filename);
+ void stop_recording();
+ virtual ~gcalc_dbug_env_struct();
+};
+
+extern gcalc_dbug_env_struct *gcalc_dbug_cur_env;
+#define GCALC_DBUG_START_RING gcalc_dbug_cur_env->start_ring()
+#define GCALC_DBUG_START_LINE gcalc_dbug_cur_env->start_line()
+#define GCALC_DBUG_ADD_POINT(X,Y) gcalc_dbug_cur_env->add_point(X,Y)
+#define GCALC_DBUG_COMPLETE gcalc_dbug_cur_env->complete()
+#define GCALC_DBUG_STARTFILE(FILENAME) gcalc_dbug_cur_env->start_newfile(FILENAME)
+#define GCALC_DBUG_STOP gcalc_dbug_cur_env->stop_recording()
+#else
+#define GCALC_DBUG_START_RING
+#define GCALC_DBUG_ADD_POINT(X,Y)
+#define GCALC_DBUG_COMPLETE
+#define GCALC_DBUG_STARTFILE(FILENAME)
+#define GCALC_DBUG_STOP
+#endif /*GCLAC_DBUG*/
+
class gcalc_dyn_list
{
public:
@@ -137,6 +172,7 @@ public:
m_shape_info= info;
m_first= m_prev= NULL;
m_line_flag= TRUE;
+ GCALC_DBUG_START_LINE;
}
void start_ring(gcalc_shape_info info)
@@ -144,6 +180,7 @@ public:
m_shape_info= info;
m_first= m_prev= NULL;
m_line_flag= FALSE;
+ GCALC_DBUG_START_RING;
}
int add_point(double x, double y)
@@ -162,6 +199,7 @@ public:
else
m_first= point;
m_prev= point;
+ GCALC_DBUG_ADD_POINT(x, y);
return 0;
}
@@ -181,6 +219,7 @@ public:
m_prev->left= m_first;
}
}
+ GCALC_DBUG_COMPLETE;
}
};
=== modified file 'sql/item_geofunc.cc'
--- a/sql/item_geofunc.cc 2009-11-18 13:40:52 +0000
+++ b/sql/item_geofunc.cc 2009-11-24 16:35:34 +0000
@@ -885,6 +885,12 @@ static int fill_gap(gcalc_shape_transpor
}
+/*
+ Calculates the vector (p2,p1) and
+ negatively orthogonal to it with the length of d.
+ The result is (ex,ey) - the vector, (px,py) - the orthogonal.
+*/
+
static void calculate_perpendicular(const gcalc_heap::info *p1,
const gcalc_heap::info *p2, double d,
double *ex, double *ey,
@@ -977,7 +983,7 @@ int Item_func_buffer::add_last_edge_buff
if (trn.add_point(p1->x + p1_x, p1->y + p1_y) ||
trn.add_point(p1->x - p1_x, p1->y - p1_y) ||
trn.add_point(p2->x - p1_x, p2->y - p1_y) ||
- fill_half_circle(&trn, p2->x, p2->y, p1_x, p1_y) ||
+ fill_half_circle(&trn, p2->x, p2->y, -p1_x, -p1_y) ||
trn.add_point(p2->x + p1_x, p2->y + p1_y))
return 1;
trn.complete();
@@ -1107,6 +1113,7 @@ String *Item_func_buffer::val_str(String
func.add_operation((dist > 0.0) ? gcalc_function::op_union :
gcalc_function::op_difference, 2);
+ GCALC_DBUG_STARTFILE("/home/hf/linebuffer");
if (g->store_shapes(&collector, &func))
goto mem_error;
@@ -1141,6 +1148,7 @@ String *Item_func_buffer::val_str(String
break;
dist_point= dist_point->get_next();
}
+ GCALC_DBUG_STOP;
func.add_operands_to_op(union_pos, n_operands);
collector.prepare_operation();
if (func.alloc_states())
Attachment: [text/bzr-bundle] bzr/holyfoot@mysql.com-20091124163534-hywby4go5483txcn.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (holyfoot:2663) Bug#46372 | Alexey Botchkov | 25 Nov |