#3469, support multipoint into to ST_MakeLine (Paul Norman)

git-svn-id: http://svn.osgeo.org/postgis/trunk@14695 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
Paul Ramsey 2016-02-25 10:44:57 +00:00
parent b214b12a98
commit e49e6de0f8
6 changed files with 43 additions and 9 deletions

1
NEWS
View file

@ -14,6 +14,7 @@ PostGIS 2.3.0
- #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

View file

@ -1439,7 +1439,7 @@ BOX3D(-989502.1875 528439.5625 10,-987121.375 529933.1875 10)
<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 @@ BOX3D(-989502.1875 528439.5625 10,-987121.375 529933.1875 10)
<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>

View file

@ -165,12 +165,13 @@ lwline_same(const LWLINE *l1, const LWLINE *l2)
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 @@ lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
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 @@ lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
}
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);

View file

@ -1408,8 +1408,9 @@ Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
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;
}

View file

@ -12,11 +12,22 @@ select 'ST_MakeLine1', ST_AsText(ST_MakeLine(
'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

View file

@ -3,7 +3,8 @@ ERROR: Operation on mixed SRID geometries
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)