[postgis-tickets] [SCM] PostGIS branch master updated. 3.3.0alpha1-107-g090312077

git at osgeo.org git at osgeo.org
Thu Jun 30 16:17:55 PDT 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  0903120772c9017f99c51c4b83b606be14e148b7 (commit)
      from  cc78c2e4050b66c5103c3b359bcae56f5023a4ed (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0903120772c9017f99c51c4b83b606be14e148b7
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Thu Jun 30 16:17:22 2022 -0700

    Harmonize use of tolerances a little and short-circuit distance calculation on identical inputs
    References #4932

diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c
index 87b4c1316..7d9f43f9b 100644
--- a/liblwgeom/lwgeodetic.c
+++ b/liblwgeom/lwgeodetic.c
@@ -947,17 +947,21 @@ int edge_contains_coplanar_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POIN
 */
 double sphere_distance(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e)
 {
-	double d_lon = e->lon - s->lon;
-	double cos_d_lon = cos(d_lon);
-	double cos_lat_e = cos(e->lat);
-	double sin_lat_e = sin(e->lat);
-	double cos_lat_s = cos(s->lat);
-	double sin_lat_s = sin(s->lat);
-
-	double a1 = POW2(cos_lat_e * sin(d_lon));
-	double a2 = POW2(cos_lat_s * sin_lat_e - sin_lat_s * cos_lat_e * cos_d_lon);
-	double a = sqrt(a1 + a2);
-	double b = sin_lat_s * sin_lat_e + cos_lat_s * cos_lat_e * cos_d_lon;
+	double d_lon, cos_d_lon, cos_lat_e, sin_lat_e, cos_lat_s, sin_lat_s;
+	double a1, a2, a, b;
+
+	if (FP_EQUALS(s->lat, e->lat) && FP_EQUALS(s->lon, e->lon)) return 0.0;
+	d_lon = e->lon - s->lon;
+	cos_d_lon = cos(d_lon);
+	cos_lat_e = cos(e->lat);
+	sin_lat_e = sin(e->lat);
+	cos_lat_s = cos(s->lat);
+	sin_lat_s = sin(s->lat);
+
+	a1 = POW2(cos_lat_e * sin(d_lon));
+	a2 = POW2(cos_lat_s * sin_lat_e - sin_lat_s * cos_lat_e * cos_d_lon);
+	a = sqrt(a1 + a2);
+	b = sin_lat_s * sin_lat_e + cos_lat_s * cos_lat_e * cos_d_lon;
 	return atan2(a, b);
 }
 
@@ -1913,7 +1917,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 				nearest2 = g2;
 			}
 			/* We've gotten closer than the tolerance... */
-			if ( d < tolerance )
+			if ( d <= tolerance )
 			{
 				/* Working on a sphere? The answer is correct, return */
 				if ( use_sphere )
@@ -1921,7 +1925,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 					return d;
 				}
 				/* Far enough past the tolerance that the spheroid calculation won't change things */
-				else if ( d < tolerance * 0.95 )
+				else if ( d <= tolerance * 0.95 )
 				{
 					return d;
 				}
@@ -1930,7 +1934,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 				{
 					d = spheroid_distance(&g1, &nearest2, s);
 					/* Yes, closer than tolerance, return! */
-					if ( d < tolerance )
+					if ( d <= tolerance )
 						return d;
 				}
 			}
@@ -1991,7 +1995,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 				nearest1 = g1;
 				nearest2 = g2;
 			}
-			if ( d < tolerance )
+			if ( d <= tolerance )
 			{
 				if ( use_sphere )
 				{
@@ -2000,7 +2004,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 				else
 				{
 					d = spheroid_distance(&nearest1, &nearest2, s);
-					if ( d < tolerance )
+					if ( d <= tolerance )
 						return d;
 				}
 			}
@@ -2282,7 +2286,7 @@ double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, co
 			double ring_distance = ptarray_distance_spheroid(lwpoly->rings[i], lwpt->point, spheroid, tolerance, check_intersection);
 			if ( ring_distance < distance )
 				distance = ring_distance;
-			if ( distance < tolerance )
+			if ( distance <= tolerance )
 				return distance;
 		}
 		return distance;
@@ -2325,7 +2329,7 @@ double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, co
 			LWDEBUGF(4, "ring[%d] ring_distance = %.8g", i, ring_distance);
 			if ( ring_distance < distance )
 				distance = ring_distance;
-			if ( distance < tolerance )
+			if ( distance <= tolerance )
 				return distance;
 		}
 		LWDEBUGF(4, "all rings checked, returning distance = %.8g", distance);
@@ -2365,7 +2369,7 @@ double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, co
 					check_intersection);
 				if (ring_distance < distance)
 					distance = ring_distance;
-				if (distance < tolerance) return distance;
+				if (distance <= tolerance) return distance;
 			}
 		}
 		return distance;
@@ -2384,7 +2388,7 @@ double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, co
 			    col->geoms[i], lwgeom2, spheroid, tolerance);
 			if ( geom_distance < distance )
 				distance = geom_distance;
-			if ( distance < tolerance )
+			if ( distance <= tolerance )
 				return distance;
 		}
 		return distance;
@@ -2402,7 +2406,7 @@ double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, co
 			double geom_distance = lwgeom_distance_spheroid(lwgeom1, col->geoms[i], spheroid, tolerance);
 			if ( geom_distance < distance )
 				distance = geom_distance;
-			if ( distance < tolerance )
+			if ( distance <= tolerance )
 				return distance;
 		}
 		return distance;
@@ -3351,22 +3355,22 @@ ptarray_nudge_geodetic(POINTARRAY *pa)
 	for(i = 0; i < pa->npoints; i++ )
 	{
 		getPoint4d_p(pa, i, &p);
-		if ( p.x < -180.0 && (-180.0 - p.x < tolerance) )
+		if ( p.x < -180.0 && (-180.0 - p.x <= tolerance) )
 		{
 			p.x = -180.0;
 			altered = LW_TRUE;
 		}
-		if ( p.x > 180.0 && (p.x - 180.0 < tolerance) )
+		if ( p.x > 180.0 && (p.x - 180.0 <= tolerance) )
 		{
 			p.x = 180.0;
 			altered = LW_TRUE;
 		}
-		if ( p.y < -90.0 && (-90.0 - p.y < tolerance) )
+		if ( p.y < -90.0 && (-90.0 - p.y <= tolerance) )
 		{
 			p.y = -90.0;
 			altered = LW_TRUE;
 		}
-		if ( p.y > 90.0 && (p.y - 90.0 < tolerance) )
+		if ( p.y > 90.0 && (p.y - 90.0 <= tolerance) )
 		{
 			p.y = 90.0;
 			altered = LW_TRUE;
diff --git a/postgis/geography_measurement.c b/postgis/geography_measurement.c
index bea5d9ec9..3e5818629 100644
--- a/postgis/geography_measurement.c
+++ b/postgis/geography_measurement.c
@@ -272,7 +272,7 @@ Datum geography_dwithin(PG_FUNCTION_ARGS)
 	const GSERIALIZED *g1 = shared_gserialized_get(shared_geom1);
 	const GSERIALIZED *g2 = shared_gserialized_get(shared_geom2);
 	SPHEROID s;
-	double tolerance = 0.0;
+	double tolerance = FP_TOLERANCE;
 	bool use_spheroid = true;
 	double distance;
 	int dwithin = LW_FALSE;

-----------------------------------------------------------------------

Summary of changes:
 liblwgeom/lwgeodetic.c          | 54 ++++++++++++++++++++++-------------------
 postgis/geography_measurement.c |  2 +-
 2 files changed, 30 insertions(+), 26 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list