<refnamediv>
<refname>ST_MakeLine</refname>
- <refpurpose>Creates a Linestring from point geometries.</refpurpose>
+ <refpurpose>Creates a Linestring from point or line geometries.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>geometry <function>ST_MakeLine</function></funcdef>
- <paramdef><type>geometry set</type> <parameter>pointfield</parameter></paramdef>
+ <paramdef><type>geometry set</type> <parameter>geoms</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>geometry <function>ST_MakeLine</function></funcdef>
- <paramdef><type>geometry</type> <parameter>point1</parameter></paramdef>
- <paramdef><type>geometry</type> <parameter>point2</parameter></paramdef>
+ <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
+ <paramdef><type>geometry</type> <parameter>geom2</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>geometry <function>ST_MakeLine</function></funcdef>
- <paramdef><type>geometry[]</type> <parameter>point_array</parameter></paramdef>
+ <paramdef><type>geometry[]</type> <parameter>geoms_array</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<title>Description</title>
<para>ST_MakeLine comes in 3 forms: a spatial aggregate that takes
- rows of point geometries and returns a line string, a function that takes an array of points, and a regular function that takes two point geometries. You
+ 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
might want to use a subselect to order points before feeding them
to the aggregate version of this function.</para>
+ <para>
+ When adding line components a common node is removed from the output.
+ </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>
</refsection>
<refsection>
LINESTRING(1 2 3,3 4 5,6 6 6)
</programlisting>
</refsection>
+
+ <!-- TODO: add an example using lines -->
+
<refsection>
<title>See Also</title>
<para><xref linkend="ST_AsEWKT" />, <xref linkend="ST_AsText" />, <xref linkend="ST_GeomFromText" />, <xref linkend="ST_MakePoint" /></para>
ArrayType *array;
int nelems;
GSERIALIZED *result=NULL;
- LWPOINT **lwpoints;
+ LWGEOM **geoms;
LWGEOM *outlwg;
- uint32 npoints;
+ uint32 ngeoms;
int i;
size_t offset;
int srid=SRID_UNKNOWN;
/*
* Deserialize all point geometries in array into the
- * lwpoints pointers array.
+ * geoms pointers array.
* Count actual number of points.
*/
/* possibly more then required */
- lwpoints = palloc(sizeof(LWGEOM *)*nelems);
- npoints = 0;
+ geoms = palloc(sizeof(LWGEOM *)*nelems);
+ ngeoms = 0;
offset = 0;
bitmap = ARR_NULLBITMAP(array);
bitmask = 1;
GSERIALIZED *geom = (GSERIALIZED *)(ARR_DATA_PTR(array)+offset);
offset += INTALIGN(VARSIZE(geom));
- if ( gserialized_get_type(geom) != POINTTYPE ) continue;
+ if ( gserialized_get_type(geom) != POINTTYPE && gserialized_get_type(geom) != LINETYPE ) continue;
- lwpoints[npoints++] =
- lwgeom_as_lwpoint(lwgeom_from_gserialized(geom));
+ geoms[ngeoms++] =
+ lwgeom_from_gserialized(geom);
/* Check SRID homogeneity */
- if ( npoints == 1 )
+ if ( ngeoms == 1 )
{
/* Get first geometry SRID */
- srid = lwpoints[npoints-1]->srid;
+ srid = geoms[ngeoms-1]->srid;
+ /* TODO: also get ZMflags */
}
else
{
- if ( lwpoints[npoints-1]->srid != srid )
+ if ( geoms[ngeoms-1]->srid != srid )
{
elog(ERROR,
"Operation on mixed SRID geometries");
}
/* Return null on 0-points input array */
- if ( npoints == 0 )
+ if ( ngeoms == 0 )
{
- elog(NOTICE, "No points in input array");
+ /* TODO: should we return LINESTRING EMPTY here ? */
+ elog(NOTICE, "No points or linestrings in input array");
PG_RETURN_NULL();
}
- POSTGIS_DEBUGF(3, "LWGEOM_makeline_garray: point elements: %d", npoints);
+ POSTGIS_DEBUGF(3, "LWGEOM_makeline_garray: elements: %d", ngeoms);
- outlwg = (LWGEOM *)lwline_from_ptarray(srid, npoints, lwpoints);
+ outlwg = (LWGEOM *)lwline_from_lwgeom_array(srid, ngeoms, geoms);
result = geometry_serialize(outlwg);
{
GSERIALIZED *pglwg1, *pglwg2;
GSERIALIZED *result=NULL;
- LWPOINT *lwpoints[2];
+ LWGEOM *lwgeoms[2];
LWLINE *outline;
POSTGIS_DEBUG(2, "LWGEOM_makeline called.");
pglwg1 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
pglwg2 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
- if ( gserialized_get_type(pglwg1) != POINTTYPE ||
- gserialized_get_type(pglwg2) != POINTTYPE )
+ if ( (gserialized_get_type(pglwg1) != POINTTYPE && gserialized_get_type(pglwg1) != LINETYPE) ||
+ (gserialized_get_type(pglwg2) != POINTTYPE && gserialized_get_type(pglwg2) != LINETYPE) )
{
- elog(ERROR, "Input geometries must be points");
+ elog(ERROR, "Input geometries must be points or lines");
PG_RETURN_NULL();
}
error_if_srid_mismatch(gserialized_get_srid(pglwg1), gserialized_get_srid(pglwg2));
- lwpoints[0] = lwgeom_as_lwpoint(lwgeom_from_gserialized(pglwg1));
- lwpoints[1] = lwgeom_as_lwpoint(lwgeom_from_gserialized(pglwg2));
+ lwgeoms[0] = lwgeom_from_gserialized(pglwg1);
+ lwgeoms[1] = lwgeom_from_gserialized(pglwg2);
- outline = lwline_from_ptarray(lwpoints[0]->srid, 2, lwpoints);
+ outline = lwline_from_lwgeom_array(lwgeoms[0]->srid, 2, lwgeoms);
result = geometry_serialize((LWGEOM *)outline);
PG_FREE_IF_COPY(pglwg1, 0);
PG_FREE_IF_COPY(pglwg2, 1);
- lwgeom_release((LWGEOM *)lwpoints[0]);
- lwgeom_release((LWGEOM *)lwpoints[1]);
+ lwgeom_release((LWGEOM *)lwgeoms[0]);
+ lwgeom_release((LWGEOM *)lwgeoms[1]);
PG_RETURN_POINTER(result);
}
select ST_asewkt(ST_makeline('SRID=3;POINT(0 0)', 'SRID=3;POINT(1 1)'));
select ST_makeline('POINT(0 0)', 'SRID=3;POINT(1 1)');
+select 'ST_MakeLine1', ST_AsText(ST_MakeLine(
+ 'POINT(0 0)'::geometry,
+ 'LINESTRING(1 1, 10 0)'::geometry
+));
+
+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)')
+) 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)');