From 3655c75d134162c5a50823264a4fc55055a1c413 Mon Sep 17 00:00:00 2001 From: Paul Ramsey Date: Fri, 18 Jan 2019 18:03:46 +0000 Subject: [PATCH] Geodetic tolerance issue in 32-bit References #4298 git-svn-id: http://svn.osgeo.org/postgis/branches/2.4@17183 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/lwgeodetic.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index a0ff524ba..1c6f003b6 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PostGIS 2.4.7 - #4289, ST_AsMVTGeom: Transform coordinates space before clipping (Raúl Marín) - #4275, Avoid passing a NULL pointer to GEOSisEmpty (Raúl Marín) - #4296, Use `server_version_num` instead of parsing `version()` (Raúl Marín) + - #4298, Geodetic tolerance issue in 32-bit (Paul Ramsey) PostGIS 2.4.6 diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c index 131ce422d..7d0d6d54d 100644 --- a/liblwgeom/lwgeodetic.c +++ b/liblwgeom/lwgeodetic.c @@ -35,6 +35,15 @@ */ int gbox_geocentric_slow = LW_FALSE; +/** +* Utility function for ptarray_contains_point_sphere() +*/ +static int +point3d_equals(const POINT3D *p1, const POINT3D *p2) +{ + return FP_EQUALS(p1->x, p2->x) && FP_EQUALS(p1->y, p2->y) && FP_EQUALS(p1->z, p2->z); +} + /** * Convert a longitude to the range of -PI,PI */ @@ -3357,6 +3366,10 @@ point_in_cone(const POINT3D *A1, const POINT3D *A2, const POINT3D *P) POINT3D AC; /* Center point of A1/A2 */ double min_similarity, similarity; + /* Boundary case */ + if (point3d_equals(A1, P) || point3d_equals(A2, P)) + return LW_TRUE; + /* The normalized sum bisects the angle between start and end. */ vector_sum(A1, A2, &AC); normalize(&AC); @@ -3365,7 +3378,7 @@ point_in_cone(const POINT3D *A1, const POINT3D *A2, const POINT3D *P) min_similarity = dot_product(A1, &AC); /* If the edge is sufficiently curved, use the dot product test */ - if (fabs(1.0 - min_similarity) > 1e-10 ) + if (fabs(1.0 - min_similarity) > 1e-10) { /* The projection of candidate p onto the center */ similarity = dot_product(P, &AC); @@ -3374,7 +3387,7 @@ point_in_cone(const POINT3D *A1, const POINT3D *A2, const POINT3D *P) /* the projection of the start point, the candidate */ /* must be closer to the center than the start, so */ /* therefor inside the cone */ - if ( similarity > min_similarity ) + if (similarity > min_similarity) { return LW_TRUE; } @@ -3409,14 +3422,6 @@ point_in_cone(const POINT3D *A1, const POINT3D *A2, const POINT3D *P) } -/** -* Utility function for ptarray_contains_point_sphere() -*/ -static int -point3d_equals(const POINT3D *p1, const POINT3D *p2) -{ - return FP_EQUALS(p1->x, p2->x) && FP_EQUALS(p1->y, p2->y) && FP_EQUALS(p1->z, p2->z); -} /** * Utility function for edge_intersects(), signum with a tolerance -- 2.40.0