Fix for bug #804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection

There were actually two bugs. One was when the line that intersects itself
        the intersection point treated as it doesn't belong to the line.
        Second when edges partly coincide, wrong result produced when we try to find their
        intersection.


per-file comments:
  mysql-test/r/gis-precise.result
Fix for bug #804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
        test result updated.

  mysql-test/t/gis-precise.test
Fix for bug #804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
        test case added.

  sql/gcalc_slicescan.cc
Fix for bug #804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
        skip the intersection if it just line that intersects itself.

  sql/gcalc_tools.cc
Fix for bug #804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
        if edges coincide, just pick the first coinciding poing as an intersection.
This commit is contained in:
Alexey Botchkov 2011-07-07 16:59:45 +05:00
parent f3b850a7b5
commit 13f6e1119f
4 changed files with 54 additions and 1 deletions

View file

@ -232,3 +232,29 @@ MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((2 2,2 8,8 8,8 2,2 2),(4 4,4 6,6 6,6 4,4 4))
((2 2,5 2,4 4,2 8,2 2)))'),
MULTIPOLY
MULTIPOLYGON(((2 2,3 2,2 2)),((5 2,0 2,5 2)),((2 2,0 2,1.5 5,2 5,2 2),(1 3,1 4,2 4,2 3,1 3)),((2 2,2 8,8 8,8 2,5 2,2 2),(6 4,4 4,4 6,6 6,6 4)))
SELECT ASTEXT(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
(8 2,1 3,9 0,4 4))'),
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')));
ASTEXT(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
(8 2,1 3,9 0,4 4))'),
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')))
MULTILINESTRING((8 2,1 3,9 0,4 4),(5 0,2 9,8 4,3 7,0 7,3 9,6 4,4 3,3 6,3 5,4 0,6 2),(3 6,1 6,5 2,9 7,6 7,2 5))
SELECT ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
(6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
(7 8,3 1,0 9,6 0,4 8),
(9 3,0 4,5 9,6 4),
(8 2,1 3,9 0,4 4))'),
MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 0,9 3,2 5,3 6,3 2),
(2 5,6 7,9 7,5 2,1 6,3 6))')),
MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((7 7,3 7,3 1,7 8,7 7)),
((3 5,2 4,2 5,3 5)),
((7 7,8 7,3 7,7 7,7 7)),
((0 5,3 5,3 4,1 4,1 3,3 3,3 0,0 0,0 5), (1 1,2 1,2 2,1 2,1 1)))'))));
ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
(6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
32

View file

@ -130,3 +130,24 @@ SELECT ASTEXT(ST_INTERSECTION(
((2 2,9 2,0 2,2 6,2 2)),
((2 2,2 8,8 8,8 2,2 2), (4 4,4 6,6 6,6 4,4 4)),
((9 9,6 8,7 0,9 9)))')));
#bug 804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
SELECT ASTEXT(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
(8 2,1 3,9 0,4 4))'),
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')));
SELECT ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
(6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
(7 8,3 1,0 9,6 0,4 8),
(9 3,0 4,5 9,6 4),
(8 2,1 3,9 0,4 4))'),
MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 0,9 3,2 5,3 6,3 2),
(2 5,6 7,9 7,5 2,1 6,3 6))')),
MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((7 7,3 7,3 1,7 8,7 7)),
((3 5,2 4,2 5,3 5)),
((7 7,8 7,3 7,7 7,7 7)),
((0 5,3 5,3 4,1 4,1 3,3 3,3 0,0 0,0 5), (1 1,2 1,2 2,1 2,1 1)))'))));

View file

@ -510,6 +510,8 @@ int Gcalc_scan_iterator::normal_scan()
}
#define INTERSECTION_ZERO 0.000000000001
int Gcalc_scan_iterator::add_intersection(const point *a, const point *b,
int isc_kind, Gcalc_dyn_list::Item ***p_hook)
{
@ -536,6 +538,9 @@ int Gcalc_scan_iterator::add_intersection(const point *a, const point *b,
{
double dk= a0->dx_dy - b0->dx_dy;
double dy= (b0->x - a0->x)/dk;
if (fabs(dk) < INTERSECTION_ZERO)
dy= 0.0;
isc->y= m_y0 + dy;
isc->x= a0->x + dy*a0->dx_dy;
return 0;

View file

@ -701,7 +701,8 @@ handle_lines_intersection(active_thread *t0, active_thread *t1,
double x, double y)
{
m_fn->invert_state(p0->shape);
m_fn->invert_state(p1->shape);
if (p0->shape != p1->shape)
m_fn->invert_state(p1->shape);
int intersection_state= m_fn->count();
if ((t0->result_range | t1->result_range) == intersection_state)
return 0;