[postgis-tickets] [SCM] PostGIS branch master updated. 1152d813c0dbd00b61506908d8c0d78902a8ea43

git at osgeo.org git at osgeo.org
Tue Jan 14 11:00:41 PST 2020


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  1152d813c0dbd00b61506908d8c0d78902a8ea43 (commit)
      from  2ee8e58e5f2401951cd9cd9765274100c324376d (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 1152d813c0dbd00b61506908d8c0d78902a8ea43
Author: Kristian Thy <thy at 42.dk>
Date:   Wed Jan 8 10:19:47 2020 +0100

    Optional value params for Force3D*, Force4D functions
    
    Changes internal signature of lwgeom_force_* functions.
    
    Closes #3057
    Closes https://github.com/postgis/postgis/pull/531
    
    Author: Kristian Thy
    
    Signed-off-by: Raúl Marín <git at rmr.ninja>

diff --git a/NEWS b/NEWS
index 27229a2..8e792b4 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PostGIS 3.1.0
   - #4601, Add ST_TileEnvelope margin argument (Yuri Astrakhan)
   - #2972, Add quiet mode (-q) to pgsql2shp (Kristian Thy)
   - #4617, Add configure switch `--without-phony-revision` (Raúl Marín)
+  - #3057, Optional value params for Force3D*, Force4D functions (Kristian Thy)
 
 * Enhancements *
   - #4539, Unify libm includes (Raúl Marín)
diff --git a/doc/reference_editor.xml b/doc/reference_editor.xml
index ca08002..7e52ea2 100644
--- a/doc/reference_editor.xml
+++ b/doc/reference_editor.xml
@@ -254,6 +254,7 @@ SELECT  ST_AsEWKT(ST_Force2D('POLYGON((0 0 2,0 5 2,5 0 2,0 0 2),(1 1 2,3 1 2,1 3
 		  <funcprototype>
 			<funcdef>geometry <function>ST_Force3D</function></funcdef>
 			<paramdef><type>geometry </type> <parameter>geomA</parameter></paramdef>
+			<paramdef><type>float </type> <parameter>Zvalue = 0.0</parameter></paramdef>
 		  </funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -261,10 +262,11 @@ SELECT  ST_AsEWKT(ST_Force2D('POLYGON((0 0 2,0 5 2,5 0 2,0 0 2),(1 1 2,3 1 2,1 3
 	  <refsection>
 		<title>Description</title>
 
-		<para>Forces the geometries into XYZ mode.  This is an alias for ST_Force_3DZ. If a geometry has no Z component, then a 0 Z coordinate is tacked on.</para>
+        <para>Forces the geometries into XYZ mode. This is an alias for ST_Force3DZ. If a geometry has no Z component, then a <parameter>Zvalue</parameter> Z coordinate is tacked on.</para>
 
 		<para>Enhanced: 2.0.0 support for Polyhedral surfaces was introduced.</para>
 		<para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_3D.</para>
+		<para>Changed: 3.1.0. Added support for supplying a non-zero Z value.</para>
 		<para>&P_support;</para>
 		<para>&curve_support;</para>
 		<para>&Z_support;</para>
@@ -310,6 +312,7 @@ SELECT  ST_AsEWKT(ST_Force3D('POLYGON((0 0,0 5,5 0,0 0),(1 1,3 1,1 3,1 1))'));
 		  <funcprototype>
 			<funcdef>geometry <function>ST_Force3DZ</function></funcdef>
 			<paramdef><type>geometry </type> <parameter>geomA</parameter></paramdef>
+			<paramdef><type>float </type> <parameter>Zvalue = 0.0</parameter></paramdef>
 		  </funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -317,10 +320,11 @@ SELECT  ST_AsEWKT(ST_Force3D('POLYGON((0 0,0 5,5 0,0 0),(1 1,3 1,1 3,1 1))'));
 	  <refsection>
 		<title>Description</title>
 
-		<para>Forces the geometries into XYZ mode.  This is a synonym for ST_Force3DZ. If a geometry has no Z component, then a 0 Z coordinate is tacked on.</para>
+		<para>Forces the geometries into XYZ mode. If a geometry has no Z component, then a <parameter>Zvalue</parameter> Z coordinate is tacked on.</para>
 
 		<para>Enhanced: 2.0.0 support for Polyhedral surfaces was introduced.</para>
 		<para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_3DZ.</para>
+		<para>Changed: 3.1.0. Added support for supplying a non-zero Z value.</para>
 		<para>&P_support;</para>
 		<para>&Z_support;</para>
 		<para>&curve_support;</para>
@@ -366,6 +370,7 @@ SELECT  ST_AsEWKT(ST_Force3DZ('POLYGON((0 0,0 5,5 0,0 0),(1 1,3 1,1 3,1 1))'));
 		  <funcprototype>
 			<funcdef>geometry <function>ST_Force3DM</function></funcdef>
 			<paramdef><type>geometry </type> <parameter>geomA</parameter></paramdef>
+			<paramdef><type>float </type> <parameter>Mvalue = 0.0</parameter></paramdef>
 		  </funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -373,10 +378,11 @@ SELECT  ST_AsEWKT(ST_Force3DZ('POLYGON((0 0,0 5,5 0,0 0),(1 1,3 1,1 3,1 1))'));
 	  <refsection>
 		<title>Description</title>
 
-		<para>Forces the geometries into XYM mode.  If a geometry has no M component, then a 0 M coordinate is tacked on.  If it has a Z component, then Z is removed</para>
+		<para>Forces the geometries into XYM mode. If a geometry has no M component, then a <parameter>Mvalue</parameter> M coordinate is tacked on.  If it has a Z component, then Z is removed</para>
 
 
-		  <para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_3DM.</para>
+		<para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_3DM.</para>
+		<para>Changed: 3.1.0. Added support for supplying a non-zero M value.</para>
 		<para>&curve_support;</para>
 	  </refsection>
 
@@ -421,6 +427,8 @@ SELECT  ST_AsEWKT(ST_Force3DM('POLYGON((0 0 1,0 5 1,5 0 1,0 0 1),(1 1 1,3 1 1,1
 		  <funcprototype>
 			<funcdef>geometry <function>ST_Force4D</function></funcdef>
 			<paramdef><type>geometry </type> <parameter>geomA</parameter></paramdef>
+			<paramdef><type>float </type> <parameter>Zvalue = 0.0</parameter></paramdef>
+			<paramdef><type>float </type> <parameter>Mvalue = 0.0</parameter></paramdef>
 		  </funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -428,9 +436,10 @@ SELECT  ST_AsEWKT(ST_Force3DM('POLYGON((0 0 1,0 5 1,5 0 1,0 0 1),(1 1 1,3 1 1,1
 	  <refsection>
 		<title>Description</title>
 
-		<para>Forces the geometries into XYZM mode.  0 is tacked on for missing Z and M dimensions. </para>
+		<para>Forces the geometries into XYZM mode. <parameter>Zvalue</parameter> and <parameter>Mvalue</parameter> is tacked on for missing Z and M dimensions, respectively. </para>
 
-		  <para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_4D.</para>
+		<para>Changed: 2.1.0. Up to 2.0.x this was called ST_Force_4D.</para>
+		<para>Changed: 3.1.0. Added support for supplying non-zero Z and M values.</para>
 		<para>&Z_support;</para>
 		<para>&curve_support;</para>
 	  </refsection>
diff --git a/liblwgeom/cunit/Makefile.in b/liblwgeom/cunit/Makefile.in
index 2780e11..008821b 100644
--- a/liblwgeom/cunit/Makefile.in
+++ b/liblwgeom/cunit/Makefile.in
@@ -50,6 +50,7 @@ OBJS=	\
 	cu_stringbuffer.o \
 	cu_triangulate.o \
 	cu_homogenize.o \
+	cu_force_dims.o \
 	cu_force_sfs.o \
 	cu_out_twkb.o \
 	cu_out_wkt.o \
diff --git a/liblwgeom/cunit/cu_force_dims.c b/liblwgeom/cunit/cu_force_dims.c
new file mode 100644
index 0000000..68a6862
--- /dev/null
+++ b/liblwgeom/cunit/cu_force_dims.c
@@ -0,0 +1,118 @@
+/**********************************************************************
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.net
+ *
+ * Copyright (C) 2008 Paul Ramsey
+ * Copyright (C) 2020 Kristian Thy <thy at 42.dk>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "CUnit/Basic.h"
+
+#include "liblwgeom_internal.h"
+#include "cu_tester.h"
+
+static void
+test_force_2d(void)
+{
+	LWGEOM *geom;
+	LWGEOM *geom2d;
+	char *wkt_out;
+
+	geom = lwgeom_from_wkt("CIRCULARSTRINGM(-5 0 4,0 5 3,5 0 2,10 -5 1,15 0 0)", LW_PARSER_CHECK_NONE);
+	geom2d = lwgeom_force_2d(geom);
+	wkt_out = lwgeom_to_ewkt(geom2d);
+	CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)", wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom2d);
+	lwfree(wkt_out);
+
+	geom = lwgeom_from_wkt(
+	    "GEOMETRYCOLLECTION(POINT(0 0 0),LINESTRING(1 1 1,2 2 2),POLYGON((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),CURVEPOLYGON(CIRCULARSTRING(0 0 0,1 1 1,2 2 2,1 1 1,0 0 0)))",
+	    LW_PARSER_CHECK_NONE);
+	geom2d = lwgeom_force_2d(geom);
+	wkt_out = lwgeom_to_ewkt(geom2d);
+	CU_ASSERT_STRING_EQUAL(
+	    "GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2),POLYGON((0 0,0 1,1 1,1 0,0 0)),CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 2,1 1,0 0)))",
+	    wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom2d);
+	lwfree(wkt_out);
+}
+
+static void
+test_force_3dm(void)
+{
+	LWGEOM *geom;
+	LWGEOM *geom3dm;
+	char *wkt_out;
+
+	geom = lwgeom_from_wkt("CIRCULARSTRING(-5 0 4,0 5 3,5 0 2,10 -5 1,15 0 0)", LW_PARSER_CHECK_NONE);
+	geom3dm = lwgeom_force_3dm(geom, 1);
+	wkt_out = lwgeom_to_ewkt(geom3dm);
+	CU_ASSERT_STRING_EQUAL("CIRCULARSTRINGM(-5 0 1,0 5 1,5 0 1,10 -5 1,15 0 1)", wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom3dm);
+	lwfree(wkt_out);
+}
+
+static void
+test_force_3dz(void)
+{
+	LWGEOM *geom;
+	LWGEOM *geom3dz;
+	char *wkt_out;
+
+	geom = lwgeom_from_wkt("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)", LW_PARSER_CHECK_NONE);
+	geom3dz = lwgeom_force_3dz(geom, -99);
+	wkt_out = lwgeom_to_ewkt(geom3dz);
+	CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0 -99,0 5 -99,5 0 -99,10 -5 -99,15 0 -99)", wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom3dz);
+	lwfree(wkt_out);
+
+	geom = lwgeom_from_wkt("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)", LW_PARSER_CHECK_NONE);
+	geom3dz = lwgeom_force_3dz(geom, 0.0);
+	wkt_out = lwgeom_to_ewkt(geom3dz);
+	CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0 0,0 5 0,5 0 0,10 -5 0,15 0 0)", wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom3dz);
+	lwfree(wkt_out);
+}
+
+static void
+test_force_4d(void)
+{
+	LWGEOM *geom;
+	LWGEOM *geom4d;
+	char *wkt_out;
+
+	geom = lwgeom_from_wkt("POINT(1 2)", LW_PARSER_CHECK_NONE);
+	geom4d = lwgeom_force_4d(geom, 3, 4);
+	wkt_out = lwgeom_to_ewkt(geom4d);
+	CU_ASSERT_STRING_EQUAL("POINT(1 2 3 4)", wkt_out);
+	lwgeom_free(geom);
+	lwgeom_free(geom4d);
+	lwfree(wkt_out);
+}
+
+/*
+** Used by the test harness to register the tests in this file.
+*/
+void force_dims_suite_setup(void);
+void
+force_dims_suite_setup(void)
+{
+	CU_pSuite suite = CU_add_suite("force_dims", NULL, NULL);
+	PG_ADD_TEST(suite, test_force_2d);
+	PG_ADD_TEST(suite, test_force_3dm);
+	PG_ADD_TEST(suite, test_force_3dz);
+	PG_ADD_TEST(suite, test_force_4d);
+}
diff --git a/liblwgeom/cunit/cu_misc.c b/liblwgeom/cunit/cu_misc.c
index d1f76eb..8cb483e 100644
--- a/liblwgeom/cunit/cu_misc.c
+++ b/liblwgeom/cunit/cu_misc.c
@@ -18,29 +18,6 @@
 #include "cu_tester.h"
 
 
-static void test_misc_force_2d(void)
-{
-	LWGEOM *geom;
-	LWGEOM *geom2d;
-	char *wkt_out;
-
-	geom = lwgeom_from_wkt("CIRCULARSTRINGM(-5 0 4,0 5 3,5 0 2,10 -5 1,15 0 0)", LW_PARSER_CHECK_NONE);
-	geom2d = lwgeom_force_2d(geom);
-	wkt_out = lwgeom_to_ewkt(geom2d);
-	CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)",wkt_out);
-	lwgeom_free(geom);
-	lwgeom_free(geom2d);
-	lwfree(wkt_out);
-
-	geom = lwgeom_from_wkt("GEOMETRYCOLLECTION(POINT(0 0 0),LINESTRING(1 1 1,2 2 2),POLYGON((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),CURVEPOLYGON(CIRCULARSTRING(0 0 0,1 1 1,2 2 2,1 1 1,0 0 0)))", LW_PARSER_CHECK_NONE);
-	geom2d = lwgeom_force_2d(geom);
-	wkt_out = lwgeom_to_ewkt(geom2d);
-	CU_ASSERT_STRING_EQUAL("GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2),POLYGON((0 0,0 1,1 1,1 0,0 0)),CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 2,1 1,0 0)))",wkt_out);
-	lwgeom_free(geom);
-	lwgeom_free(geom2d);
-	lwfree(wkt_out);
-}
-
 static void test_misc_simplify(void)
 {
 	LWGEOM *geom;
@@ -265,7 +242,6 @@ void misc_suite_setup(void);
 void misc_suite_setup(void)
 {
 	CU_pSuite suite = CU_add_suite("miscellaneous", NULL, NULL);
-	PG_ADD_TEST(suite, test_misc_force_2d);
 	PG_ADD_TEST(suite, test_misc_simplify);
 	PG_ADD_TEST(suite, test_misc_count_vertices);
 	PG_ADD_TEST(suite, test_misc_area);
diff --git a/liblwgeom/cunit/cu_tester.c b/liblwgeom/cunit/cu_tester.c
index 605386a..ac979da 100644
--- a/liblwgeom/cunit/cu_tester.c
+++ b/liblwgeom/cunit/cu_tester.c
@@ -35,6 +35,7 @@ extern void algorithms_suite_setup();
 extern void buildarea_suite_setup();
 extern void clean_suite_setup();
 extern void clip_by_rect_suite_setup();
+extern void force_dims_suite_setup(void);
 extern void force_sfs_suite_setup(void);
 extern void geodetic_suite_setup(void);
 extern void geos_suite_setup(void);
@@ -86,6 +87,7 @@ PG_SuiteSetup setupfuncs[] =
 	buildarea_suite_setup,
 	clean_suite_setup,
 	clip_by_rect_suite_setup,
+	force_dims_suite_setup,
 	force_sfs_suite_setup,
 	geodetic_suite_setup,
 	geos_suite_setup,
diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in
index 516cfaa..b6c4475 100644
--- a/liblwgeom/liblwgeom.h.in
+++ b/liblwgeom/liblwgeom.h.in
@@ -1066,9 +1066,9 @@ extern POINTARRAY *ptarray_substring(POINTARRAY *pa, double d1, double d2,
 * Strip out the Z/M components of an #LWGEOM
 */
 extern LWGEOM* lwgeom_force_2d(const LWGEOM *geom);
-extern LWGEOM* lwgeom_force_3dz(const LWGEOM *geom);
-extern LWGEOM* lwgeom_force_3dm(const LWGEOM *geom);
-extern LWGEOM* lwgeom_force_4d(const LWGEOM *geom);
+extern LWGEOM* lwgeom_force_3dz(const LWGEOM *geom, double zval);
+extern LWGEOM* lwgeom_force_3dm(const LWGEOM *geom, double mval);
+extern LWGEOM* lwgeom_force_4d(const LWGEOM *geom, double zval, double mval);
 
 extern LWGEOM* lwgeom_set_effective_area(const LWGEOM *igeom, int set_area, double area);
 extern LWGEOM* lwgeom_chaikin(const LWGEOM *igeom, int n_iterations, int preserve_endpoint);
diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h
index c98eaa9..e47d6d4 100644
--- a/liblwgeom/liblwgeom_internal.h
+++ b/liblwgeom/liblwgeom_internal.h
@@ -180,12 +180,12 @@
 /*
 * Force dims
 */
-LWGEOM* lwgeom_force_dims(const LWGEOM *lwgeom, int hasz, int hasm);
-LWPOINT* lwpoint_force_dims(const LWPOINT *lwpoint, int hasz, int hasm);
-LWLINE* lwline_force_dims(const LWLINE *lwline, int hasz, int hasm);
-LWPOLY* lwpoly_force_dims(const LWPOLY *lwpoly, int hasz, int hasm);
-LWCOLLECTION* lwcollection_force_dims(const LWCOLLECTION *lwcol, int hasz, int hasm);
-POINTARRAY* ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm);
+LWGEOM* lwgeom_force_dims(const LWGEOM *lwgeom, int hasz, int hasm, double zval, double mval);
+LWPOINT* lwpoint_force_dims(const LWPOINT *lwpoint, int hasz, int hasm, double zval, double mval);
+LWLINE* lwline_force_dims(const LWLINE *lwline, int hasz, int hasm, double zval, double mval);
+LWPOLY* lwpoly_force_dims(const LWPOLY *lwpoly, int hasz, int hasm, double zval, double mval);
+LWCOLLECTION* lwcollection_force_dims(const LWCOLLECTION *lwcol, int hasz, int hasm, double zval, double mval);
+POINTARRAY* ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm, double zval, double mval);
 
 /**
  * Swap ordinate values o1 and o2 on a given POINTARRAY
diff --git a/liblwgeom/lwcollection.c b/liblwgeom/lwcollection.c
index 20b4b5e..e64d723 100644
--- a/liblwgeom/lwcollection.c
+++ b/liblwgeom/lwcollection.c
@@ -483,7 +483,7 @@ lwcollection_extract(LWCOLLECTION* col, int type)
 }
 
 LWCOLLECTION*
-lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
+lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm, double zval, double mval)
 {
 	LWCOLLECTION *colout;
 
@@ -499,7 +499,7 @@ lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
 		geoms = lwalloc(sizeof(LWGEOM*) * col->ngeoms);
 		for( i = 0; i < col->ngeoms; i++ )
 		{
-			geoms[i] = lwgeom_force_dims(col->geoms[i], hasz, hasm);
+			geoms[i] = lwgeom_force_dims(col->geoms[i], hasz, hasm, zval, mval);
 		}
 		colout = lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, geoms);
 	}
diff --git a/liblwgeom/lwgeom.c b/liblwgeom/lwgeom.c
index a9fbfd4..ddcf11d 100644
--- a/liblwgeom/lwgeom.c
+++ b/liblwgeom/lwgeom.c
@@ -774,42 +774,42 @@ lwgeom_segmentize2d(const LWGEOM *lwgeom, double dist)
 LWGEOM*
 lwgeom_force_2d(const LWGEOM *geom)
 {
-	return lwgeom_force_dims(geom, 0, 0);
+	return lwgeom_force_dims(geom, 0, 0, 0, 0);
 }
 
 LWGEOM*
-lwgeom_force_3dz(const LWGEOM *geom)
+lwgeom_force_3dz(const LWGEOM *geom, double zval)
 {
-	return lwgeom_force_dims(geom, 1, 0);
+	return lwgeom_force_dims(geom, 1, 0, zval, 0);
 }
 
 LWGEOM*
-lwgeom_force_3dm(const LWGEOM *geom)
+lwgeom_force_3dm(const LWGEOM *geom, double mval)
 {
-	return lwgeom_force_dims(geom, 0, 1);
+	return lwgeom_force_dims(geom, 0, 1, 0, mval);
 }
 
 LWGEOM*
-lwgeom_force_4d(const LWGEOM *geom)
+lwgeom_force_4d(const LWGEOM *geom, double zval, double mval)
 {
-	return lwgeom_force_dims(geom, 1, 1);
+	return lwgeom_force_dims(geom, 1, 1, zval, mval);
 }
 
 LWGEOM*
-lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
+lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm, double zval, double mval)
 {
 	if (!geom)
 		return NULL;
 	switch(geom->type)
 	{
 		case POINTTYPE:
-			return lwpoint_as_lwgeom(lwpoint_force_dims((LWPOINT*)geom, hasz, hasm));
+			return lwpoint_as_lwgeom(lwpoint_force_dims((LWPOINT*)geom, hasz, hasm, zval, mval));
 		case CIRCSTRINGTYPE:
 		case LINETYPE:
 		case TRIANGLETYPE:
-			return lwline_as_lwgeom(lwline_force_dims((LWLINE*)geom, hasz, hasm));
+			return lwline_as_lwgeom(lwline_force_dims((LWLINE*)geom, hasz, hasm, zval, mval));
 		case POLYGONTYPE:
-			return lwpoly_as_lwgeom(lwpoly_force_dims((LWPOLY*)geom, hasz, hasm));
+			return lwpoly_as_lwgeom(lwpoly_force_dims((LWPOLY*)geom, hasz, hasm, zval, mval));
 		case COMPOUNDTYPE:
 		case CURVEPOLYTYPE:
 		case MULTICURVETYPE:
@@ -820,7 +820,7 @@ lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
 		case POLYHEDRALSURFACETYPE:
 		case TINTYPE:
 		case COLLECTIONTYPE:
-			return lwcollection_as_lwgeom(lwcollection_force_dims((LWCOLLECTION*)geom, hasz, hasm));
+			return lwcollection_as_lwgeom(lwcollection_force_dims((LWCOLLECTION*)geom, hasz, hasm, zval, mval));
 		default:
 			lwerror("lwgeom_force_2d: unsupported geom type: %s", lwtype_name(geom->type));
 			return NULL;
diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index 672870d..6106e81 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -5046,7 +5046,7 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int
       POINT4D p4d;
       LWPOINT *prjpt;
       /* add Z to "prj" */
-      tmp = lwgeom_force_3dz(prj);
+      tmp = lwgeom_force_3dz(prj, 0);
       prjpt = lwgeom_as_lwpoint(tmp);
       getPoint4d_p(point->point, 0, &p4d);
       z = p4d.z;
diff --git a/liblwgeom/lwline.c b/liblwgeom/lwline.c
index 4406b07..af5b67e 100644
--- a/liblwgeom/lwline.c
+++ b/liblwgeom/lwline.c
@@ -483,7 +483,7 @@ lwline_is_trajectory(const LWLINE *line)
 }
 
 LWLINE*
-lwline_force_dims(const LWLINE *line, int hasz, int hasm)
+lwline_force_dims(const LWLINE *line, int hasz, int hasm, double zval, double mval)
 {
 	POINTARRAY *pdims = NULL;
 	LWLINE *lineout;
@@ -495,7 +495,7 @@ lwline_force_dims(const LWLINE *line, int hasz, int hasm)
 	}
 	else
 	{
-		pdims = ptarray_force_dims(line->points, hasz, hasm);
+		pdims = ptarray_force_dims(line->points, hasz, hasm, zval, mval);
 		lineout = lwline_construct(line->srid, NULL, pdims);
 	}
 	lineout->type = line->type;
diff --git a/liblwgeom/lwpoint.c b/liblwgeom/lwpoint.c
index 0656863..3f28c06 100644
--- a/liblwgeom/lwpoint.c
+++ b/liblwgeom/lwpoint.c
@@ -268,7 +268,7 @@ lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
 
 
 LWPOINT*
-lwpoint_force_dims(const LWPOINT *point, int hasz, int hasm)
+lwpoint_force_dims(const LWPOINT *point, int hasz, int hasm, double zval, double mval)
 {
 	POINTARRAY *pdims = NULL;
 	LWPOINT *pointout;
@@ -281,7 +281,7 @@ lwpoint_force_dims(const LWPOINT *point, int hasz, int hasm)
 	else
 	{
 		/* Always we duplicate the ptarray and return */
-		pdims = ptarray_force_dims(point->point, hasz, hasm);
+		pdims = ptarray_force_dims(point->point, hasz, hasm, zval, mval);
 		pointout = lwpoint_construct(point->srid, NULL, pdims);
 	}
 	pointout->type = point->type;
diff --git a/liblwgeom/lwpoly.c b/liblwgeom/lwpoly.c
index 7ebf739..e35fe2e 100644
--- a/liblwgeom/lwpoly.c
+++ b/liblwgeom/lwpoly.c
@@ -391,7 +391,7 @@ lwpoly_from_lwlines(const LWLINE *shell,
 }
 
 LWPOLY*
-lwpoly_force_dims(const LWPOLY *poly, int hasz, int hasm)
+lwpoly_force_dims(const LWPOLY *poly, int hasz, int hasm, double zval, double mval)
 {
 	LWPOLY *polyout;
 
@@ -407,7 +407,7 @@ lwpoly_force_dims(const LWPOLY *poly, int hasz, int hasm)
 		rings = lwalloc(sizeof(POINTARRAY*) * poly->nrings);
 		for( i = 0; i < poly->nrings; i++ )
 		{
-			rings[i] = ptarray_force_dims(poly->rings[i], hasz, hasm);
+			rings[i] = ptarray_force_dims(poly->rings[i], hasz, hasm, zval, mval);
 		}
 		polyout = lwpoly_construct(poly->srid, NULL, poly->nrings, rings);
 	}
diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c
index 1a12fca..3e95cec 100644
--- a/liblwgeom/ptarray.c
+++ b/liblwgeom/ptarray.c
@@ -1032,7 +1032,7 @@ ptarray_isccw(const POINTARRAY *pa)
 }
 
 POINTARRAY*
-ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm)
+ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm, double zval, double mval)
 {
 	/* TODO handle zero-length point arrays */
 	uint32_t i;
@@ -1045,9 +1045,9 @@ ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm)
 	{
 		getPoint4d_p(pa, i, &pt);
 		if( hasz && ! in_hasz )
-			pt.z = 0.0;
+			pt.z = zval;
 		if( hasm && ! in_hasm )
-			pt.m = 0.0;
+			pt.m = mval;
 		ptarray_append_point(pa_out, &pt, LW_TRUE);
 	}
 
diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c
index 5fa2f39..c365162 100644
--- a/postgis/lwgeom_functions_basic.c
+++ b/postgis/lwgeom_functions_basic.c
@@ -395,13 +395,14 @@ Datum LWGEOM_force_3dz(PG_FUNCTION_ARGS)
 	GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
 	GSERIALIZED *pg_geom_out;
 	LWGEOM *lwg_in, *lwg_out;
+	double z = PG_NARGS() < 2 ? 0 : PG_GETARG_FLOAT8(1);
 
 	/* already 3d */
 	if (gserialized_ndims(pg_geom_in) == 3 && gserialized_has_z(pg_geom_in))
 		PG_RETURN_POINTER(pg_geom_in);
 
 	lwg_in = lwgeom_from_gserialized(pg_geom_in);
-	lwg_out = lwgeom_force_3dz(lwg_in);
+	lwg_out = lwgeom_force_3dz(lwg_in, z);
 	pg_geom_out = geometry_serialize(lwg_out);
 	lwgeom_free(lwg_out);
 	lwgeom_free(lwg_in);
@@ -417,13 +418,14 @@ Datum LWGEOM_force_3dm(PG_FUNCTION_ARGS)
 	GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
 	GSERIALIZED *pg_geom_out;
 	LWGEOM *lwg_in, *lwg_out;
+	double m = PG_NARGS() < 2 ? 0 : PG_GETARG_FLOAT8(1);
 
 	/* already 3d */
 	if (gserialized_ndims(pg_geom_in) == 3 && gserialized_has_m(pg_geom_in))
 		PG_RETURN_POINTER(pg_geom_in);
 
 	lwg_in = lwgeom_from_gserialized(pg_geom_in);
-	lwg_out = lwgeom_force_3dm(lwg_in);
+	lwg_out = lwgeom_force_3dm(lwg_in, m);
 	pg_geom_out = geometry_serialize(lwg_out);
 	lwgeom_free(lwg_out);
 	lwgeom_free(lwg_in);
@@ -439,13 +441,15 @@ Datum LWGEOM_force_4d(PG_FUNCTION_ARGS)
 	GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
 	GSERIALIZED *pg_geom_out;
 	LWGEOM *lwg_in, *lwg_out;
+	double z = PG_NARGS() < 3 ? 0 : PG_GETARG_FLOAT8(1);
+	double m = PG_NARGS() < 3 ? 0 : PG_GETARG_FLOAT8(2);
 
 	/* already 4d */
 	if (gserialized_ndims(pg_geom_in) == 4)
 		PG_RETURN_POINTER(pg_geom_in);
 
 	lwg_in = lwgeom_from_gserialized(pg_geom_in);
-	lwg_out = lwgeom_force_4d(lwg_in);
+	lwg_out = lwgeom_force_4d(lwg_in, z, m);
 	pg_geom_out = geometry_serialize(lwg_out);
 	lwgeom_free(lwg_out);
 	lwgeom_free(lwg_in);
diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in
index ded515c..15311ed 100644
--- a/postgis/postgis.sql.in
+++ b/postgis/postgis.sql.in
@@ -1312,28 +1312,32 @@ CREATE OR REPLACE FUNCTION ST_Force2D(geometry)
 	_COST_LOW;
 
 -- Availability: 2.1.0
-CREATE OR REPLACE FUNCTION ST_Force3DZ(geometry)
+-- Changed: 3.1.0 - add zvalue=0.0 parameter
+CREATE OR REPLACE FUNCTION ST_Force3DZ(geom geometry, zvalue float8 default 0.0)
 	RETURNS geometry
 	AS 'MODULE_PATHNAME', 'LWGEOM_force_3dz'
 	LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
 	_COST_LOW;
 
 -- Availability: 2.1.0
-CREATE OR REPLACE FUNCTION ST_Force3D(geometry)
+-- Changed: 3.1.0 - add zvalue=0.0 parameter
+CREATE OR REPLACE FUNCTION ST_Force3D(geom geometry, zvalue float8 default 0.0)
 	RETURNS geometry
-	AS 'MODULE_PATHNAME', 'LWGEOM_force_3dz'
-	LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
+	AS 'SELECT @extschema at .ST_Force3DZ($1, $2)'
+	LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE
 	_COST_LOW;
 
 -- Availability: 2.1.0
-CREATE OR REPLACE FUNCTION ST_Force3DM(geometry)
+-- Changed: 3.1.0 - add mvalue=0.0 parameter
+CREATE OR REPLACE FUNCTION ST_Force3DM(geom geometry, mvalue float8 default 0.0)
 	RETURNS geometry
 	AS 'MODULE_PATHNAME', 'LWGEOM_force_3dm'
 	LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
 	_COST_LOW;
 
 -- Availability: 2.1.0
-CREATE OR REPLACE FUNCTION ST_Force4D(geometry)
+-- Changed: 3.1.0 - add zvalue=0.0 and mvalue=0.0 parameters
+CREATE OR REPLACE FUNCTION ST_Force4D(geom geometry, zvalue float8 default 0.0, mvalue float8 default 0.0)
 	RETURNS geometry
 	AS 'MODULE_PATHNAME', 'LWGEOM_force_4d'
 	LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
diff --git a/postgis/postgis_before_upgrade.sql b/postgis/postgis_before_upgrade.sql
index 8780c90..0a5f266 100644
--- a/postgis/postgis_before_upgrade.sql
+++ b/postgis/postgis_before_upgrade.sql
@@ -194,6 +194,14 @@ SELECT _postgis_drop_function_if_needed
     'zoom integer, x integer, y integer, bounds geometry DEFAULT ''0102000020110F00000200000052107C45F81B73C152107C45F81B73C152107C45F81B734152107C45F81B7341''::geometry'
     );
 
+-- FUNCTION ST_Force3D, ST_Force3DZ, ST_Force3DM, ST_Force4DZ changed to add defaults in 3.1
+-- These signatures were superseeded
+DROP FUNCTION IF EXISTS ST_Force3D(geometry); -- Does not conflict
+DROP FUNCTION IF EXISTS ST_Force3DZ(geometry); -- Does not conflict
+DROP FUNCTION IF EXISTS ST_Force3DM(geometry); -- Does not conflict
+DROP FUNCTION IF EXISTS ST_Force4D(geometry); -- Does not conflict
+
+
 -- FUNCTION st_askml changed to add defaults in 3.0 / r17357
 -- These signatures were superseeded
 DROP FUNCTION IF EXISTS st_askml(geometry, integer); -- Does not conflict
diff --git a/regress/core/lwgeom_regress.sql b/regress/core/lwgeom_regress.sql
index 077a0e1..988b81e 100644
--- a/regress/core/lwgeom_regress.sql
+++ b/regress/core/lwgeom_regress.sql
@@ -98,6 +98,15 @@ SELECT ST_MemSize(ST_collect(ST_Force2d(ST_force4d(ST_force3dm(ST_force3dz(ST_fo
 
 DROP TABLE test_data;
 
+SELECT '#3057', ST_AsEWKT(ST_Force3D(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry)));
+SELECT '#3057', ST_AsEWKT(ST_Force3D(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry), 1));
+SELECT '#3057', ST_AsEWKT(ST_Force3DZ(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry)));
+SELECT '#3057', ST_AsEWKT(ST_Force3DZ(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry), 1));
+SELECT '#3057', ST_AsEWKT(ST_Force3DM(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry)));
+SELECT '#3057', ST_AsEWKT(ST_Force3DM(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry), 2));
+SELECT '#3057', ST_AsEWKT(ST_Force4D(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry)));
+SELECT '#3057', ST_AsEWKT(ST_Force4D(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry), 1, 2));
+
 SELECT '#3069', ST_Summary(PostGIS_Noop('SRID=4326;POINT(1 1)'::geometry));
 SELECT '#3069', ST_Summary(PostGIS_Noop('SRID=4326;LINESTRING(1 1,0 0)'::geometry));
 SELECT '#3069', replace(ST_Summary(PostGIS_Noop('SRID=4326;MULTIPOINT(1 1)'::geometry)),E'\n',' ');
diff --git a/regress/core/lwgeom_regress_expected b/regress/core/lwgeom_regress_expected
index 696bbb0..dd88331 100644
--- a/regress/core/lwgeom_regress_expected
+++ b/regress/core/lwgeom_regress_expected
@@ -5,6 +5,14 @@ BOX3D(0 0.1 -55,11 12 12)
 20464
 15824
 11184
+#3057|SRID=4326;POINT(1 1 0)
+#3057|SRID=4326;POINT(1 1 1)
+#3057|SRID=4326;POINT(1 1 0)
+#3057|SRID=4326;POINT(1 1 1)
+#3057|SRID=4326;POINTM(1 1 0)
+#3057|SRID=4326;POINTM(1 1 2)
+#3057|SRID=4326;POINT(1 1 0 0)
+#3057|SRID=4326;POINT(1 1 1 2)
 #3069|Point[S]
 #3069|LineString[S] with 2 points
 #3069|MultiPoint[S] with 1 element:   Point[S]

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

Summary of changes:
 NEWS                                 |   1 +
 doc/reference_editor.xml             |  21 +++++--
 liblwgeom/cunit/Makefile.in          |   1 +
 liblwgeom/cunit/cu_force_dims.c      | 118 +++++++++++++++++++++++++++++++++++
 liblwgeom/cunit/cu_misc.c            |  24 -------
 liblwgeom/cunit/cu_tester.c          |   2 +
 liblwgeom/liblwgeom.h.in             |   6 +-
 liblwgeom/liblwgeom_internal.h       |  12 ++--
 liblwgeom/lwcollection.c             |   4 +-
 liblwgeom/lwgeom.c                   |  24 +++----
 liblwgeom/lwgeom_topo.c              |   2 +-
 liblwgeom/lwline.c                   |   4 +-
 liblwgeom/lwpoint.c                  |   4 +-
 liblwgeom/lwpoly.c                   |   4 +-
 liblwgeom/ptarray.c                  |   6 +-
 postgis/lwgeom_functions_basic.c     |  10 ++-
 postgis/postgis.sql.in               |  16 +++--
 postgis/postgis_before_upgrade.sql   |   8 +++
 regress/core/lwgeom_regress.sql      |   9 +++
 regress/core/lwgeom_regress_expected |   8 +++
 20 files changed, 212 insertions(+), 72 deletions(-)
 create mode 100644 liblwgeom/cunit/cu_force_dims.c


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list