Commit 0249413a authored by Alexey Botchkov's avatar Alexey Botchkov

several bugs fixed here.

        849789  Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis
        849791  Fourth assertion `n > 0 && n < SINUSES_CALCULATED*2+1' in get_n_sincos
        849789  Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis
        848901   Assertion `fabs(cur_isc->x-m_cur_intersection->x) + fabs(cur_isc->y-m_cur_intersection->y) < 0.000000000001' failed in Gcalc_scan_iterator::intersection_scan() in maria-5.3-gis
        
per-file comments:
  mysql-test/r/gis-precise.result
        test result updated.
  mysql-test/r/gis.result
        test result updated.
  sql/gcalc_slicescan.cc
        bugfixes.
  sql/gcalc_slicescan.h
        bugfixes.
  sql/gcalc_tools.cc
        bugfixes.
  sql/gcalc_tools.h
        bugfixes.
  sql/item_geofunc.cc
        bugfixes.
  sql/spatial.cc
        bugfixes.
parent 5a04ac7b
...@@ -189,7 +189,7 @@ st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 ...@@ -189,7 +189,7 @@ st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1
0 0
select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))')); select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'));
st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))')) st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'))
1 0
select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))')); select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'));
st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))')) st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'))
1 1
...@@ -257,7 +257,7 @@ ST_NUMGEOMETRIES((ST_UNION(ST_UNION( ...@@ -257,7 +257,7 @@ ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8), 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), (6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
176 185
SELECT Round(ST_AREA(ST_BUFFER( ST_UNION( SELECT Round(ST_AREA(ST_BUFFER( ST_UNION(
POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'), POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'),
POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6); POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6);
...@@ -338,7 +338,7 @@ MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2, 1 5))') ...@@ -338,7 +338,7 @@ MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2, 1 5))')
ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION( ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION(
MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) , MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) ,
MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2 MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2
280 275
SELECT ST_NUMGEOMETRIES(ST_DIFFERENCE ( SELECT ST_NUMGEOMETRIES(ST_DIFFERENCE (
ST_UNION ( ST_UNION (
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) ) ' ), MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) ) ' ),
...@@ -354,7 +354,7 @@ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 9 , 1 3 , 7 3 , 8 5 ) , ( 5 0 , ...@@ -354,7 +354,7 @@ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 9 , 1 3 , 7 3 , 8 5 ) , ( 5 0 ,
ST_NUMGEOMETRIES(ST_DIFFERENCE ( ST_NUMGEOMETRIES(ST_DIFFERENCE (
ST_UNION ( ST_UNION (
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 )
126 123
SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER ( SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER (
ST_UNION ( ST_UNION (
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) , MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) ,
...@@ -365,7 +365,7 @@ ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER ( ...@@ -365,7 +365,7 @@ ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER (
ST_UNION ( ST_UNION (
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) , MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) ,
MULTILINESTRI MULTILINESTRI
659 653
SELECT ASTEXT(ST_DIFFERENCE ( SELECT ASTEXT(ST_DIFFERENCE (
POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) , POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) ,
ST_UNION ( ST_UNION (
...@@ -416,7 +416,7 @@ ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFR ...@@ -416,7 +416,7 @@ ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFR
NULL NULL
SELECT ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6 , 7 2 , 3 4 ) ' ) , ST_BUFFER ( ST_UNION ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 6 2 , 1 3 , 2 2 , 2 2 ) ) ) ' ) , GEOMETRYFROMTEXT( ' MULTILINESTRING( ( 1 4 , 9 9 , 3 0 , 6 6 ) , ( 3 5 , 1 0 , 5 8 , 6 1 ) , ( 8 9 , 6 1 , 5 1 , 6 2 ) , ( 2 2 , 7 5 , 5 8 , 6 9 , 3 0 ) , ( 8 0 , 8 4 , 6 7 , 5 5 ) ) ' ) ) , NUMPOINTS( EXTERIORRING( POLYGONFROMTEXT( ' POLYGON( ( 0 0 , 2 1 , 8 2 , 0 0 ) ) ' ) ) ) ) ) ) , ST_INTERSECTION ( POLYGONFROMTEXT( ' POLYGON( ( 2 3, 5 7 , 3 7 , 4 1 , 0 5, 2 3 ) ) ' ) , MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 3 , 1 4 , 6 4 , 9 1 , 3 4 , 1 8 ) , ( 9 9 , 0 3 , 1 7 , 9 9 ) ) ' ) ) ) , POLYGONFROMTEXT( ' POLYGON( ( 1 3, 7 2 , 1 5 , 3 8 , 5 0, 1 3) ) ' ) ) ) ; SELECT ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6 , 7 2 , 3 4 ) ' ) , ST_BUFFER ( ST_UNION ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 6 2 , 1 3 , 2 2 , 2 2 ) ) ) ' ) , GEOMETRYFROMTEXT( ' MULTILINESTRING( ( 1 4 , 9 9 , 3 0 , 6 6 ) , ( 3 5 , 1 0 , 5 8 , 6 1 ) , ( 8 9 , 6 1 , 5 1 , 6 2 ) , ( 2 2 , 7 5 , 5 8 , 6 9 , 3 0 ) , ( 8 0 , 8 4 , 6 7 , 5 5 ) ) ' ) ) , NUMPOINTS( EXTERIORRING( POLYGONFROMTEXT( ' POLYGON( ( 0 0 , 2 1 , 8 2 , 0 0 ) ) ' ) ) ) ) ) ) , ST_INTERSECTION ( POLYGONFROMTEXT( ' POLYGON( ( 2 3, 5 7 , 3 7 , 4 1 , 0 5, 2 3 ) ) ' ) , MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 3 , 1 4 , 6 4 , 9 1 , 3 4 , 1 8 ) , ( 9 9 , 0 3 , 1 7 , 9 9 ) ) ' ) ) ) , POLYGONFROMTEXT( ' POLYGON( ( 1 3, 7 2 , 1 5 , 3 8 , 5 0, 1 3) ) ' ) ) ) ;
ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6 ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6
27 25
SELECT ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)))'), geomETRYFROMTEXT(' MULTILINESTRING( ( 5 1 , 3 7 , 6 1 , 7 0 ) , ( 1 6 , 8 5 , 7 5 , 5 6 ) )') )); SELECT ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)))'), geomETRYFROMTEXT(' MULTILINESTRING( ( 5 1 , 3 7 , 6 1 , 7 0 ) , ( 1 6 , 8 5 , 7 5 , 5 6 ) )') ));
ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)) ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5))
MULTIPOINT(7 5,7 5.14285714285714,5.9 5.3,5.8 5.6,3 7) MULTIPOINT(7 5,7 5.14285714285714,5.9 5.3,5.8 5.6,3 7)
...@@ -850,7 +850,7 @@ mbroverlaps ...@@ -850,7 +850,7 @@ mbroverlaps
down,left,right,up down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches mbrtouches
big,center,down,down2,left,left2,right,right2,small,up,up2 down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin mbrwithin
big,center big,center
...@@ -871,7 +871,7 @@ overlaps ...@@ -871,7 +871,7 @@ overlaps
down,left,right,up down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches touches
big,center,down,down2,left,left2,right,right2,small,up,up2 down2,left2,right2,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within within
big,center big,center
......
This diff is collapsed.
...@@ -58,10 +58,13 @@ public: ...@@ -58,10 +58,13 @@ public:
m_free= item; m_free= item;
} }
inline void free_list(Item *list, Item **hook) inline void free_list(Item *list, Item **hook)
{
if (*hook != list)
{ {
*hook= m_free; *hook= m_free;
m_free= list; m_free= list;
} }
}
void free_list(Item *list) void free_list(Item *list)
{ {
...@@ -91,6 +94,79 @@ protected: ...@@ -91,6 +94,79 @@ protected:
} }
}; };
/* Internal Gcalc coordinates to provide the precise calculations */
#define DIG_BASE 1000000000
typedef int32 coord_digit_t;
typedef long long coord2;
#define C_SCALE 1e13
#define COORD_BASE 2
#ifndef DBUG_OFF
//#define GCALC_CHECK_WITH_FLOAT
#define NO_TESTING
#else
#define NO_TESTING
#endif /*DBUG_OFF*/
class Gcalc_internal_coord
{
public:
coord_digit_t *digits;
int sign;
int n_digits;
void set_zero();
int is_zero() const;
#ifdef GCALC_CHECK_WITH_FLOAT
long double get_double() const;
#endif /*GCALC_CHECK_WITH_FLOAT*/
};
class Gcalc_coord1 : public Gcalc_internal_coord
{
coord_digit_t c[COORD_BASE];
public:
void init()
{
n_digits= COORD_BASE;
digits= c;
}
int set_double(double d);
void copy(const Gcalc_coord1 *from);
};
class Gcalc_coord2 : public Gcalc_internal_coord
{
coord_digit_t c[COORD_BASE*2];
public:
void init()
{
n_digits= COORD_BASE*2;
digits= c;
}
};
void gcalc_mul_coord(Gcalc_internal_coord *result,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b);
void gcalc_add_coord(Gcalc_internal_coord *result,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b);
void gcalc_sub_coord(Gcalc_internal_coord *result,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b);
int gcalc_cmp_coord(const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b);
/* Internal coordinates declarations end. */
typedef uint gcalc_shape_info; typedef uint gcalc_shape_info;
/* /*
...@@ -114,27 +190,34 @@ public: ...@@ -114,27 +190,34 @@ public:
Info *left; Info *left;
Info *right; Info *right;
double x,y; double x,y;
Gcalc_coord1 ix, iy;
inline bool is_bottom() const { return !left; } inline bool is_bottom() const { return !left; }
inline Info *get_next() { return (Info *)next; } inline Info *get_next() { return (Info *)next; }
inline const Info *get_next() const { return (const Info *)next; } inline const Info *get_next() const { return (const Info *)next; }
}; };
class Intersection_info : public Gcalc_dyn_list::Item
{
public:
/* Line p1-p2 supposed to intersect line p3-p4 */
const Info *p1;
const Info *p2;
const Info *p3;
const Info *p4;
void calc_xy(double *x, double *y) const;
#ifdef GCALC_CHECK_WITH_FLOAT
void calc_xy_ld(long double *x, long double *y) const;
#endif /*GCALC_CHECK_WITH_FLOAT*/
};
Gcalc_heap(size_t blk_size=8192) : Gcalc_heap(size_t blk_size=8192) :
Gcalc_dyn_list(blk_size, sizeof(Info)), m_hook(&m_first), m_n_points(0) {} Gcalc_dyn_list(blk_size, sizeof(Info)),
Info *new_point_info(double x, double y, gcalc_shape_info shape) m_hook(&m_first), m_n_points(0),
{ m_intersection_hook((Gcalc_dyn_list::Item **) &m_first_intersection)
Info *result= (Info *)new_item(); {}
if (!result) Info *new_point_info(double x, double y, gcalc_shape_info shape);
return NULL; Intersection_info *new_intersection(const Info *p1, const Info *p2,
*m_hook= result; const Info *p3, const Info *p4);
m_hook= &result->next;
m_n_points++;
result->x= x;
result->y= y;
result->shape= shape;
return result;
}
void prepare_operation(); void prepare_operation();
inline bool ready() const { return m_hook == NULL; } inline bool ready() const { return m_hook == NULL; }
Info *get_first() { return (Info *)m_first; } Info *get_first() { return (Info *)m_first; }
...@@ -145,6 +228,8 @@ private: ...@@ -145,6 +228,8 @@ private:
Gcalc_dyn_list::Item *m_first; Gcalc_dyn_list::Item *m_first;
Gcalc_dyn_list::Item **m_hook; Gcalc_dyn_list::Item **m_hook;
int m_n_points; int m_n_points;
Intersection_info *m_first_intersection;
Gcalc_dyn_list::Item **m_intersection_hook;
}; };
...@@ -263,9 +348,13 @@ public: ...@@ -263,9 +348,13 @@ public:
class point : public Gcalc_dyn_list::Item class point : public Gcalc_dyn_list::Item
{ {
public: public:
#ifdef TMP_BLOCK
double x; double x;
double dx_dy; double dx_dy;
int horiz_dir; int horiz_dir;
#endif /*TMP_BLOCK*/
Gcalc_coord1 dx;
Gcalc_coord1 dy;
Gcalc_heap::Info *pi; Gcalc_heap::Info *pi;
Gcalc_heap::Info *next_pi; Gcalc_heap::Info *next_pi;
sc_thread_id thread; sc_thread_id thread;
...@@ -273,22 +362,32 @@ public: ...@@ -273,22 +362,32 @@ public:
const point *intersection_link; const point *intersection_link;
Gcalc_scan_events event; Gcalc_scan_events event;
#ifdef TO_REMOVE #ifdef TO_REMOVE
const point *event_pair;
point *next_link; point *next_link;
#endif /*TO_REMOVE*/ #endif /*TO_REMOVE*/
inline const point *c_get_next() const inline const point *c_get_next() const
{ return (const point *)next; } { return (const point *)next; }
inline bool is_bottom() const { return pi->is_bottom(); } inline bool is_bottom() const { return !next_pi; }
gcalc_shape_info get_shape() const { return pi->shape; } gcalc_shape_info get_shape() const { return pi->shape; }
inline point *get_next() { return (point *)next; } inline point *get_next() { return (point *)next; }
inline const point *get_next() const { return (const point *)next; } inline const point *get_next() const { return (const point *)next; }
/* copies all but 'next' 'x' and 'precursor' */ /* copies all but 'next' 'x' and 'precursor' */
void copy_core(point *from); void copy_core(const point *from);
void copy_all(const point *from);
/* Compare the dx_dy parameters regarding the horiz_dir */ /* Compare the dx_dy parameters regarding the horiz_dir */
/* returns -1 if less, 0 if equal, 1 if bigger */ /* returns -1 if less, 0 if equal, 1 if bigger */
static int compare_dx_dy(int horiz_dir_a, double dx_dy_a, #ifdef TMP_BLOCK
static int cmp_dx_dy(int horiz_dir_a, double dx_dy_a,
int horiz_dir_b, double dx_dy_b); int horiz_dir_b, double dx_dy_b);
#endif /*TMP_BLOCK*/
static int cmp_dx_dy(const Gcalc_coord1 *dx_a,
const Gcalc_coord1 *dy_a,
const Gcalc_coord1 *dx_b,
const Gcalc_coord1 *dy_b);
static int cmp_dx_dy(const Gcalc_heap::Info *p1,
const Gcalc_heap::Info *p2,
const Gcalc_heap::Info *p3,
const Gcalc_heap::Info *p4);
int cmp_dx_dy(const point *p) const; int cmp_dx_dy(const point *p) const;
int simple_event() const int simple_event() const
{ {
...@@ -298,6 +397,9 @@ public: ...@@ -298,6 +397,9 @@ public:
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_print(); void dbug_print();
#endif /*DBUG_OFF*/ #endif /*DBUG_OFF*/
#ifdef GCALC_CHECK_WITH_FLOAT
void calc_x(long double *x, long double y, long double ix) const;
#endif /*GCALC_CHECK_WITH_FLOAT*/
}; };
class intersection : public Gcalc_dyn_list::Item class intersection : public Gcalc_dyn_list::Item
...@@ -306,8 +408,11 @@ public: ...@@ -306,8 +408,11 @@ public:
int n_row; int n_row;
sc_thread_id thread_a; sc_thread_id thread_a;
sc_thread_id thread_b; sc_thread_id thread_b;
#ifdef TMP_BLOCK
double x; double x;
double y; double y;
#endif /*TMP_BLOCK*/
const Gcalc_heap::Intersection_info *ii;
inline intersection *get_next() { return (intersection *)next; } inline intersection *get_next() { return (intersection *)next; }
}; };
...@@ -318,7 +423,15 @@ public: ...@@ -318,7 +423,15 @@ public:
point *event_position; point *event_position;
Gcalc_dyn_list::Item **event_position_hook; Gcalc_dyn_list::Item **event_position_hook;
Gcalc_dyn_list::Item **event_end_hook; Gcalc_dyn_list::Item **event_end_hook;
int intersection_scan;
union
{
const Gcalc_heap::Info *pi;
const Gcalc_heap::Intersection_info *isc;
};
#ifdef TMP_BLOCK
double y; double y;
#endif /*TMP_BLOCK*/
slice_state() : slice(NULL) {} slice_state() : slice(NULL) {}
void clear_event_position() void clear_event_position()
{ {
...@@ -350,10 +463,24 @@ public: ...@@ -350,10 +463,24 @@ public:
{ return (point *) *current_state->event_end_hook; } { return (point *) *current_state->event_end_hook; }
inline const point *get_b_slice() const { return current_state->slice; } inline const point *get_b_slice() const { return current_state->slice; }
inline const point *get_t_slice() const { return next_state->slice; } inline const point *get_t_slice() const { return next_state->slice; }
inline double get_h() const { return current_state->y - next_state->y; } double get_h() const;
inline double get_y() const { return current_state->y; } double get_y() const;
double get_event_x() const;
double get_sp_x(const point *sp) const;
int intersection_step() const { return current_state->intersection_scan; }
const Gcalc_heap::Info *get_cur_pi() const
{
DBUG_ASSERT(!intersection_step());
return current_state->pi;
}
const Gcalc_heap::Intersection_info *get_cur_ii() const
{
DBUG_ASSERT(intersection_step());
return current_state->isc;
}
private: private:
Gcalc_heap *m_heap;
Gcalc_heap::Info *m_cur_pi; Gcalc_heap::Info *m_cur_pi;
slice_state state0, state1, state_s; slice_state state0, state1, state_s;
slice_state *current_state; slice_state *current_state;
...@@ -382,7 +509,10 @@ private: ...@@ -382,7 +509,10 @@ private:
} }
point *new_slice_point() point *new_slice_point()
{ {
return (point *)new_item(); point *new_point= (point *)new_item();
new_point->dx.init();
new_point->dy.init();
return new_point;
} }
point *new_slice(point *example); point *new_slice(point *example);
int arrange_event(); int arrange_event();
...@@ -450,7 +580,6 @@ public: ...@@ -450,7 +580,6 @@ public:
inline const Gcalc_scan_iterator::point *point() const { return sp; } inline const Gcalc_scan_iterator::point *point() const { return sp; }
inline const Gcalc_heap::Info *get_pi() const { return sp->pi; } inline const Gcalc_heap::Info *get_pi() const { return sp->pi; }
inline gcalc_shape_info get_shape() const { return sp->get_shape(); } inline gcalc_shape_info get_shape() const { return sp->get_shape(); }
inline double get_x() const { return sp->x; }
inline void restart(const Gcalc_scan_iterator *scan_i) inline void restart(const Gcalc_scan_iterator *scan_i)
{ sp= scan_i->get_b_slice(); } { sp= scan_i->get_b_slice(); }
}; };
......
This diff is collapsed.
...@@ -206,26 +206,37 @@ public: ...@@ -206,26 +206,37 @@ public:
int get_result(Gcalc_result_receiver *storage); int get_result(Gcalc_result_receiver *storage);
void reset(); void reset();
#ifndef DBUG_OFF
int n_res_points;
#endif /*DBUG_OFF*/
class res_point : public Gcalc_dyn_list::Item class res_point : public Gcalc_dyn_list::Item
{ {
public: public:
bool intersection_point; int intersection_point;
double x,y;
res_point *up;
res_point *down;
res_point *glue;
Gcalc_function::shape_type type;
union union
{ {
const Gcalc_heap::Info *pi; const Gcalc_heap::Info *pi;
const Gcalc_heap::Intersection_info *ii;
res_point *first_poly_node; res_point *first_poly_node;
}; };
#ifdef TMP_BLOCK
union union
{ {
#endif /*TMP_BLOCK*/
res_point *outer_poly; res_point *outer_poly;
uint32 poly_position; uint32 poly_position;
#ifdef TMP_BLOCK
}; };
#endif /*TMP_BLOCK*/
res_point *up;
res_point *down;
res_point *glue;
Gcalc_function::shape_type type;
Gcalc_dyn_list::Item **prev_hook; Gcalc_dyn_list::Item **prev_hook;
#ifndef DBUG_OFF
int point_n;
#endif /*DBUG_OFF*/
void set(const Gcalc_scan_iterator *si);
res_point *get_next() { return (res_point *)next; } res_point *get_next() { return (res_point *)next; }
}; };
...@@ -233,9 +244,9 @@ public: ...@@ -233,9 +244,9 @@ public:
{ {
public: public:
res_point *rp; res_point *rp;
int horiz_dir;
double dx_dy;
res_point *thread_start; res_point *thread_start;
const Gcalc_heap::Info *p1, *p2;
res_point *enabled() { return rp; } res_point *enabled() { return rp; }
active_thread *get_next() { return (active_thread *)next; } active_thread *get_next() { return (active_thread *)next; }
}; };
...@@ -273,33 +284,9 @@ public: ...@@ -273,33 +284,9 @@ public:
line *new_line() { return (line *) new_item(); } line *new_line() { return (line *) new_item(); }
poly_border *new_poly_border() { return (poly_border *) new_item(); } poly_border *new_poly_border() { return (poly_border *) new_item(); }
int add_line(int incoming, active_thread *t, int add_line(int incoming, active_thread *t,
const Gcalc_scan_iterator::point *p) const Gcalc_scan_iterator::point *p);
{
line *l= new_line();
if (!l)
return 1;
l->incoming= incoming;
l->t= t;
l->p= p;
*m_lines_hook= l;
m_lines_hook= &l->next;
return 0;
}
int add_poly_border(int incoming, active_thread *t, int prev_state, int add_poly_border(int incoming, active_thread *t, int prev_state,
const Gcalc_scan_iterator::point *p) const Gcalc_scan_iterator::point *p);
{
poly_border *b= new_poly_border();
if (!b)
return 1;
b->incoming= incoming;
b->t= t;
b->prev_state= prev_state;
b->p= p;
*m_poly_borders_hook= b;
m_poly_borders_hook= &b->next;
return 0;
}
protected: protected:
Gcalc_function *m_fn; Gcalc_function *m_fn;
...@@ -310,43 +297,29 @@ protected: ...@@ -310,43 +297,29 @@ protected:
res_point *result_heap; res_point *result_heap;
active_thread *m_first_active_thread; active_thread *m_first_active_thread;
res_point *add_res_point(Gcalc_function::shape_type type) res_point *add_res_point(Gcalc_function::shape_type type);
{
res_point *result= (res_point *)new_item();
*m_res_hook= result;
result->prev_hook= m_res_hook;
m_res_hook= &result->next;
result->type= type;
return result;
}
active_thread *new_active_thread() { return (active_thread *)new_item(); } active_thread *new_active_thread() { return (active_thread *)new_item(); }
poly_instance *new_poly() { return (poly_instance *) new_item(); } poly_instance *new_poly() { return (poly_instance *) new_item(); }
private: private:
int start_line(active_thread *t, const Gcalc_scan_iterator::point *p, int start_line(active_thread *t, const Gcalc_scan_iterator::point *p,
const Gcalc_heap::Info *ev_p, const Gcalc_scan_iterator *si);
int end_line(active_thread *t, const Gcalc_heap::Info *ev_p,
const Gcalc_scan_iterator *si); const Gcalc_scan_iterator *si);
int end_line(active_thread *t, const Gcalc_scan_iterator *si);
int connect_threads(int incoming_a, int incoming_b, int connect_threads(int incoming_a, int incoming_b,
active_thread *ta, active_thread *tb, active_thread *ta, active_thread *tb,
const Gcalc_scan_iterator::point *pa, const Gcalc_scan_iterator::point *pa,
const Gcalc_scan_iterator::point *pb, const Gcalc_scan_iterator::point *pb,
active_thread *prev_range, active_thread *prev_range,
const Gcalc_heap::Info *ev_p,
const Gcalc_scan_iterator *si, const Gcalc_scan_iterator *si,
Gcalc_function::shape_type s_t); Gcalc_function::shape_type s_t);
int add_single_point(const Gcalc_heap::Info *p, int add_single_point(const Gcalc_scan_iterator *si);
const Gcalc_scan_iterator *si);
poly_border *get_pair_border(poly_border *b1); poly_border *get_pair_border(poly_border *b1);
int continue_range(active_thread *t, const Gcalc_heap::Info *p, int continue_range(active_thread *t, const Gcalc_heap::Info *p,
int horiz_dir, double dx_dy); const Gcalc_heap::Info *p_next);
int continue_i_range(active_thread *t, double x, double y, int continue_i_range(active_thread *t,
int horiz_dir, double dx_dy); const Gcalc_heap::Intersection_info *ii);
int end_couple(active_thread *t0, active_thread *t1, const Gcalc_heap::Info *p); int end_couple(active_thread *t0, active_thread *t1, const Gcalc_heap::Info *p);
int add_single_point(const Gcalc_heap::Info *p);
int get_single_result(res_point *res, Gcalc_result_receiver *storage); int get_single_result(res_point *res, Gcalc_result_receiver *storage);
int get_result_thread(res_point *cur, Gcalc_result_receiver *storage, int get_result_thread(res_point *cur, Gcalc_result_receiver *storage,
int move_upward, res_point *first_poly_node); int move_upward, res_point *first_poly_node);
......
...@@ -867,7 +867,8 @@ int Item_func_spatial_rel::func_touches() ...@@ -867,7 +867,8 @@ int Item_func_spatial_rel::func_touches()
if (cur_func) if (cur_func)
{ {
area= scan_it.get_h() * area= scan_it.get_h() *
((ti.rb()->x - ti.lb()->x) + (ti.rt()->x - ti.lt()->x)); ((scan_it.get_sp_x(ti.rb()) - scan_it.get_sp_x(ti.lb())) +
(scan_it.get_sp_x(ti.rt()) - scan_it.get_sp_x(ti.lt())));
if (area > GIS_ZERO) if (area > GIS_ZERO)
{ {
result= 0; result= 0;
......
...@@ -2230,6 +2230,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const ...@@ -2230,6 +2230,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
return 1; return 1;
n_objects= uint4korr(data); n_objects= uint4korr(data);
data+= 4; data+= 4;
if (n_objects == 0)
return 1;
while (n_objects--) while (n_objects--)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment