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,
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;
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 122 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)'))
#
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))')))
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)
--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))')));
--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)
gcalc_shape_info si= events->get_shape();
if (events->event == scev_thread ||
events->event == scev_end ||
events->event == scev_single_point ||
(get_shape_kind(si) == Gcalc_function::shape_polygon))
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);
}
......
......@@ -1081,9 +1081,9 @@ static Gcalc_function::op_type op_matrix(int n)
switch (n)
{
case 0:
return Gcalc_function::op_border;
case 1:
return Gcalc_function::op_internals;
case 1:
return Gcalc_function::op_border;
case 2:
return (Gcalc_function::op_type)
((int) Gcalc_function::op_not | (int) Gcalc_function::op_union);
......@@ -1103,6 +1103,8 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
int last_shape_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);
for (int nc=0; nc<9; nc++)
{
......@@ -1120,11 +1122,11 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
cur_op|= Gcalc_function::v_find_t;
break;
case 'F':
cur_op|= Gcalc_function::v_find_f;
cur_op|= (Gcalc_function::op_not | Gcalc_function::v_find_t);
break;
};
++n_operands;
if (func->reserve_op_buffer(1))
if (func->reserve_op_buffer(3))
return 1;
func->add_operation(cur_op, 2);
......@@ -2346,7 +2348,7 @@ String *Item_func_pointonsurface::val_str(String *str)
}
x0= scan_it.get_sp_x(pprev);
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)
{
......
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