Commit 37345bd9 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations.

Problem was that we considered the point itself as the 'border' object. Instead
of that the 'border' of a POINT is an empty set, and the point is the 'interior'.
Another error fixed by the way - not all operations of the resulting function were properly
allocated.
parent ca304188
...@@ -404,7 +404,7 @@ Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t, ...@@ -404,7 +404,7 @@ Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
first second w c o e d t i r first second w c o e d t i r
120 120 1 1 0 1 0 1 1 0 120 120 1 1 0 1 0 0 1 0
120 121 0 0 1 0 0 0 1 0 120 121 0 0 1 0 0 0 1 0
120 122 NULL NULL NULL NULL NULL NULL NULL NULL 120 122 NULL NULL NULL NULL NULL NULL NULL NULL
120 123 NULL NULL NULL NULL NULL NULL NULL NULL 120 123 NULL NULL NULL NULL NULL NULL NULL NULL
...@@ -1779,4 +1779,22 @@ ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')) ...@@ -1779,4 +1779,22 @@ ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)'))
# #
SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))); SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')));
ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))) ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')))
POINT NULL
#
# MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations
#
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**FFF*') AS equals;
equals
1
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*****FF*') AS contains;
contains
1
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**F***') AS within;
within
1
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(1 1)'),'FF*FF****') as disjoint;
disjoint
1
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'FF*FF****') as disjoint;
disjoint
0
...@@ -1497,3 +1497,12 @@ select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0) ...@@ -1497,3 +1497,12 @@ select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)
--echo # --echo #
SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))); SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')));
--echo #
--echo # MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations
--echo #
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**FFF*') AS equals;
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*****FF*') AS contains;
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**F***') AS within;
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(1 1)'),'FF*FF****') as disjoint;
select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'FF*FF****') as disjoint;
...@@ -300,10 +300,10 @@ int Gcalc_function::check_function(Gcalc_scan_iterator &scan_it) ...@@ -300,10 +300,10 @@ int Gcalc_function::check_function(Gcalc_scan_iterator &scan_it)
gcalc_shape_info si= events->get_shape(); gcalc_shape_info si= events->get_shape();
if (events->event == scev_thread || if (events->event == scev_thread ||
events->event == scev_end || events->event == scev_end ||
events->event == scev_single_point ||
(get_shape_kind(si) == Gcalc_function::shape_polygon)) (get_shape_kind(si) == Gcalc_function::shape_polygon))
set_b_state(si); set_b_state(si);
else if (get_shape_kind(si) == Gcalc_function::shape_line) else if (events->event == scev_single_point ||
get_shape_kind(si) == Gcalc_function::shape_line)
set_i_state(si); set_i_state(si);
} }
......
...@@ -1081,9 +1081,9 @@ static Gcalc_function::op_type op_matrix(int n) ...@@ -1081,9 +1081,9 @@ static Gcalc_function::op_type op_matrix(int n)
switch (n) switch (n)
{ {
case 0: case 0:
return Gcalc_function::op_border;
case 1:
return Gcalc_function::op_internals; return Gcalc_function::op_internals;
case 1:
return Gcalc_function::op_border;
case 2: case 2:
return (Gcalc_function::op_type) return (Gcalc_function::op_type)
((int) Gcalc_function::op_not | (int) Gcalc_function::op_union); ((int) Gcalc_function::op_not | (int) Gcalc_function::op_union);
...@@ -1103,6 +1103,8 @@ static int setup_relate_func(Geometry *g1, Geometry *g2, ...@@ -1103,6 +1103,8 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
int last_shape_pos; int last_shape_pos;
last_shape_pos= func->get_next_expression_pos(); last_shape_pos= func->get_next_expression_pos();
if (func->reserve_op_buffer(1))
return 1;
func->add_operation(Gcalc_function::op_intersection, 0); func->add_operation(Gcalc_function::op_intersection, 0);
for (int nc=0; nc<9; nc++) for (int nc=0; nc<9; nc++)
{ {
...@@ -1120,11 +1122,11 @@ static int setup_relate_func(Geometry *g1, Geometry *g2, ...@@ -1120,11 +1122,11 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
cur_op|= Gcalc_function::v_find_t; cur_op|= Gcalc_function::v_find_t;
break; break;
case 'F': case 'F':
cur_op|= Gcalc_function::v_find_f; cur_op|= (Gcalc_function::op_not | Gcalc_function::v_find_t);
break; break;
}; };
++n_operands; ++n_operands;
if (func->reserve_op_buffer(1)) if (func->reserve_op_buffer(3))
return 1; return 1;
func->add_operation(cur_op, 2); func->add_operation(cur_op, 2);
...@@ -2346,7 +2348,7 @@ String *Item_func_pointonsurface::val_str(String *str) ...@@ -2346,7 +2348,7 @@ String *Item_func_pointonsurface::val_str(String *str)
} }
x0= scan_it.get_sp_x(pprev); x0= scan_it.get_sp_x(pprev);
px= scan_it.get_sp_x(pit.point()); px= scan_it.get_sp_x(pit.point());
if (fabs(px - x0) > GIS_ZERO) if (px - x0 > GIS_ZERO)
{ {
if (scan_it.get_h() > GIS_ZERO) if (scan_it.get_h() > GIS_ZERO)
{ {
......
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