From c5e12f90303bb34f9754d2fcf13629179aa74748 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Wed, 13 Jan 2016 11:09:24 +0000 Subject: [PATCH] Avoid any drift of cutter point on lines split Should fix splitting operations on at least arm64, ppc64el and s390x. See #3422 and #3401 Also turn ASSERT_DOUBLE_EQUAL back to a tolerance-free check (better use a different name for tolerance-aware check, so caller can decide) git-svn-id: http://svn.osgeo.org/postgis/trunk@14594 b70326c6-7e19-0410-871a-916f4a2858ee --- liblwgeom/cunit/cu_tester.h | 5 ++--- liblwgeom/lwgeom_geos_split.c | 10 +++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/liblwgeom/cunit/cu_tester.h b/liblwgeom/cunit/cu_tester.h index 521bcf05a..918a0d153 100644 --- a/liblwgeom/cunit/cu_tester.h +++ b/liblwgeom/cunit/cu_tester.h @@ -23,11 +23,10 @@ void cu_error_msg_reset(void); /* Our internal callback to register Suites with the main tester */ typedef void (*PG_SuiteSetup)(void); -#define ASSERT_DOUBLE_EQUAL_TOLERANCE 10e-8 #define ASSERT_DOUBLE_EQUAL(o,e) do { \ - if ( fabs((double)o-(double)e) > ASSERT_DOUBLE_EQUAL_TOLERANCE ) \ + if ( o != e ) \ fprintf(stderr, "[%s:%d]\n Expected: %g\n Obtained: %g\n", __FILE__, __LINE__, (double)(e), (o)); \ - CU_ASSERT_DOUBLE_EQUAL((double)o,(double)e,ASSERT_DOUBLE_EQUAL_TOLERANCE); \ + CU_ASSERT_EQUAL(o,(double)e); \ } while (0); #define ASSERT_INT_EQUAL(o,e) do { \ diff --git a/liblwgeom/lwgeom_geos_split.c b/liblwgeom/lwgeom_geos_split.c index 1bf332475..887abbe84 100644 --- a/liblwgeom/lwgeom_geos_split.c +++ b/liblwgeom/lwgeom_geos_split.c @@ -245,6 +245,7 @@ lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in, { mindist = dist; seg=i; + if ( mindist == 0.0 ) break; /* can't be closer than ON line */ } p1 = p2; } @@ -260,11 +261,18 @@ lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in, /* * We need to project the - * point on the closest segment. + * point on the closest segment, + * to interpolate Z and M if needed */ getPoint4d_p(ipa, seg, &p1); getPoint4d_p(ipa, seg+1, &p2); closest_point_on_segment(&pt, &p1, &p2, &pt_projected); + /* But X and Y we want the ones of the input point, + * as on some architectures the interpolation math moves the + * coordinates (see #3422) + */ + pt_projected.x = pt.x; + pt_projected.y = pt.y; LWDEBUGF(3, "Projected point:(%g %g), seg:%d, p1:(%g %g), p2:(%g %g)", pt_projected.x, pt_projected.y, seg, p1.x, p1.y, p2.x, p2.y); -- 2.40.0