[SCM] PostGIS branch master updated. 3.6.0rc2-469-gbb1a71e15

git at osgeo.org git at osgeo.org
Fri Apr 17 00:38: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  bb1a71e15fdece2cab099682be270683b529cbc9 (commit)
      from  123d1687331c22066c5e8c901e5a2c7cd46c0ba8 (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 bb1a71e15fdece2cab099682be270683b529cbc9
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Apr 17 09:37:46 2026 +0200

    Reduce polygon construction when all we need is CCW detection of ring

diff --git a/liblwgeom/topo/liblwgeom_topo.h b/liblwgeom/topo/liblwgeom_topo.h
index d3e3cd133..fb25c3a10 100644
--- a/liblwgeom/topo/liblwgeom_topo.h
+++ b/liblwgeom/topo/liblwgeom_topo.h
@@ -1430,6 +1430,6 @@ int lwt_GetFaceEdges(LWT_TOPOLOGY* topo, LWT_ELEMID face, LWT_ELEMID **edges);
  */
 LWGEOM* lwt_GetFaceGeometry(LWT_TOPOLOGY* topo, LWT_ELEMID face);
 
-int lwt_IsTopoRingCCW(const LWGEOM *geom);
+int lwt_IsTopoRingCCW(const POINTARRAY *pa);
 
 #endif /* LIBLWGEOM_TOPO_H */
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index 584b4d210..6d0144bb9 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -1881,10 +1881,8 @@ _lwt_GetInteriorEdgePoint(const LWLINE* edge, POINT2D* ip)
 }
 
 int
-lwt_IsTopoRingCCW(const LWGEOM *lwg)
+lwt_IsTopoRingCCW(const POINTARRAY *pa)
 {
-  LWPOLY *poly = lwgeom_as_lwpoly(lwg);
-  POINTARRAY *pa;
   const POINT2D *P1;
   const POINT2D *P2;
   const POINT2D *P3;
@@ -1894,11 +1892,6 @@ lwt_IsTopoRingCCW(const LWGEOM *lwg)
   uint32_t i;
   int ret;
 
-  if ( ! poly ) return 0;
-  if ( ! poly->nrings ) return 0;
-
-  pa = poly->rings[0];
-
   if (! pa || pa->npoints < 3 )
     return 0;
 
@@ -2048,6 +2041,8 @@ _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num
     return NULL;
   }
 
+  *isccw = lwt_IsTopoRingCCW(full_ring_pa);
+
   POINTARRAY **points = lwalloc(sizeof(POINTARRAY*));
   points[0] = full_ring_pa;
 
@@ -2056,8 +2051,6 @@ _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num
    */
   LWPOLY* shell = lwpoly_construct(0, 0, 1, points);
 
-  *isccw = lwt_IsTopoRingCCW(lwpoly_as_lwgeom(shell));
-
   return shell;
 }
 
diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c
index 769cececb..0599fc010 100644
--- a/topology/postgis_topology.c
+++ b/topology/postgis_topology.c
@@ -5828,10 +5828,31 @@ Datum TopoRingIsCCW(PG_FUNCTION_ARGS)
   GSERIALIZED *geom;
   LWGEOM *lwgeom;
   int isCCW;
+  const POINTARRAY *pa;
 
   geom = PG_GETARG_GSERIALIZED_P(0);
   lwgeom = lwgeom_from_gserialized(geom);
-  isCCW = lwt_IsTopoRingCCW(lwgeom);
+
+  if ( lwgeom_is_empty(lwgeom) )
+  {
+    PG_RETURN_BOOL(false);
+  }
+
+  if (lwgeom->type == POLYGONTYPE)
+  {
+    pa = ((const LWPOLY *)lwgeom)->rings[0];
+  }
+  else if (lwgeom->type == LINETYPE)
+  {
+    pa = ((const LWLINE *)lwgeom)->points;
+  }
+  else
+  {
+    lwpgerror("Unsupported geometry type passed to TopoRingIsCCW");
+    PG_RETURN_NULL();
+  }
+
+  isCCW = lwt_IsTopoRingCCW(pa);
   lwgeom_free(lwgeom);
 
   PG_FREE_IF_COPY(geom, 0);
diff --git a/topology/sql/manage/ValidateTopology.sql.in b/topology/sql/manage/ValidateTopology.sql.in
index 08ccd06f5..fb6f23c02 100644
--- a/topology/sql/manage/ValidateTopology.sql.in
+++ b/topology/sql/manage/ValidateTopology.sql.in
@@ -394,7 +394,6 @@ $BODY$
 DECLARE
   retrec topology.ValidateTopology_ReturnType;
   rec RECORD;
-  ring_poly GEOMETRY;
   is_shell BOOLEAN;
   found_rings INT := 0;
   found_shells INT := 0;
@@ -553,8 +552,7 @@ BEGIN
     IF ST_NPoints(rec.ring_geom) > 3 AND
        rec.num_edges != rec.distinct_edges * 2
     THEN
-      ring_poly := ST_MakePolygon(rec.ring_geom);
-      is_shell := topology.TopoRingIsCCW(ring_poly);
+      is_shell := topology.TopoRingIsCCW(rec.ring_geom);
     END IF;
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
@@ -571,7 +569,7 @@ BEGIN
       BEGIN
         INSERT INTO shell_check VALUES (
           rec.side_faces[1],
-          ring_poly
+          ST_MakePolygon(rec.ring_geom)
         );
         found_shells := found_shells + 1;
       EXCEPTION WHEN unique_violation THEN

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

Summary of changes:
 liblwgeom/topo/liblwgeom_topo.h             |  2 +-
 liblwgeom/topo/lwgeom_topo.c                | 13 +++----------
 topology/postgis_topology.c                 | 23 ++++++++++++++++++++++-
 topology/sql/manage/ValidateTopology.sql.in |  6 ++----
 4 files changed, 28 insertions(+), 16 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list