[SCM] PostGIS branch master updated. 3.5.0-318-gc2d181ede

git at osgeo.org git at osgeo.org
Wed May 14 23:42:18 PDT 2025


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  c2d181ede78b74820cbd1f94d97241de5075a8e2 (commit)
       via  690cf7edf9e90fdb88a5ebc13581b9c47d167473 (commit)
       via  67fb694e3b118b8862e6be9e52d8d1efb7991460 (commit)
       via  15e974f8d5aaa3ae74cc92a2ffeacddc085bfc5f (commit)
      from  637410f77a5a127150a5b55e2c3a4589ee329799 (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 c2d181ede78b74820cbd1f94d97241de5075a8e2
Author: Loïc Bartoletti <loic.bartoletti at oslandia.com>
Date:   Thu May 15 08:33:20 2025 +0200

    docs(NEWS): SFCGAL: Add M Support

diff --git a/NEWS b/NEWS
index 709c09d44..2f80800e7 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ PostGIS 3.6.0
 
 * New Features *
 
+  - GH-805, Add M support for SFCGAL >= 1.5.0 (Loïc Bartoletti)
   - #5894, TotalTopologySize (Sandro Santilli)
   - #5890, ValidateTopologyPrecision, MakeTopologyPrecise (Sandro Santilli)
   - #5861, Add --drop-topology switch to pgtopo_import (Sandro Santilli)

commit 690cf7edf9e90fdb88a5ebc13581b9c47d167473
Author: Loïc Bartoletti <loic.bartoletti at oslandia.com>
Date:   Wed May 14 22:03:09 2025 +0200

    tests(SFCGAL): Add Z/M for SFCGAL / EWKT

diff --git a/liblwgeom/cunit/cu_sfcgal.c b/liblwgeom/cunit/cu_sfcgal.c
index f226b0ea9..a54bd5218 100644
--- a/liblwgeom/cunit/cu_sfcgal.c
+++ b/liblwgeom/cunit/cu_sfcgal.c
@@ -41,8 +41,29 @@ test_sfcgal_noop(void)
 	    "POLYHEDRALSURFACE(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
 	    "POLYHEDRALSURFACE(((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)),((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)))",
 	    "TIN(((0 0,0 -1,-1 1,0 0)),((0 0,1 0,0 -1,0 0)))",
+#if POSTGIS_SFCGAL_VERSION >= 10500
+	    // Z/M Support
+	    "POINTZM(1 2 3 4)",
+	    "LINESTRINGM(0 0 1, 1 1 2, 2 2 3)",
+	    "LINESTRINGZM(0 0 1 10, 1 1 2 20, 2 2 3 30)",
+	    "TRIANGLEM((0 0 1, 1 1 2, 2 0 3, 0 0 1))",
+	    "TRIANGLEZM((0 0 1 10, 1 1 2 20, 2 0 3 30, 0 0 1 10))",
+	    "POLYGONM((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1))",
+	    "POLYGONZM((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10))",
+	    "MULTIPOINTM(0 0 1, 1 1 2, 2 2 3)",
+	    "MULTIPOINTZM(0 0 1 10, 1 1 2 20, 2 2 3 30)",
+	    "MULTILINESTRINGM((0 0 1, 1 1 2),(2 2 3, 3 3 4))",
+	    "MULTILINESTRINGZM((0 0 1 10, 1 1 2 20),(2 2 3 30, 3 3 4 40))",
+	    "MULTIPOLYGONM(((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1)),((2 2 5, 2 3 6, 3 3 7, 3 2 8, 2 2 5)))",
+	    "MULTIPOLYGONZM(((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10)),((2 2 5 50, 2 3 6 60, 3 3 7 70, 3 2 8 80, 2 2 5 50)))",
+	    "TINM(((0 0 1, 0 1 2, 1 0 3, 0 0 1)),((0 0 1, 1 0 3, 1 1 4, 0 0 1)))",
+	    "TINZM(((0 0 1 10, 0 1 2 20, 1 0 3 30, 0 0 1 10)),((0 0 1 10, 1 0 3 30, 1 1 4 40, 0 0 1 10)))",
+	    "POLYHEDRALSURFACEM(((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1)),((0 0 1, 1 0 4, 1 -1 5, 0 -1 6, 0 0 1)))",
+	    "POLYHEDRALSURFACEZM(((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10)),((0 0 1 10, 1 0 4 40, 1 -1 5 50, 0 -1 6 60, 0 0 1 10)))",
+	    "GEOMETRYCOLLECTIONM(LINESTRING M(-1 -1 3, 2 19 25, -4 20 15),POLYGONM((0 0 10, 2 19 25, -4 20 15, 0 0 10)))",
+	    "GEOMETRYCOLLECTIONZM(LINESTRING ZM(-1 -1 3 4, 2 19 25 250, -4 20 15 150),POLYGONZM((0 0 10 100, 2 19 25 250, -4 20 15 150, 0 0 10 100)))",
+#endif
 	};
-
 	char *expected_ewkt[] = {
 	    "POINT(0 0.2)",
 	    "LINESTRING(-1 -1,-1 2.5,2 2,2 -1)",
@@ -60,6 +81,28 @@ test_sfcgal_noop(void)
 	    "POLYHEDRALSURFACE(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
 	    "POLYHEDRALSURFACE(((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)),((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)))",
 	    "TIN(((0 0,0 -1,-1 1,0 0)),((0 0,1 0,0 -1,0 0)))",
+#if POSTGIS_SFCGAL_VERSION >= 10500
+	    // Z/M Support
+	    "POINT(1 2 3 4)",
+	    "LINESTRINGM(0 0 1,1 1 2,2 2 3)",
+	    "LINESTRING(0 0 1 10,1 1 2 20,2 2 3 30)",
+	    "TRIANGLEM((0 0 1,1 1 2,2 0 3,0 0 1))",
+	    "TRIANGLE((0 0 1 10,1 1 2 20,2 0 3 30,0 0 1 10))",
+	    "POLYGONM((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1))",
+	    "POLYGON((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10))",
+	    "MULTIPOINTM(0 0 1,1 1 2,2 2 3)",
+	    "MULTIPOINT(0 0 1 10,1 1 2 20,2 2 3 30)",
+	    "MULTILINESTRINGM((0 0 1,1 1 2),(2 2 3,3 3 4))",
+	    "MULTILINESTRING((0 0 1 10,1 1 2 20),(2 2 3 30,3 3 4 40))",
+	    "MULTIPOLYGONM(((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1)),((2 2 5,2 3 6,3 3 7,3 2 8,2 2 5)))",
+	    "MULTIPOLYGON(((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10)),((2 2 5 50,2 3 6 60,3 3 7 70,3 2 8 80,2 2 5 50)))",
+	    "TINM(((0 0 1,0 1 2,1 0 3,0 0 1)),((0 0 1,1 0 3,1 1 4,0 0 1)))",
+	    "TIN(((0 0 1 10,0 1 2 20,1 0 3 30,0 0 1 10)),((0 0 1 10,1 0 3 30,1 1 4 40,0 0 1 10)))",
+	    "POLYHEDRALSURFACEM(((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1)),((0 0 1,1 0 4,1 -1 5,0 -1 6,0 0 1)))",
+	    "POLYHEDRALSURFACE(((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10)),((0 0 1 10,1 0 4 40,1 -1 5 50,0 -1 6 60,0 0 1 10)))",
+	    "GEOMETRYCOLLECTIONM(LINESTRINGM(-1 -1 3,2 19 25,-4 20 15),POLYGONM((0 0 10,2 19 25,-4 20 15,0 0 10)))",
+	    "GEOMETRYCOLLECTION(LINESTRING(-1 -1 3 4,2 19 25 250,-4 20 15 150),POLYGON((0 0 10 100,2 19 25 250,-4 20 15 150,0 0 10 100)))",
+#endif
 	};
 
 	for (i = 0; i < (sizeof ewkt / sizeof(char *)); i++)
@@ -79,7 +122,7 @@ test_sfcgal_noop(void)
 		}
 		out_ewkt = lwgeom_to_ewkt(geom_out);
 		if (strcmp(expected_ewkt[i], out_ewkt))
-			fprintf(stderr, "\nExp:   %s\nObt:  %s\n", expected_ewkt[i], out_ewkt);
+			fprintf(stderr, "\nTest case %zu failed:\nExp:\t%s\nObt:\t%s\n", i, expected_ewkt[i], out_ewkt);
 		ASSERT_STRING_EQUAL(expected_ewkt[i], out_ewkt);
 		lwfree(out_ewkt);
 		lwgeom_free(geom_out);

commit 67fb694e3b118b8862e6be9e52d8d1efb7991460
Author: Loïc Bartoletti <loic.bartoletti at oslandia.com>
Date:   Wed May 14 14:27:30 2025 +0200

    fix(SFCGAL): Add M support for ptarry_to_SFCGAL only for >= 1.5.0

diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c
index 242687b7c..433c01a51 100644
--- a/liblwgeom/lwgeom_sfcgal.c
+++ b/liblwgeom/lwgeom_sfcgal.c
@@ -27,15 +27,14 @@
 
 #if POSTGIS_SFCGAL_VERSION >= 20100
 #define sfcgal_triangulated_surface_num_triangles(g) sfcgal_triangulated_surface_num_patches((g))
-#define sfcgal_triangulated_surface_triangle_n(g,i)  sfcgal_triangulated_surface_patch_n((g), (i))
+#define sfcgal_triangulated_surface_triangle_n(g, i) sfcgal_triangulated_surface_patch_n((g), (i))
 #define sfcgal_triangulated_surface_add_triangle(g, p) sfcgal_triangulated_surface_add_patch((g), (p))
-#define sfcgal_polyhedral_surface_num_polygons(g)    sfcgal_polyhedral_surface_num_patches((g))
-#define sfcgal_polyhedral_surface_polygon_n(g,i)     sfcgal_polyhedral_surface_patch_n((g), (i))
+#define sfcgal_polyhedral_surface_num_polygons(g) sfcgal_polyhedral_surface_num_patches((g))
+#define sfcgal_polyhedral_surface_polygon_n(g, i) sfcgal_polyhedral_surface_patch_n((g), (i))
 #define sfcgal_geometry_collection_num_geometries(g) sfcgal_geometry_num_geometries((g))
 #define sfcgal_polyhedral_surface_add_polygon(g, p) sfcgal_polyhedral_surface_add_patch((g), (p))
 #endif
 
-
 static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type);
 static POINTARRAY *ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D);
 static sfcgal_geometry_t *ptarray_to_SFCGAL(const POINTARRAY *pa, int type);
@@ -56,10 +55,11 @@ lwgeom_sfcgal_full_version()
 #if POSTGIS_SFCGAL_VERSION >= 10400
 	const char *version = sfcgal_full_version();
 #else
-	char *version = (char*)lwalloc(MAX_LENGTH_SFCGAL_FULL_VERSION);
-	snprintf(version, MAX_LENGTH_SFCGAL_FULL_VERSION,
-		"SFCGAL=\"%s\" CGAL=\"Unknown\" Boost=\"Unknown\"",
-		sfcgal_version());
+	char *version = (char *)lwalloc(MAX_LENGTH_SFCGAL_FULL_VERSION);
+	snprintf(version,
+		 MAX_LENGTH_SFCGAL_FULL_VERSION,
+		 "SFCGAL=\"%s\" CGAL=\"Unknown\" Boost=\"Unknown\"",
+		 sfcgal_version());
 #endif
 	return version;
 }
@@ -157,8 +157,7 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 
 	switch (sfcgal_geometry_type_id(geom))
 	{
-	case SFCGAL_TYPE_POINT:
-	{
+	case SFCGAL_TYPE_POINT: {
 		pa = ptarray_construct(want3d, is_measured, 1);
 		point.x = sfcgal_point_x(geom);
 		point.y = sfcgal_point_y(geom);
@@ -177,8 +176,7 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 	}
 	break;
 
-	case SFCGAL_TYPE_LINESTRING:
-	{
+	case SFCGAL_TYPE_LINESTRING: {
 		npoints = sfcgal_linestring_num_points(geom);
 		pa = ptarray_construct(want3d, is_measured, npoints);
 
@@ -203,8 +201,7 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 	}
 	break;
 
-	case SFCGAL_TYPE_TRIANGLE:
-	{
+	case SFCGAL_TYPE_TRIANGLE: {
 		pa = ptarray_construct(want3d, is_measured, 4);
 
 		for (i = 0; i < 4; i++)
@@ -236,80 +233,85 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 	return pa;
 }
 
-/*
- * Create a SFCGAL point based on dimensional flags (2D, 3D, 2D+M, 3D+M).
+/**
+ * Create a SFCGAL point based on dimensional flags (XY, XYZ, XYM, XYZM).
  */
 static sfcgal_geometry_t *
 create_sfcgal_point_by_dimensions(double x, double y, double z, double m, int is_3d, int is_measured)
 {
-    if (is_3d && is_measured)
-        return sfcgal_point_create_from_xyzm(x, y, z, m);
-    else if (is_3d)
-        return sfcgal_point_create_from_xyz(x, y, z);
-    else if (is_measured)
-        return sfcgal_point_create_from_xym(x, y, m);
-    else
-        return sfcgal_point_create_from_xy(x, y);
+#if POSTGIS_SFCGAL_VERSION >= 10500
+	if (is_3d && is_measured)
+		return sfcgal_point_create_from_xyzm(x, y, z, m);
+	else if (is_3d)
+		return sfcgal_point_create_from_xyz(x, y, z);
+	else if (is_measured)
+		return sfcgal_point_create_from_xym(x, y, m);
+	else
+		return sfcgal_point_create_from_xy(x, y);
+#else
+	(void)is_measured;
+	(void)m;
+	if (is_3d)
+		return sfcgal_point_create_from_xyz(x, y, z);
+	else
+		return sfcgal_point_create_from_xy(x, y);
+#endif
 }
 
-/*
+/**
  * Convert a PostGIS pointarray to SFCGAL structure
- *
- * Used for simple LWGEOM geometry POINT, LINESTRING, TRIANGLE
- * and POLYGON rings
  */
 static sfcgal_geometry_t *
 ptarray_to_SFCGAL(const POINTARRAY *pa, int type)
 {
-    POINT4D point;
-    int is_3d, is_measured;
-    uint32_t i;
+	POINT4D point;
+	int is_3d, is_measured;
+	uint32_t i;
 
-    assert(pa);
+	assert(pa);
 
-    is_3d = FLAGS_GET_Z(pa->flags) != 0;
-    is_measured = FLAGS_GET_M(pa->flags) != 0;
+	is_3d = FLAGS_GET_Z(pa->flags) != 0;
+	is_measured = FLAGS_GET_M(pa->flags) != 0;
 
-    switch (type)
-    {
-    case POINTTYPE:
-    {
-        getPoint4d_p(pa, 0, &point);
-        return create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
-    }
-    break;
-    case LINETYPE:
-    {
-        sfcgal_geometry_t *line = sfcgal_linestring_create();
-        for (i = 0; i < pa->npoints; i++)
-        {
-            getPoint4d_p(pa, i, &point);
-            sfcgal_linestring_add_point(line,
-                create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured));
-        }
-        return line;
-    }
-    break;
-    case TRIANGLETYPE:
-    {
-        sfcgal_geometry_t *triangle = sfcgal_triangle_create();
-        sfcgal_geometry_t *vertex;
-
-        for (i = 0; i < 3; i++)
-        {
-            getPoint4d_p(pa, i, &point);
-            vertex = create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
-            sfcgal_triangle_set_vertex(triangle, i, vertex);
-        }
-
-        return triangle;
-    }
-    break;
-    /* Other SFCGAL types should not be called directly ... */
-    default:
-        lwerror("ptarray_from_SFCGAL: Unknown Type");
-        return NULL;
-    }
+	switch (type)
+	{
+	case POINTTYPE: {
+		getPoint4d_p(pa, 0, &point);
+		return create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
+	}
+	break;
+	case LINETYPE: {
+		sfcgal_geometry_t *line = sfcgal_linestring_create();
+		for (i = 0; i < pa->npoints; i++)
+		{
+			getPoint4d_p(pa, i, &point);
+			sfcgal_linestring_add_point(
+			    line,
+			    create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured));
+		}
+		return line;
+	}
+	break;
+	case TRIANGLETYPE: {
+		sfcgal_geometry_t *triangle = sfcgal_triangle_create();
+		for (i = 0; i < 3; i++)
+		{
+			getPoint4d_p(pa, i, &point);
+			sfcgal_geometry_t *vertex =
+			    create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
+			if (vertex)
+			{
+				sfcgal_triangle_set_vertex(triangle, i, vertex);
+				sfcgal_geometry_delete(vertex);
+			}
+		}
+		return triangle;
+	}
+	break;
+	default:
+		lwerror("ptarray_to_SFCGAL: Unknown Type");
+		return NULL;
+	}
 }
 
 /*
@@ -330,8 +332,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 
 	switch (sfcgal_geometry_type_id(geom))
 	{
-	case SFCGAL_TYPE_POINT:
-	{
+	case SFCGAL_TYPE_POINT: {
 		if (sfcgal_geometry_is_empty(geom))
 			return (LWGEOM *)lwpoint_construct_empty(srid, want3d, 0);
 
@@ -339,8 +340,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 		return (LWGEOM *)lwpoint_construct(srid, NULL, pa);
 	}
 
-	case SFCGAL_TYPE_LINESTRING:
-	{
+	case SFCGAL_TYPE_LINESTRING: {
 		if (sfcgal_geometry_is_empty(geom))
 			return (LWGEOM *)lwline_construct_empty(srid, want3d, 0);
 
@@ -348,8 +348,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 		return (LWGEOM *)lwline_construct(srid, NULL, pa);
 	}
 
-	case SFCGAL_TYPE_TRIANGLE:
-	{
+	case SFCGAL_TYPE_TRIANGLE: {
 		if (sfcgal_geometry_is_empty(geom))
 			return (LWGEOM *)lwtriangle_construct_empty(srid, want3d, 0);
 
@@ -357,8 +356,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 		return (LWGEOM *)lwtriangle_construct(srid, NULL, pa);
 	}
 
-	case SFCGAL_TYPE_POLYGON:
-	{
+	case SFCGAL_TYPE_POLYGON: {
 		if (sfcgal_geometry_is_empty(geom))
 			return (LWGEOM *)lwpoly_construct_empty(srid, want3d, 0);
 
@@ -376,8 +374,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 	case SFCGAL_TYPE_MULTILINESTRING:
 	case SFCGAL_TYPE_MULTIPOLYGON:
 	case SFCGAL_TYPE_MULTISOLID:
-	case SFCGAL_TYPE_GEOMETRYCOLLECTION:
-	{
+	case SFCGAL_TYPE_GEOMETRYCOLLECTION: {
 		ngeoms = sfcgal_geometry_collection_num_geometries(geom);
 		LWGEOM **geoms = NULL;
 		if (ngeoms)
@@ -418,8 +415,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 	/* TODO curve types handling */
 #endif
 
-	case SFCGAL_TYPE_POLYHEDRALSURFACE:
-	{
+	case SFCGAL_TYPE_POLYHEDRALSURFACE: {
 		ngeoms = sfcgal_polyhedral_surface_num_polygons(geom);
 
 		LWGEOM **geoms = NULL;
@@ -436,8 +432,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 	}
 
 	/* Solid is map as a closed PolyhedralSurface (for now) */
-	case SFCGAL_TYPE_SOLID:
-	{
+	case SFCGAL_TYPE_SOLID: {
 		nshells = sfcgal_solid_num_shells(geom);
 
 		for (ngeoms = 0, i = 0; i < nshells; i++)
@@ -466,8 +461,7 @@ SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
 		return rgeom;
 	}
 
-	case SFCGAL_TYPE_TRIANGULATEDSURFACE:
-	{
+	case SFCGAL_TYPE_TRIANGULATEDSURFACE: {
 		ngeoms = sfcgal_triangulated_surface_num_triangles(geom);
 		LWGEOM **geoms = NULL;
 		if (ngeoms)
@@ -498,8 +492,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 
 	switch (geom->type)
 	{
-	case POINTTYPE:
-	{
+	case POINTTYPE: {
 		const LWPOINT *lwp = (const LWPOINT *)geom;
 		if (lwgeom_is_empty(geom))
 			return sfcgal_point_create();
@@ -508,8 +501,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	}
 	break;
 
-	case LINETYPE:
-	{
+	case LINETYPE: {
 		const LWLINE *line = (const LWLINE *)geom;
 		if (lwgeom_is_empty(geom))
 			return sfcgal_linestring_create();
@@ -518,8 +510,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	}
 	break;
 
-	case TRIANGLETYPE:
-	{
+	case TRIANGLETYPE: {
 		const LWTRIANGLE *triangle = (const LWTRIANGLE *)geom;
 		if (lwgeom_is_empty(geom))
 			return sfcgal_triangle_create();
@@ -527,8 +518,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	}
 	break;
 
-	case POLYGONTYPE:
-	{
+	case POLYGONTYPE: {
 		const LWPOLY *poly = (const LWPOLY *)geom;
 		uint32_t nrings = poly->nrings - 1;
 
@@ -550,8 +540,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	case MULTIPOINTTYPE:
 	case MULTILINETYPE:
 	case MULTIPOLYGONTYPE:
-	case COLLECTIONTYPE:
-	{
+	case COLLECTIONTYPE: {
 		if (geom->type == MULTIPOINTTYPE)
 			ret_geom = sfcgal_multi_point_create();
 		else if (geom->type == MULTILINETYPE)
@@ -572,8 +561,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	}
 	break;
 
-	case POLYHEDRALSURFACETYPE:
-	{
+	case POLYHEDRALSURFACETYPE: {
 		const LWPSURFACE *lwp = (const LWPSURFACE *)geom;
 		ret_geom = sfcgal_polyhedral_surface_create();
 
@@ -593,8 +581,7 @@ LWGEOM2SFCGAL(const LWGEOM *geom)
 	}
 	break;
 
-	case TINTYPE:
-	{
+	case TINTYPE: {
 		const LWTIN *lwp = (const LWTIN *)geom;
 		ret_geom = sfcgal_triangulated_surface_create();
 

commit 15e974f8d5aaa3ae74cc92a2ffeacddc085bfc5f
Author: Loïc Bartoletti <loic.bartoletti at oslandia.com>
Date:   Wed May 14 06:22:06 2025 +0200

    fix(SFCGAL): Add M support for ptarry_to_SFCGAL

diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c
index baee870d5..242687b7c 100644
--- a/liblwgeom/lwgeom_sfcgal.c
+++ b/liblwgeom/lwgeom_sfcgal.c
@@ -236,6 +236,22 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 	return pa;
 }
 
+/*
+ * Create a SFCGAL point based on dimensional flags (2D, 3D, 2D+M, 3D+M).
+ */
+static sfcgal_geometry_t *
+create_sfcgal_point_by_dimensions(double x, double y, double z, double m, int is_3d, int is_measured)
+{
+    if (is_3d && is_measured)
+        return sfcgal_point_create_from_xyzm(x, y, z, m);
+    else if (is_3d)
+        return sfcgal_point_create_from_xyz(x, y, z);
+    else if (is_measured)
+        return sfcgal_point_create_from_xym(x, y, m);
+    else
+        return sfcgal_point_create_from_xy(x, y);
+}
+
 /*
  * Convert a PostGIS pointarray to SFCGAL structure
  *
@@ -245,79 +261,55 @@ ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
 static sfcgal_geometry_t *
 ptarray_to_SFCGAL(const POINTARRAY *pa, int type)
 {
-	POINT3DZ point;
-	int is_3d;
-	uint32_t i;
+    POINT4D point;
+    int is_3d, is_measured;
+    uint32_t i;
 
-	assert(pa);
+    assert(pa);
 
-	is_3d = FLAGS_GET_Z(pa->flags) != 0;
+    is_3d = FLAGS_GET_Z(pa->flags) != 0;
+    is_measured = FLAGS_GET_M(pa->flags) != 0;
 
-	switch (type)
-	{
-	case POINTTYPE:
-	{
-		getPoint3dz_p(pa, 0, &point);
-		if (is_3d)
-			return sfcgal_point_create_from_xyz(point.x, point.y, point.z);
-		else
-			return sfcgal_point_create_from_xy(point.x, point.y);
-	}
-	break;
+    switch (type)
+    {
+    case POINTTYPE:
+    {
+        getPoint4d_p(pa, 0, &point);
+        return create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
+    }
+    break;
+    case LINETYPE:
+    {
+        sfcgal_geometry_t *line = sfcgal_linestring_create();
+        for (i = 0; i < pa->npoints; i++)
+        {
+            getPoint4d_p(pa, i, &point);
+            sfcgal_linestring_add_point(line,
+                create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured));
+        }
+        return line;
+    }
+    break;
+    case TRIANGLETYPE:
+    {
+        sfcgal_geometry_t *triangle = sfcgal_triangle_create();
+        sfcgal_geometry_t *vertex;
 
-	case LINETYPE:
-	{
-		sfcgal_geometry_t *line = sfcgal_linestring_create();
+        for (i = 0; i < 3; i++)
+        {
+            getPoint4d_p(pa, i, &point);
+            vertex = create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
+            sfcgal_triangle_set_vertex(triangle, i, vertex);
+        }
 
-		for (i = 0; i < pa->npoints; i++)
-		{
-			getPoint3dz_p(pa, i, &point);
-			if (is_3d)
-			{
-				sfcgal_linestring_add_point(line,
-							    sfcgal_point_create_from_xyz(point.x, point.y, point.z));
-			}
-			else
-			{
-				sfcgal_linestring_add_point(line, sfcgal_point_create_from_xy(point.x, point.y));
-			}
-		}
-
-		return line;
-	}
-	break;
-
-	case TRIANGLETYPE:
-	{
-		sfcgal_geometry_t *triangle = sfcgal_triangle_create();
-
-		getPoint3dz_p(pa, 0, &point);
-		if (is_3d)
-			sfcgal_triangle_set_vertex_from_xyz(triangle, 0, point.x, point.y, point.z);
-		else
-			sfcgal_triangle_set_vertex_from_xy(triangle, 0, point.x, point.y);
-
-		getPoint3dz_p(pa, 1, &point);
-		if (is_3d)
-			sfcgal_triangle_set_vertex_from_xyz(triangle, 1, point.x, point.y, point.z);
-		else
-			sfcgal_triangle_set_vertex_from_xy(triangle, 1, point.x, point.y);
-
-		getPoint3dz_p(pa, 2, &point);
-		if (is_3d)
-			sfcgal_triangle_set_vertex_from_xyz(triangle, 2, point.x, point.y, point.z);
-		else
-			sfcgal_triangle_set_vertex_from_xy(triangle, 2, point.x, point.y);
-
-		return triangle;
-	}
-	break;
-
-	/* Other SFCGAL types should not be called directly ... */
-	default:
-		lwerror("ptarray_from_SFCGAL: Unknown Type");
-		return NULL;
-	}
+        return triangle;
+    }
+    break;
+    /* Other SFCGAL types should not be called directly ... */
+    default:
+        lwerror("ptarray_from_SFCGAL: Unknown Type");
+        return NULL;
+    }
 }
 
 /*

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

Summary of changes:
 NEWS                        |   1 +
 liblwgeom/cunit/cu_sfcgal.c |  47 +++++++++++-
 liblwgeom/lwgeom_sfcgal.c   | 173 +++++++++++++++++++-------------------------
 3 files changed, 122 insertions(+), 99 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list