Commit 3947f98f authored by Sandro Santilli's avatar Sandro Santilli

Fix ST_ClosestPointOfApproach assumption of lwgeom->bbox being exact

See #3136

git-svn-id: http://svn.osgeo.org/postgis/trunk@13569 b70326c6-7e19-0410-871a-916f4a2858ee
parent a8523fe5
......@@ -1089,6 +1089,18 @@ test_lwgeom_tcpa(void)
ASSERT_DOUBLE_EQUAL(m, 3.0);
ASSERT_DOUBLE_EQUAL(dist, 1.0);
/* Test for https://trac.osgeo.org/postgis/ticket/3136 */
g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
dist = -1;
m = lwgeom_tcpa(g1, g2, &dist);
lwgeom_free(g1);
lwgeom_free(g2);
ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
ASSERT_DOUBLE_EQUAL(dist, 0.0);
}
/*
......
......@@ -1043,7 +1043,7 @@ lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
double *mvals;
int nmvals = 0;
double mintime;
double mindist2; /* minimum distance, squared */
double mindist2 = FLT_MAX; /* minimum distance, squared */
if ( ! lwgeom_has_m(g1) || ! lwgeom_has_m(g2) ) {
lwerror("Both input geometries must have a measure dimension");
......@@ -1063,6 +1063,7 @@ lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
return -1;
}
/* WARNING: these ranges may be wider than real ones */
gbox1 = lwgeom_get_bbox(g1);
gbox2 = lwgeom_get_bbox(g2);
......@@ -1071,6 +1072,7 @@ lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
/*
* Find overlapping M range
* WARNING: may be larger than the real one
*/
tmin = FP_MAX(gbox1->mmin, gbox2->mmin);
......@@ -1130,39 +1132,19 @@ lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
/*lwnotice("T %g-%g", t0, t1);*/
seg = ptarray_locate_along_linear(l1->points, t0, &p0, 0);
if ( -1 == seg )
{
lwfree(mvals);
lwerror("Non-linear measures in first geometry");
return -1;
}
if ( -1 == seg ) continue; /* possible, if GBOX is approximated */
/*lwnotice("Measure %g on segment %d of line 1: %g, %g, %g", t0, seg, p0.x, p0.y, p0.z);*/
seg = ptarray_locate_along_linear(l1->points, t1, &p1, seg);
if ( -1 == seg )
{
lwfree(mvals);
lwerror("Non-linear measures in first geometry");
return -1;
}
if ( -1 == seg ) continue; /* possible, if GBOX is approximated */
/*lwnotice("Measure %g on segment %d of line 1: %g, %g, %g", t1, seg, p1.x, p1.y, p1.z);*/
seg = ptarray_locate_along_linear(l2->points, t0, &q0, 0);
if ( -1 == seg )
{
lwfree(mvals);
lwerror("Non-linear measures in second geometry");
return -1;
}
if ( -1 == seg ) continue; /* possible, if GBOX is approximated */
/*lwnotice("Measure %g on segment %d of line 2: %g, %g, %g", t0, seg, q0.x, q0.y, q0.z);*/
seg = ptarray_locate_along_linear(l2->points, t1, &q1, seg);
if ( -1 == seg )
{
lwfree(mvals);
lwerror("Non-linear measures in second geometry");
return -1;
}
if ( -1 == seg ) continue; /* possible, if GBOX is approximated */
/*lwnotice("Measure %g on segment %d of line 2: %g, %g, %g", t1, seg, q1.x, q1.y, q1.z);*/
t = segments_tcpa(&p0, &p1, &q0, &q1, t0, t1);
......@@ -1176,7 +1158,7 @@ lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
dist2 = ( q0.x - p0.x ) * ( q0.x - p0.x ) +
( q0.y - p0.y ) * ( q0.y - p0.y ) +
( q0.z - p0.z ) * ( q0.z - p0.z );
if ( i == 1 || dist2 < mindist2 )
if ( dist2 < mindist2 )
{
mindist2 = dist2;
mintime = t;
......
......@@ -79,6 +79,13 @@ select 'pca2', ST_ClosestPointOfApproach(
select 'pca3', ST_ClosestPointOfApproach(
'LINESTRINGZM(0 0 0 0, 0 0 0 10)',
'LINESTRINGZM(-30 0 5 4, 10 0 5 6)');
-- Ticket #3136
WITH inp as ( SELECT
'LINESTRING M (0 0 80000002,1 0 80000003)'::geometry g1,
'LINESTRING M (2 2 80000000,1 1 80000001,0 0 80000002)'::geometry g2 )
SELECT 'pca#3136',
ST_ClosestPointOfApproach(g2,g1), ST_ClosestPointOfApproach(g1,g2)
FROM inp;
--
-- ST_AddMeasure
......
......@@ -37,6 +37,7 @@ line_interpolate_point|POINT Z (0.5 0.5 7.5)
pca1|10
pca2|5
pca3|5.5
pca#3136|80000002|80000002
addMeasure1|LINESTRING M (0 0 10,2 0 15,4 0 20)
addMeasure2|LINESTRING M (0 0 10,9 0 19,10 0 20)
interpolatePoint1|2
......
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