[SCM] PostGIS branch master updated. 3.6.0rc2-613-gfc2a5bdd5
git at osgeo.org
git at osgeo.org
Thu Jun 18 10:20:05 PDT 2026
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 fc2a5bdd5ea9e0f9a26a9374e0d3bb69ae4288b3 (commit)
from 2f87b9ef28eb63e50d935da7141647ceb34f520f (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 fc2a5bdd5ea9e0f9a26a9374e0d3bb69ae4288b3
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Thu Jun 18 21:18:39 2026 +0400
geography: stabilize 32-bit LRS and pole centroid tests
Clamp geography interpolation at tolerant segment endpoints, skip zero-length interpolation segments, and assert signed pole latitude in centroid regressions.
Closes https://github.com/postgis/postgis/pull/907
Closes #6073
Closes #6074
diff --git a/NEWS b/NEWS
index f4db1a5fc..8a8baa0d2 100644
--- a/NEWS
+++ b/NEWS
@@ -72,6 +72,8 @@ To take advantage of all postgis_sfcgal extension features SFCGAL 2.3+ is needed
finite coordinates (Darafei Praliaskouski)
- GH-892, Add OSS-Fuzz coverage for TWKB and serialized raster inputs,
including guards for malformed TWKB reads and counts (Darafei Praliaskouski)
+ - #6073, #6074, Stabilize geography LRS endpoint interpolation and pole
+ centroid regressions on 32-bit systems (Darafei Praliaskouski)
- #6082, Fix Japanese PDF build by avoiding non-ASCII arrows in SQL
program listings (Darafei Praliaskouski)
- GH-888, [sfcgal] Avoid stale detoasted geometry access in
diff --git a/liblwgeom/lwgeodetic_measures.c b/liblwgeom/lwgeodetic_measures.c
index 27f57ecdb..0640d0c39 100644
--- a/liblwgeom/lwgeodetic_measures.c
+++ b/liblwgeom/lwgeodetic_measures.c
@@ -317,15 +317,34 @@ geography_interpolate_points(
else
segment_length_frac = spheroid_distance(&g1, &g2, s) / length;
+ /* Duplicate vertices produce zero-length geodetic segments. Skip them
+ * before endpoint tolerance matching because spheroid interpolation with
+ * identical endpoints has no stable direction. */
+ if (segment_length_frac <= 0.0)
+ {
+ p1 = p2;
+ g1 = g2;
+ continue;
+ }
+
/* If our target distance is before the total length we've seen
* so far. create a new point some distance down the current
* segment.
*/
- while ( length_fraction < length_fraction_consumed + segment_length_frac && points_found < points_to_interpolate )
+ while (length_fraction <= length_fraction_consumed + segment_length_frac + FP_TOLERANCE &&
+ points_found < points_to_interpolate)
{
+ double segment_end_fraction = length_fraction_consumed + segment_length_frac;
+ double segment_fraction;
geog2cart(&g1, &q1);
geog2cart(&g2, &q2);
- double segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
+ /* The endpoint tolerance compensates for 32-bit accumulated fraction
+ * drift, but it must clamp before segment normalization so short
+ * segments are not extrapolated. */
+ if (length_fraction > segment_end_fraction)
+ segment_fraction = 1.0;
+ else
+ segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
interpolate_point4d_spheroid(&p1, &p2, &pt, s, segment_fraction);
ptarray_set_point4d(opa, points_found++, &pt);
length_fraction += length_fraction_increment;
@@ -342,7 +361,7 @@ geography_interpolate_points(
if (points_found < points_to_interpolate)
{
getPoint4d_p(ipa, ipa->npoints - 1, &pt);
- ptarray_set_point4d(opa, points_found, &pt);
+ ptarray_set_point4d(opa, points_found++, &pt);
}
if (opa->npoints <= 1)
diff --git a/regress/core/geography.sql b/regress/core/geography.sql
index 5f98c7066..6e5ca26c5 100644
--- a/regress/core/geography.sql
+++ b/regress/core/geography.sql
@@ -141,6 +141,14 @@ SELECT 'lrs_lip_2', ST_AsText(ST_LineInterpolatePoints(geography 'Linestring(4.3
SELECT 'lrs_lip_3', ST_AsText(ST_LineInterpolatePoints(geography 'Linestring(4.35 50.85, 37.617222 55.755833)', 1.0, false), 2);
SELECT 'lrs_lip_4', ST_AsText(ST_LineInterpolatePoints(geography 'Linestring(4.35 50.85, 37.617222 55.755833)', 0.1, true), 2);
SELECT 'lrs_lip_5', ST_AsText(ST_LineInterpolatePoints(geography 'Linestring(4.35 50.85, 37.617222 55.755833)', 0.1, false), 2);
+SELECT 'lrs_lip_6073_short_segment', ST_Distance(
+ ST_LineInterpolatePoint(geography 'LINESTRING(0 0, 0 0.000000000001, 1 0)', 0.000000000001),
+ geography 'POINT(0 0.000000000001)'
+) < 1e-8;
+SELECT 'lrs_lip_6073_duplicate_start', ST_Distance(
+ ST_LineInterpolatePoint(geography 'LINESTRING(0 0, 0 0, 1 0)', 0.00000000000001),
+ geography 'POINT(0.00000000000001 0)'
+) < 1e-8;
SELECT 'lrs_llp_1', round(ST_LineLocatePoint(geography 'linestring(0 1, 50 1)', geography 'Point(25 0)')::numeric, 2);
SELECT 'lrs_llp_2', round(ST_LineLocatePoint(geography 'linestring(0 1, 50 1)', geography 'Point(-5 0)')::numeric, 2);
@@ -157,4 +165,3 @@ SELECT 'ticket_6076_perimeter', round(ST_Perimeter(ST_GeogFromText('GEOMETRYCOLL
--SELECT 'lrs_cp_2', ST_AsText(ST_ClosestPoint(geography 'Point(25 20)', geography 'Linestring(0 20, 50 20)'), 3);
SELECT 'lrs_sl_1', ST_AsText(ST_ShortestLine(geography 'linestring(0 40, 50 40)', 'Point(25 40)', true), 2);
-
diff --git a/regress/core/geography_centroid.sql b/regress/core/geography_centroid.sql
index 260e4d32a..077a64ce2 100644
--- a/regress/core/geography_centroid.sql
+++ b/regress/core/geography_centroid.sql
@@ -1,6 +1,6 @@
-- check for pole crossing
-SELECT c, ST_AsText(ST_Centroid(g::geography),6) FROM
+SELECT c, ST_Y(ST_Centroid(g::geography)::geometry)::numeric(12,6) FROM
( VALUES
('geog_centroid_mpt_pole_north', 'MULTIPOINT ( 90 80, -90 80)'),
('geog_centroid_mpt_pole_south', 'MULTIPOINT ( 90 -80, -90 -80)')
diff --git a/regress/core/geography_centroid_expected b/regress/core/geography_centroid_expected
index b9e5ca7ca..805e6987c 100644
--- a/regress/core/geography_centroid_expected
+++ b/regress/core/geography_centroid_expected
@@ -1,5 +1,5 @@
-geog_centroid_mpt_pole_north|POINT(0 90)
-geog_centroid_mpt_pole_south|POINT(0 -90)
+geog_centroid_mpt_pole_north|90.000000
+geog_centroid_mpt_pole_south|-90.000000
geog_centroid_mpt_idl_1|180.000000|0.000000
geog_centroid_mpt_idl_2|179.500000|0.000000
geog_centroid_mpt_idl_3|-179.500000|0.000000
diff --git a/regress/core/geography_expected b/regress/core/geography_expected
index 8584b7df0..6c5af43d8 100644
--- a/regress/core/geography_expected
+++ b/regress/core/geography_expected
@@ -61,6 +61,8 @@ lrs_lip_2|POINT(4.35 50.85)
lrs_lip_3|POINT(37.62 55.76)
lrs_lip_4|MULTIPOINT((7.27 51.73),(10.3 52.54),(13.43 53.27),(16.67 53.91),(20 54.47),(23.42 54.93),(26.9 55.29),(30.44 55.55),(34.02 55.7),(37.62 55.76))
lrs_lip_5|MULTIPOINT((7.27 51.73),(10.29 52.54),(13.43 53.27),(16.67 53.91),(20 54.46),(23.42 54.92),(26.9 55.29),(30.44 55.55),(34.02 55.7),(37.62 55.76))
+lrs_lip_6073_short_segment|t
+lrs_lip_6073_duplicate_start|t
lrs_llp_1|0.50
lrs_llp_2|0.00
lrs_llp_3|1.00
-----------------------------------------------------------------------
Summary of changes:
NEWS | 2 ++
liblwgeom/lwgeodetic_measures.c | 25 ++++++++++++++++++++++---
regress/core/geography.sql | 9 ++++++++-
regress/core/geography_centroid.sql | 2 +-
regress/core/geography_centroid_expected | 4 ++--
regress/core/geography_expected | 2 ++
6 files changed, 37 insertions(+), 7 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list