[postgis-tickets] r14695 - #3469, support multipoint into to ST_MakeLine (Paul Norman)

Paul Ramsey pramsey at cleverelephant.ca
Thu Feb 25 02:44:57 PST 2016


Author: pramsey
Date: 2016-02-25 02:44:57 -0800 (Thu, 25 Feb 2016)
New Revision: 14695

Modified:
   trunk/NEWS
   trunk/doc/reference_constructor.xml
   trunk/liblwgeom/lwline.c
   trunk/postgis/lwgeom_functions_basic.c
   trunk/regress/ctors.sql
   trunk/regress/ctors_expected
Log:
#3469, support multipoint into to ST_MakeLine (Paul Norman)


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/NEWS	2016-02-25 10:44:57 UTC (rev 14695)
@@ -14,6 +14,7 @@
   - #3362 ST_ClusterDBSCAN (Dan Baston) 
   - #3428 ST_Points (Dan Baston)
   - #3465 ST_ClusterKMeans (Paul Ramsey)
+  - #3469 ST_MakeLine with MULTIPOINTs (Paul Norman)
 
 PostGIS 2.2.1
 2016/01/06

Modified: trunk/doc/reference_constructor.xml
===================================================================
--- trunk/doc/reference_constructor.xml	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/doc/reference_constructor.xml	2016-02-25 10:44:57 UTC (rev 14695)
@@ -1439,7 +1439,7 @@
 		<refnamediv>
 		<refname>ST_MakeLine</refname>
 
-		<refpurpose>Creates a Linestring from point or line geometries.</refpurpose>
+		<refpurpose>Creates a Linestring from point, multipoint, or line geometries.</refpurpose>
 		</refnamediv>
 
 		<refsynopsisdiv>
@@ -1466,17 +1466,21 @@
 		<title>Description</title>
 
 		<para>ST_MakeLine comes in 3 forms: a spatial aggregate that takes
-			rows of point-or-line geometries and returns a line string, a function that takes an array of point-or-lines, and a regular function that takes two point-or-line geometries. You
+			rows of point, multipoint, or line geometries and returns a line string, a
+			function that takes an array of point, multipoint, or line, and a regular
+			function that takes two point, multipoint, or line geometries. You
 			might want to use a subselect to order points before feeding them
 			to  the aggregate version of this function.</para>
 
+		<para>Inputs other than point, multipoint, or lines are ignored.</para>
 		<para>
-			When adding line components a common node is removed from the output.
+			When adding line components common nodes at the beginning of lines are removed from the output. Common nodes in point and multipoint inputs are not removed.
 		</para>
 
 		<para>&Z_support;</para>
 		<para>Availability: 1.4.0 -  ST_MakeLine(geomarray) was introduced. ST_MakeLine aggregate functions was enhanced to handle more points faster.</para>
 		<para>Availability: 2.0.0 -  Support for linestring input elements was introduced</para>
+		<para>Availability: 2.0.0 -  Support for multipoint input elements was introduced</para>
 		</refsection>
 
 		<refsection>

Modified: trunk/liblwgeom/lwline.c
===================================================================
--- trunk/liblwgeom/lwline.c	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/liblwgeom/lwline.c	2016-02-25 10:44:57 UTC (rev 14695)
@@ -165,12 +165,13 @@
 LWLINE *
 lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
 {
- 	int i;
+	int i;
 	int hasz = LW_FALSE;
 	int hasm = LW_FALSE;
 	POINTARRAY *pa;
 	LWLINE *line;
 	POINT4D pt;
+	LWPOINTITERATOR* it;
 
 	/*
 	 * Find output dimensions, check integrity
@@ -182,7 +183,9 @@
 		if ( hasz && hasm ) break; /* Nothing more to learn! */
 	}
 
-	/* ngeoms should be a guess about how many points we have in input */
+	/*
+	 * ngeoms should be a guess about how many points we have in input.
+	 * It's an underestimate for lines and multipoints */
 	pa = ptarray_construct_empty(hasz, hasm, ngeoms);
 	
 	for ( i=0; i < ngeoms; i++ )
@@ -198,8 +201,21 @@
 		}
 		else if ( g->type == LINETYPE )
 		{
+			/*
+			 * Append the new line points, de-duplicating against the previous points.
+			 * Duplicated points internal to the linestring are untouched.
+			 */
 			ptarray_append_ptarray(pa, ((LWLINE*)g)->points, -1);
 		}
+		else if ( g->type == MULTIPOINTTYPE )
+		{
+			it = lwpointiterator_create(g);
+			while(lwpointiterator_next(it, &pt))
+			{
+				ptarray_append_point(pa, &pt, LW_TRUE);
+			}
+			lwpointiterator_destroy(it);
+		}
 		else
 		{
 			ptarray_free(pa);

Modified: trunk/postgis/lwgeom_functions_basic.c
===================================================================
--- trunk/postgis/lwgeom_functions_basic.c	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/postgis/lwgeom_functions_basic.c	2016-02-25 10:44:57 UTC (rev 14695)
@@ -1408,8 +1408,9 @@
 		
 		geom = (GSERIALIZED *)DatumGetPointer(value);
 
-		if ( gserialized_get_type(geom) != POINTTYPE && 
-		     gserialized_get_type(geom) != LINETYPE ) 
+		if ( gserialized_get_type(geom) != POINTTYPE &&
+		     gserialized_get_type(geom) != LINETYPE &&
+		     gserialized_get_type(geom) != MULTIPOINTTYPE)
 		{
 			continue;
 		}

Modified: trunk/regress/ctors.sql
===================================================================
--- trunk/regress/ctors.sql	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/regress/ctors.sql	2016-02-25 10:44:57 UTC (rev 14695)
@@ -12,13 +12,24 @@
  'LINESTRING(1 1, 10 0)'::geometry
 ));
 
+-- postgis-devel/2016-February/025634.html for repeated point background
 select 'ST_MakeLine_agg1', ST_AsText(ST_MakeLine(g)) from (
  values ('POINT(0 0)'),
         ('LINESTRING(1 1, 10 0)'),
         ('LINESTRING(10 0, 20 20)'),
-        ('POINT(40 4)')
+        ('POINT(40 4)'),
+        ('POINT(40 4)'),
+        ('POINT(40 5)'),
+        ('MULTIPOINT(40 5, 40 6, 40 6, 40 7)'),
+        ('LINESTRING(40 7, 40 8)')
 ) as foo(g);
 
+select 'ST_MakeLine_agg2', ST_AsText(ST_MakeLine(g)) from (
+ values ('POINT(0 0)'),
+        ('LINESTRING(0 0, 1 0)'),
+        ('POINT(1 0)')
+) as foo(g);
+
 -- postgis-users/2006-July/012788.html
 select ST_makebox2d('SRID=3;POINT(0 0)', 'SRID=3;POINT(1 1)');
 select ST_makebox2d('POINT(0 0)', 'SRID=3;POINT(1 1)');

Modified: trunk/regress/ctors_expected
===================================================================
--- trunk/regress/ctors_expected	2016-02-25 10:08:04 UTC (rev 14694)
+++ trunk/regress/ctors_expected	2016-02-25 10:44:57 UTC (rev 14695)
@@ -3,7 +3,8 @@
 SRID=3;LINESTRING(0 0,1 1)
 ERROR:  Operation on mixed SRID geometries
 ST_MakeLine1|LINESTRING(0 0,1 1,10 0)
-ST_MakeLine_agg1|LINESTRING(0 0,1 1,10 0,20 20,40 4)
+ST_MakeLine_agg1|LINESTRING(0 0,1 1,10 0,20 20,40 4,40 4,40 5,40 5,40 6,40 6,40 7,40 8)
+ST_MakeLine_agg2|LINESTRING(0 0,1 0,1 0)
 BOX(0 0,1 1)
 ERROR:  Operation on mixed SRID geometries
 BOX3D(0 0 0,1 1 0)



More information about the postgis-tickets mailing list