[SCM] PostGIS branch master updated. 3.6.0rc2-360-g8b07652d0
git at osgeo.org
git at osgeo.org
Fri Mar 6 01:08:41 PST 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 8b07652d087b33fc347ee243b7af998fa58ab4a3 (commit)
from eabe42d06e572fedfd6684c1be542e41097e5bc2 (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 8b07652d087b33fc347ee243b7af998fa58ab4a3
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Fri Mar 6 00:00:02 2026 +0400
regress: stabilize topology output across architectures
Break tied topology edge, node, and edge-end selections deterministically so regressions no longer depend on platform-specific ordering.
Refresh alphashape_components expected output to match current SFCGAL behavior.
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index ba42f592c..054c2b21c 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -5193,22 +5193,48 @@ _lwt_minTolerance( LWGEOM *g )
#define _LWT_MINTOLERANCE( topo, geom ) ( \
topo->precision ? topo->precision : _lwt_minTolerance(geom) )
-typedef struct scored_pointer_t {
- void *ptr;
- double score;
-} scored_pointer;
+typedef struct scored_node_t {
+ LWT_ISO_NODE *node;
+ double score;
+} scored_node;
static int
-compare_scored_pointer(const void *si1, const void *si2)
+compare_scored_node(const void *si1, const void *si2)
{
- double a = ((scored_pointer *)si1)->score;
- double b = ((scored_pointer *)si2)->score;
- if ( a < b )
- return -1;
- else if ( a > b )
- return 1;
- else
- return 0;
+ const scored_node *a = si1;
+ const scored_node *b = si2;
+ if (a->score < b->score)
+ return -1;
+ else if (a->score > b->score)
+ return 1;
+ else if (a->node->node_id < b->node->node_id)
+ return -1;
+ else if (a->node->node_id > b->node->node_id)
+ return 1;
+ else
+ return 0;
+}
+
+typedef struct scored_edge_t {
+ LWT_ISO_EDGE *edge;
+ double score;
+} scored_edge;
+
+static int
+compare_scored_edge(const void *si1, const void *si2)
+{
+ const scored_edge *a = si1;
+ const scored_edge *b = si2;
+ if (a->score < b->score)
+ return -1;
+ else if (a->score > b->score)
+ return 1;
+ else if (a->edge->edge_id < b->edge->edge_id)
+ return -1;
+ else if (a->edge->edge_id > b->edge->edge_id)
+ return 1;
+ else
+ return 0;
}
/* Return identifier of an equal edge, 0 if none or -1 on error
@@ -6646,7 +6672,7 @@ static LWT_ELEMID
_lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t num, LWPOINT *point, double tol, int *moved)
{
uint64_t i, j;
- scored_pointer *sorted = lwalloc(sizeof(scored_pointer)*num);
+ scored_edge *sorted = lwalloc(sizeof(scored_edge) * num);
LWT_ISO_EDGE *edges2 = NULL;
LWT_ISO_NODE node;
node.node_id = 0; /* unneeded, but hushes a compiler warning */
@@ -6663,7 +6689,7 @@ _lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t nu
dist = lwgeom_mindistance2d(lwline_as_lwgeom(edges[i].geom), lwpoint_as_lwgeom(point));
LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " distance: %.15g", e->edge_id, dist);
if ( dist >= tol ) continue;
- sorted[j].ptr = e;
+ sorted[j].edge = e;
sorted[j++].score = dist;
}
if ( ! j )
@@ -6673,18 +6699,18 @@ _lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t nu
}
num = j;
- qsort(sorted, num, sizeof(scored_pointer), compare_scored_pointer);
+ qsort(sorted, num, sizeof(scored_edge), compare_scored_edge);
edges2 = lwalloc(sizeof(LWT_ISO_EDGE)*num);
for (j=0, i=0; i<num; ++i)
{
if ( sorted[i].score == sorted[0].score )
{
- edges2[j++] = *((LWT_ISO_EDGE*)sorted[i].ptr);
+ edges2[j++] = *sorted[i].edge;
}
else
{
- edges2[j++] = *((LWT_ISO_EDGE*)sorted[i].ptr);
- //lwline_free(((LWT_ISO_EDGE*)sorted[i].ptr)->geom);
+ edges2[j++] = *sorted[i].edge;
+ // lwline_free(sorted[i].edge->geom);
}
}
num = j;
@@ -6890,7 +6916,7 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int
LWT_ISO_NODE *nodes, *nodes2;
LWT_ISO_EDGE *edges;
LWGEOM *pt = lwpoint_as_lwgeom(point);
- scored_pointer *sorted;
+ scored_node *sorted;
int flds;
LWT_ELEMID id = 0;
@@ -6921,20 +6947,20 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int
/* Order by distance if there are more than a single return */
if ( num > 1 )
{{
- sorted = lwalloc(sizeof(scored_pointer)*num);
- for (i=0; i<num; ++i)
- {
- sorted[i].ptr = nodes+i;
- sorted[i].score = lwgeom_mindistance2d(lwpoint_as_lwgeom(nodes[i].geom), pt);
- LWDEBUGF(1, "Node %" LWTFMT_ELEMID " distance: %.15g",
- ((LWT_ISO_NODE*)(sorted[i].ptr))->node_id, sorted[i].score);
- }
- qsort(sorted, num, sizeof(scored_pointer), compare_scored_pointer);
- nodes2 = lwalloc(sizeof(LWT_ISO_NODE)*num);
- for (i=0; i<num; ++i)
- {
- nodes2[i] = *((LWT_ISO_NODE*)sorted[i].ptr);
- }
+ sorted = lwalloc(sizeof(scored_node) * num);
+ for (i = 0; i < num; ++i)
+ {
+ sorted[i].node = nodes + i;
+ sorted[i].score = lwgeom_mindistance2d(lwpoint_as_lwgeom(nodes[i].geom), pt);
+ LWDEBUGF(
+ 1, "Node %" LWTFMT_ELEMID " distance: %.15g", sorted[i].node->node_id, sorted[i].score);
+ }
+ qsort(sorted, num, sizeof(scored_node), compare_scored_node);
+ nodes2 = lwalloc(sizeof(LWT_ISO_NODE) * num);
+ for (i = 0; i < num; ++i)
+ {
+ nodes2[i] = *sorted[i].node;
+ }
lwfree(sorted);
lwfree(nodes);
nodes = nodes2;
diff --git a/liblwgeom/topo/lwt_edgeend_star.c b/liblwgeom/topo/lwt_edgeend_star.c
index 600e7b6da..a9a0e7acb 100644
--- a/liblwgeom/topo/lwt_edgeend_star.c
+++ b/liblwgeom/topo/lwt_edgeend_star.c
@@ -135,6 +135,14 @@ lwt_edgeEnd_compare(const void *i1, const void *i2)
ret = -1;
else if ( ee1->azimuth > ee2->azimuth )
ret = 1;
+ else if (ee1->edge->edge_id < ee2->edge->edge_id)
+ ret = -1;
+ else if (ee1->edge->edge_id > ee2->edge->edge_id)
+ ret = 1;
+ else if (ee1->outgoing < ee2->outgoing)
+ ret = -1;
+ else if (ee1->outgoing > ee2->outgoing)
+ ret = 1;
else
ret = 0;
diff --git a/regress/run_test.pl b/regress/run_test.pl
index bf7386bbe..40fcce21e 100755
--- a/regress/run_test.pl
+++ b/regress/run_test.pl
@@ -524,7 +524,6 @@ print " GDAL: $gdalver\n" if $gdalver;
# allow hook scripts to perform arbitrary reports via output of INFO strings
system("grep INFO $REGRESS_LOG | sed 's/INFO://'");
-
##################################################################
# Run the tests
##################################################################
diff --git a/sfcgal/regress/alphashape_components_expected b/sfcgal/regress/alphashape_components_expected
index a30a4ad59..022ef1221 100644
--- a/sfcgal/regress/alphashape_components_expected
+++ b/sfcgal/regress/alphashape_components_expected
@@ -1,2 +1,2 @@
-CG_Optimalalphashape_2components|MULTIPOLYGON(((8.3 11.8,6.2 12.1,4.1 11.9,2.6 11.2,1.1 10.1,0.3 8.2,0.1 6.1,0.4 4,1.2 2.3,2.5 1,4.2 0.3,6 0,8.1 0.1,10.1 0.2,9.2 2.4,7.8 2.2,6 2.3,3.6 6.2,7.6 9.8,9.1 9.9,10.2 11.1,8.3 11.8)),((55.6 12.1,55.8 15,54.3 15.2,52.9 10.6,52.7 7.3,52.8 4.1,46.9 2.8,43.3 7.1,43.1 10.4,43.1 15.3,41.9 15.6,40.5 15.2,40.2 12.3,40.4 9,39.8 6.2,40.1 3.1,40.3 0.4,42.1 0.3,44.2 0.2,49.8 -0.2,52.6 0.1,55.4 0.5,55.7 3.3,55.5 6,55.9 9.2,55.6 12.1)))
-CG_OptimalAlphaShape_hole_2components|MULTIPOLYGON(((5.5 8.5,5 9,4.5 9.5,4 10,3 10,2 10,1 10,0.5 10,0.23 10,0.03 9.82,0 9,0 8,0 7,0 6,0 5,0 4,0 3,0 2,0 1,0 0,0.5 0,1 0,2 0,3 0,4 0,5 0,5.5 0.5,6 1,6 2,5.8 2.5,5.5 3,5 3.5,4.5 4,4 4.5,5 5,5.5 5.5,6 6,6 7,6 8,5.5 8.5),(0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 1,0.5 2),(0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 6,0.5 7)),((17.5 8.5,17 9,16.5 9.5,16 10,15 10,14 10,13 10,12.5 10,12 10,12 9,12 8,12 7,12 6,12 5,12 4,12 3,12 2,12 1,12 0,12.5 0,13 1,13 2,13 3,13 4,13 5,14 5,15 5,16 5,17 5,17.5 5.5,18 6,18 7,18 7.3,18 8,17.5 8.5),(12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6,12.5 7)))
+CG_Optimalalphashape_2components|POLYGON((0.1 6.1,0.3 8.2,1.1 10.1,2.6 11.2,4.1 11.9,6.2 12.1,8.3 11.8,10.2 11.1,9.1 9.9,7.6 9.8,3.6 6.2,6 2.3,7.8 2.2,9.2 2.4,10.1 0.2,8.1 0.1,6 0,4.2 0.3,2.5 1,1.2 2.3,0.4 4,55.6 12.1,55.9 9.2,55.5 6,55.7 3.3,55.4 0.5,52.6 0.1,49.8 -0.2,44.2 0.2,42.1 0.3,40.3 0.4,40.1 3.1,39.8 6.2,40.4 9,40.2 12.3,40.5 15.2,41.9 15.6,43.1 15.3,43.1 10.4,43.3 7.1,46.9 2.8,52.8 4.1,52.7 7.3,52.9 10.6,54.3 15.2,55.8 15,0.1 6.1))
+CG_OptimalAlphaShape_hole_2components|POLYGON((0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0.03 9.82,0.23 10,0.5 10,1 10,2 10,3 10,4 10,4.5 9.5,5 9,5.5 8.5,6 8,6 7,6 6,5.5 5.5,5 5,4 4.5,4.5 4,5 3.5,5.5 3,5.8 2.5,6 2,6 1,5.5 0.5,5 0,4 0,3 0,2 0,1 0,0.5 0,12 0,12 1,12 2,12 3,12 4,12 5,12 6,12 7,12 8,12 9,12 10,12.5 10,13 10,14 10,15 10,16 10,16.5 9.5,17 9,17.5 8.5,18 8,18 7.3,18 7,18 6,17.5 5.5,17 5,16 5,15 5,14 5,13 5,13 4,13 3,13 2,13 1,12.5 0,0 0),(0.5 1,0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 6,0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 1),(12.5 6,12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6))
diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c
index f6bd71a5c..7707ece2b 100644
--- a/topology/postgis_topology.c
+++ b/topology/postgis_topology.c
@@ -3048,7 +3048,11 @@ cb_getClosestEdge( const LWT_BE_TOPOLOGY* topo, const LWPOINT* pt, uint64_t *num
appendStringInfoString(sql, "SELECT ");
addEdgeFields(sql, fields, 0);
- appendStringInfo(sql, " FROM \"%s\".edge_data ORDER BY geom <-> $1 ASC LIMIT 1", topo->name);
+ appendStringInfo(sql,
+ " FROM \"%s\".edge_data"
+ " ORDER BY geom <-> $1 ASC, edge_id ASC"
+ " LIMIT 1",
+ topo->name);
POSTGIS_DEBUGF(1, "cb_getClosestEdge query: %s", sql->data);
-----------------------------------------------------------------------
Summary of changes:
liblwgeom/topo/lwgeom_topo.c | 94 +++++++++++++++++----------
liblwgeom/topo/lwt_edgeend_star.c | 8 +++
regress/run_test.pl | 1 -
sfcgal/regress/alphashape_components_expected | 4 +-
topology/postgis_topology.c | 6 +-
5 files changed, 75 insertions(+), 38 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list