[postgis-tickets] [SCM] PostGIS branch master updated. 3.1.0rc1-325-g13634f9
git at osgeo.org
git at osgeo.org
Mon Jul 12 12:44:49 PDT 2021
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 13634f91f99e4d8eeddd63f79a25c947cce1f148 (commit)
via c5348d44b775d8b23d0d969a6277f2e04fd03ef2 (commit)
via de60f59e46462ec03da356f93eadf8c74261d2b3 (commit)
via 3349c07c24e2c1c39e3a03c681f8ae574ebd0841 (commit)
via 7d44a0ddf0968f0bb3543805923dff3c54dfaa42 (commit)
via d7a7f60ff6db7586a2d7bf17f3a57fa31190e5a1 (commit)
via 446cfe43844fcedd9a435960388ccb87d1cb0a50 (commit)
via b8f3067f6f14024b94f93cc1c50d42adc403537e (commit)
via 29852831a2e68f599f024af1e56fd9914d6c2036 (commit)
via 791e686d7d58e78a9c551bad335855357ca2d44d (commit)
via 35ea0c3957af12e955e48fff16540e9d89ea7402 (commit)
via 8488dccb895cd6afc7b5113e1c33699b2e48fbf0 (commit)
via 22c55934836f841931413d810dab2d7f4f93a9b4 (commit)
via 181d5fb3981393ab40374b62c7685b4673bbea08 (commit)
via 77cb26589d5cc889b9d427c932b67226ed11a041 (commit)
via aa018f66b4938ba60ec825b3f478327d2be93382 (commit)
via 115203f9b0c4286ec6382c6e1bbe5535772caeb5 (commit)
from 63b1ea1a04a1bc14cfeeeb3b51a0e3f9b9b90c7b (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 13634f91f99e4d8eeddd63f79a25c947cce1f148
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Mon Jul 12 22:44:19 2021 +0300
Add ST_DumpSegments to NEWS
diff --git a/NEWS b/NEWS
index 87eb4c1..b45bd41 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,7 @@ PostGIS 3.2.0
from a raster (Paul Ramsey)
- New postgis.gdal_vsi_options GUC allows out-db rasters on VSI network
services to be accessed with authentication keys, etc. (Paul Ramsey)
+ - ST_DumpSegments returns a set of segments of input geometry (Aliaksandr Kalenik)
PostGIS 3.1.0
commit c5348d44b775d8b23d0d969a6277f2e04fd03ef2
Merge: 63b1ea1 de60f59
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Mon Jul 12 22:41:48 2021 +0300
ST_DumpSegments (Aliaksandr Kalenik)
commit de60f59e46462ec03da356f93eadf8c74261d2b3
Merge: 63b1ea1 3349c07
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Mon Jul 12 22:31:42 2021 +0300
Merge 3349c07c24e2c1c39e3a03c681f8ae574ebd0841 into 63b1ea1a04a1bc14cfeeeb3b51a0e3f9b9b90c7b
commit 3349c07c24e2c1c39e3a03c681f8ae574ebd0841
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Mon Jul 12 14:35:16 2021 +0300
merge lwgeom_dumpsegments.c into lwgeom_dumppoints.c
diff --git a/postgis/Makefile.in b/postgis/Makefile.in
index a4e0de7..9e42c2e 100644
--- a/postgis/Makefile.in
+++ b/postgis/Makefile.in
@@ -93,7 +93,6 @@ PG_OBJS= \
lwgeom_triggers.o \
lwgeom_dump.o \
lwgeom_dumppoints.o \
- lwgeom_dumpsegments.o \
lwgeom_functions_lrs.o \
lwgeom_functions_temporal.o \
lwgeom_rectree.o \
diff --git a/postgis/lwgeom_dumppoints.c b/postgis/lwgeom_dumppoints.c
index 0f9aabe..223a8e3 100644
--- a/postgis/lwgeom_dumppoints.c
+++ b/postgis/lwgeom_dumppoints.c
@@ -45,6 +45,7 @@
*/
Datum LWGEOM_dumppoints(PG_FUNCTION_ARGS);
+Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS);
struct dumpnode {
LWGEOM *geom;
@@ -290,4 +291,218 @@ Datum LWGEOM_dumppoints(PG_FUNCTION_ARGS) {
}
}
+PG_FUNCTION_INFO_V1(LWGEOM_dumpsegments);
+Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ MemoryContext oldcontext, newcontext;
+
+ GSERIALIZED *pglwgeom;
+ LWCOLLECTION *lwcoll;
+ LWGEOM *lwgeom;
+ struct dumpstate *state;
+ struct dumpnode *node;
+
+ HeapTuple tuple;
+ Datum pathpt[2]; /* used to construct the composite return value */
+ bool isnull[2] = {0, 0}; /* needed to say neither value is null */
+ Datum result; /* the actual composite return value */
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ funcctx = SRF_FIRSTCALL_INIT();
+
+ newcontext = funcctx->multi_call_memory_ctx;
+ oldcontext = MemoryContextSwitchTo(newcontext);
+
+ pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
+ lwgeom = lwgeom_from_gserialized(pglwgeom);
+
+ /* return early if nothing to do */
+ if (!lwgeom || lwgeom_is_empty(lwgeom))
+ {
+ MemoryContextSwitchTo(oldcontext);
+ funcctx = SRF_PERCALL_SETUP();
+ SRF_RETURN_DONE(funcctx);
+ }
+
+ /* Create function state */
+ state = lwalloc(sizeof *state);
+ state->root = lwgeom;
+ state->stacklen = 0;
+ state->pathlen = 0;
+ state->pt = 0;
+ state->ring = 0;
+
+ funcctx->user_fctx = state;
+
+ /*
+ * Push a struct dumpnode on the state stack
+ */
+ state->stack[0].idx = 0;
+ state->stack[0].geom = lwgeom;
+ state->stacklen++;
+
+ /*
+ * get tuple description for return type
+ */
+ if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("set-valued function called in context that cannot accept a set")));
+ }
+
+ BlessTupleDesc(funcctx->tuple_desc);
+
+ /* get and cache data for constructing int4 arrays */
+ get_typlenbyvalalign(INT4OID, &state->typlen, &state->byval, &state->align);
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* stuff done on every call of the function */
+ funcctx = SRF_PERCALL_SETUP();
+ newcontext = funcctx->multi_call_memory_ctx;
+
+ /* get state */
+ state = funcctx->user_fctx;
+
+ while (1)
+ {
+ POINTARRAY *points = NULL;
+ LWLINE *line;
+ LWTRIANGLE *tri;
+ LWPOLY *poly;
+ POINT4D pt_start, pt_end;
+ POINTARRAY *segment_pa;
+ LWLINE *segment;
+
+ node = &state->stack[state->stacklen - 1];
+ lwgeom = node->geom;
+
+ if (lwgeom->type == LINETYPE || lwgeom->type == TRIANGLETYPE || lwgeom->type == POLYGONTYPE)
+ {
+ if (lwgeom->type == LINETYPE)
+ {
+ line = (LWLINE *)lwgeom;
+
+ if (state->pt < line->points->npoints - 1)
+ {
+ points = line->points;
+ }
+ }
+ if (lwgeom->type == TRIANGLETYPE)
+ {
+ tri = (LWTRIANGLE *)lwgeom;
+
+ if (state->pt == 0)
+ {
+ state->path[state->pathlen++] = Int32GetDatum(state->ring + 1);
+ }
+
+ if (state->pt < 3)
+ {
+ points = tri->points;
+ }
+ else
+ {
+ state->pathlen--;
+ }
+ }
+ if (lwgeom->type == POLYGONTYPE)
+ {
+ poly = (LWPOLY *)lwgeom;
+
+ if (state->pt == poly->rings[state->ring]->npoints)
+ {
+ state->pt = 0;
+ state->ring++;
+ state->pathlen--;
+ }
+
+ if (state->ring < poly->nrings)
+ {
+ if (state->pt == 0)
+ {
+ state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
+ state->pathlen++;
+ }
+
+ if (state->pt < poly->rings[state->ring]->npoints - 1)
+ {
+ points = poly->rings[state->ring];
+ }
+ else
+ {
+ state->pt++;
+ continue;
+ }
+ }
+ }
+
+ if (points)
+ {
+ getPoint4d_p(points, state->pt, &pt_start);
+ getPoint4d_p(points, state->pt + 1, &pt_end);
+
+ segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
+ ptarray_set_point4d(segment_pa, 0, &pt_start);
+ ptarray_set_point4d(segment_pa, 1, &pt_end);
+
+ segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
+
+ state->pt++;
+
+ state->path[state->pathlen] = Int32GetDatum(state->pt);
+ pathpt[0] = PointerGetDatum(construct_array(state->path,
+ state->pathlen + 1,
+ INT4OID,
+ state->typlen,
+ state->byval,
+ state->align));
+ pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
+
+ tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
+ result = HeapTupleGetDatum(tuple);
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
+ }
+
+ if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE ||
+ lwgeom->type == MULTIPOLYGONTYPE || lwgeom->type == TINTYPE)
+ {
+ lwcoll = (LWCOLLECTION *)node->geom;
+
+ /* if a collection and we have more geoms */
+ if (node->idx < lwcoll->ngeoms)
+ {
+ /* push the next geom on the path and the stack */
+ lwgeom = lwcoll->geoms[node->idx++];
+ state->path[state->pathlen++] = Int32GetDatum(node->idx);
+
+ node = &state->stack[state->stacklen++];
+ node->idx = 0;
+ node->geom = lwgeom;
+
+ state->pt = 0;
+ state->ring = 0;
+
+ /* loop back to beginning, which will then check whatever node we just pushed */
+ continue;
+ }
+ }
+
+ /* no more geometries in the current collection */
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ }
+}
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
deleted file mode 100644
index 9ff3ba1..0000000
--- a/postgis/lwgeom_dumpsegments.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/**********************************************************************
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.net
- *
- * PostGIS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * PostGIS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
- *
- **********************************************************************/
-
-#include "postgres.h"
-#include "fmgr.h"
-#include "utils/elog.h"
-#include "utils/array.h"
-#include "utils/geo_decls.h"
-#include "utils/lsyscache.h"
-#include "catalog/pg_type.h"
-#include "funcapi.h"
-
-#include "../postgis_config.h"
-#include "lwgeom_pg.h"
-
-#include "access/htup_details.h"
-
-#include "liblwgeom.h"
-
-Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS);
-
-struct dumpnode {
- LWGEOM *geom;
- uint32_t idx; /* which member geom we're working on */
-};
-
-/* 32 is the max depth for st_dump, so it seems reasonable
- * to use the same here
- */
-#define MAXDEPTH 32
-struct dumpstate {
- LWGEOM *root;
- int stacklen; /* collections/geoms on stack */
- int pathlen; /* polygon rings and such need extra path info */
- struct dumpnode stack[MAXDEPTH];
- Datum path[34]; /* two more than max depth, for ring and point */
-
- /* used to cache the type attributes for integer arrays */
- int16 typlen;
- bool byval;
- char align;
-
- uint32_t ring; /* ring of top polygon */
- uint32_t pt; /* point of top geom or current ring */
-};
-
-PG_FUNCTION_INFO_V1(LWGEOM_dumpsegments);
-Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
-{
- FuncCallContext *funcctx;
- MemoryContext oldcontext, newcontext;
-
- GSERIALIZED *pglwgeom;
- LWCOLLECTION *lwcoll;
- LWGEOM *lwgeom;
- struct dumpstate *state;
- struct dumpnode *node;
-
- HeapTuple tuple;
- Datum pathpt[2]; /* used to construct the composite return value */
- bool isnull[2] = {0, 0}; /* needed to say neither value is null */
- Datum result; /* the actual composite return value */
-
- if (SRF_IS_FIRSTCALL())
- {
- funcctx = SRF_FIRSTCALL_INIT();
-
- newcontext = funcctx->multi_call_memory_ctx;
- oldcontext = MemoryContextSwitchTo(newcontext);
-
- pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
- lwgeom = lwgeom_from_gserialized(pglwgeom);
-
- /* return early if nothing to do */
- if (!lwgeom || lwgeom_is_empty(lwgeom))
- {
- MemoryContextSwitchTo(oldcontext);
- funcctx = SRF_PERCALL_SETUP();
- SRF_RETURN_DONE(funcctx);
- }
-
- /* Create function state */
- state = lwalloc(sizeof *state);
- state->root = lwgeom;
- state->stacklen = 0;
- state->pathlen = 0;
- state->pt = 0;
- state->ring = 0;
-
- funcctx->user_fctx = state;
-
- /*
- * Push a struct dumpnode on the state stack
- */
- state->stack[0].idx = 0;
- state->stack[0].geom = lwgeom;
- state->stacklen++;
-
- /*
- * get tuple description for return type
- */
- if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
- {
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("set-valued function called in context that cannot accept a set")));
- }
-
- BlessTupleDesc(funcctx->tuple_desc);
-
- /* get and cache data for constructing int4 arrays */
- get_typlenbyvalalign(INT4OID, &state->typlen, &state->byval, &state->align);
-
- MemoryContextSwitchTo(oldcontext);
- }
-
- /* stuff done on every call of the function */
- funcctx = SRF_PERCALL_SETUP();
- newcontext = funcctx->multi_call_memory_ctx;
-
- /* get state */
- state = funcctx->user_fctx;
-
- while (1)
- {
- POINTARRAY *points = NULL;
- LWLINE *line;
- LWTRIANGLE *tri;
- LWPOLY *poly;
- POINT4D pt_start, pt_end;
- POINTARRAY *segment_pa;
- LWLINE *segment;
-
- node = &state->stack[state->stacklen - 1];
- lwgeom = node->geom;
-
- if (lwgeom->type == LINETYPE || lwgeom->type == TRIANGLETYPE || lwgeom->type == POLYGONTYPE)
- {
- if (lwgeom->type == LINETYPE)
- {
- line = (LWLINE *)lwgeom;
-
- if (state->pt < line->points->npoints - 1)
- {
- points = line->points;
- }
- }
- if (lwgeom->type == TRIANGLETYPE)
- {
- tri = (LWTRIANGLE *)lwgeom;
-
- if (state->pt == 0)
- {
- state->path[state->pathlen++] = Int32GetDatum(state->ring + 1);
- }
-
- if (state->pt < 3)
- {
- points = tri->points;
- }
- else
- {
- state->pathlen--;
- }
- }
- if (lwgeom->type == POLYGONTYPE)
- {
- poly = (LWPOLY *)lwgeom;
-
- if (state->pt == poly->rings[state->ring]->npoints)
- {
- state->pt = 0;
- state->ring++;
- state->pathlen--;
- }
-
- if (state->ring < poly->nrings)
- {
- if (state->pt == 0)
- {
- state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
- state->pathlen++;
- }
-
- if (state->pt < poly->rings[state->ring]->npoints - 1)
- {
- points = poly->rings[state->ring];
- }
- else
- {
- state->pt++;
- continue;
- }
- }
- }
-
- if (points)
- {
- getPoint4d_p(points, state->pt, &pt_start);
- getPoint4d_p(points, state->pt + 1, &pt_end);
-
- segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
- ptarray_set_point4d(segment_pa, 0, &pt_start);
- ptarray_set_point4d(segment_pa, 1, &pt_end);
-
- segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
-
- state->pt++;
-
- state->path[state->pathlen] = Int32GetDatum(state->pt);
- pathpt[0] = PointerGetDatum(construct_array(state->path,
- state->pathlen + 1,
- INT4OID,
- state->typlen,
- state->byval,
- state->align));
- pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
-
- tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
- result = HeapTupleGetDatum(tuple);
- SRF_RETURN_NEXT(funcctx, result);
- }
- else
- {
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- continue;
- }
- }
-
- if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE ||
- lwgeom->type == MULTIPOLYGONTYPE || lwgeom->type == TINTYPE)
- {
- lwcoll = (LWCOLLECTION *)node->geom;
-
- /* if a collection and we have more geoms */
- if (node->idx < lwcoll->ngeoms)
- {
- /* push the next geom on the path and the stack */
- lwgeom = lwcoll->geoms[node->idx++];
- state->path[state->pathlen++] = Int32GetDatum(node->idx);
-
- node = &state->stack[state->stacklen++];
- node->idx = 0;
- node->geom = lwgeom;
-
- state->pt = 0;
- state->ring = 0;
-
- /* loop back to beginning, which will then check whatever node we just pushed */
- continue;
- }
- }
-
- /* no more geometries in the current collection */
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- }
-}
commit 7d44a0ddf0968f0bb3543805923dff3c54dfaa42
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Wed May 19 14:25:56 2021 +0300
doc
diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml
index 227b810..8d23ce1 100644
--- a/doc/reference_accessor.xml
+++ b/doc/reference_accessor.xml
@@ -739,6 +739,137 @@ SELECT (g.gdump).path, ST_AsEWKT((g.gdump).geom) as wkt
<xref linkend="ST_Dump" />, <xref linkend="ST_DumpRings" />, <xref linkend="ST_Points" /></para>
</refsection>
</refentry>
+
+ <refentry id="ST_DumpSegments">
+ <refnamediv>
+ <refname>ST_DumpSegments</refname>
+ <refpurpose>Returns a set of <varname>geometry_dump</varname> rows for the segments in a geometry.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>geometry_dump[] <function>ST_DumpSegments</function></funcdef>
+ <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsection>
+ <title>Description</title>
+ <para>A set-returning function (SRF) that extracts the segments of a geometry.
+ It returns a set of
+ <xref linkend="geometry_dump" /> rows,
+ each containing a geometry (<parameter>geom</parameter> field)
+ and an array of integers (<parameter>path</parameter> field).
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the <parameter>geom</parameter> field
+ <varname>LINESTRING</varname>s represent the segments of the supplied geometry.
+ </para>
+ </listitem>
+ <listitem>
+ <para>the <parameter>path</parameter> field (an <varname>integer[]</varname>)
+ is an index enumerating the segment start point positions in the elements of the supplied geometry.
+ The indices are 1-based.
+ For example, for a <varname>LINESTRING</varname> the paths are <varname>{i}</varname>
+ where <varname>i</varname> is the <varname>nth</varname>
+ segment start point in the <varname>LINESTRING</varname>.
+ For a <varname>POLYGON</varname> the paths are <varname>{i,j}</varname> where
+ <varname>i</varname> is the ring number (1 is outer; inner rings follow)
+ and <varname>j</varname> is the segment start point position in the ring.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Availability: 3.2.0</para>
+ <para>&T_support;</para>
+ <para>&Z_support;</para>
+ </refsection>
+
+ <refsection>
+ <title>Standard Geometry Examples</title>
+
+ <programlisting>SELECT path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'GEOMETRYCOLLECTION(
+ LINESTRING(1 1, 3 3, 4 4),
+ POLYGON((5 5, 6 6, 7 7, 5 5))
+)'::geometry AS geom
+ ) AS g
+) j;
+
+ path │ st_astext
+---------------------------------
+ {1,1} │ LINESTRING(1 1,3 3)
+ {1,2} │ LINESTRING(3 3,4 4)
+ {2,1,1} │ LINESTRING(5 5,6 6)
+ {2,1,2} │ LINESTRING(6 6,7 7)
+ {2,1,3} │ LINESTRING(7 7,5 5)
+(5 rows)</programlisting>
+ </refsection>
+ <refsection>
+ <title>TIN and Triangle Examples</title>
+<programlisting>-- Triangle --
+SELECT path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'TRIANGLE((
+ 0 0,
+ 0 9,
+ 9 0,
+ 0 0
+ ))'::geometry AS geom
+ ) AS g
+) j;
+
+ path │ st_astext
+ ---------------------------------
+ {1,1} │ LINESTRING(0 0,0 9)
+ {1,2} │ LINESTRING(0 9,9 0)
+ {1,3} │ LINESTRING(9 0,0 0)
+(3 rows)
+</programlisting>
+<programlisting>-- TIN --
+SELECT path, ST_AsEWKT(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'TIN(((
+ 0 0 0,
+ 0 0 1,
+ 0 1 0,
+ 0 0 0
+ )), ((
+ 0 0 0,
+ 0 1 0,
+ 1 1 0,
+ 0 0 0
+ ))
+ )'::geometry AS geom
+ ) AS g
+) j;
+
+ path │ st_asewkt
+ ---------------------------------
+ {1,1,1} │ LINESTRING(0 0 0,0 0 1)
+ {1,1,2} │ LINESTRING(0 0 1,0 1 0)
+ {1,1,3} │ LINESTRING(0 1 0,0 0 0)
+ {2,1,1} │ LINESTRING(0 0 0,0 1 0)
+ {2,1,2} │ LINESTRING(0 1 0,1 1 0)
+ {2,1,3} │ LINESTRING(1 1 0,0 0 0)
+(6 rows)
+</programlisting>
+ </refsection>
+ <refsection>
+ <title>See Also</title>
+ <para><xref linkend="geometry_dump" />, <xref linkend="PostGIS_Geometry_DumpFunctions" />,
+ <xref linkend="ST_Dump" />, <xref linkend="ST_DumpRings" /></para>
+ </refsection>
+ </refentry>
+
<refentry id="ST_DumpRings">
<refnamediv>
<refname>ST_DumpRings</refname>
commit d7a7f60ff6db7586a2d7bf17f3a57fa31190e5a1
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Wed May 19 12:09:42 2021 +0300
remove copyright
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index 22854dc..9ff3ba1 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -16,10 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
*
- **********************************************************************
- *
- * ^copyright^
- *
**********************************************************************/
#include "postgres.h"
commit 446cfe43844fcedd9a435960388ccb87d1cb0a50
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Wed May 19 12:06:02 2021 +0300
triange + tin
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index d6e7b9c..22854dc 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -146,6 +146,7 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
{
POINTARRAY *points = NULL;
LWLINE *line;
+ LWTRIANGLE *tri;
LWPOLY *poly;
POINT4D pt_start, pt_end;
POINTARRAY *segment_pa;
@@ -154,20 +155,38 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
node = &state->stack[state->stacklen - 1];
lwgeom = node->geom;
- if (lwgeom->type == LINETYPE || lwgeom->type == POLYGONTYPE)
+ if (lwgeom->type == LINETYPE || lwgeom->type == TRIANGLETYPE || lwgeom->type == POLYGONTYPE)
{
if (lwgeom->type == LINETYPE)
{
- line = lwgeom_as_lwline(lwgeom);
+ line = (LWLINE *)lwgeom;
if (state->pt < line->points->npoints - 1)
{
points = line->points;
}
}
+ if (lwgeom->type == TRIANGLETYPE)
+ {
+ tri = (LWTRIANGLE *)lwgeom;
+
+ if (state->pt == 0)
+ {
+ state->path[state->pathlen++] = Int32GetDatum(state->ring + 1);
+ }
+
+ if (state->pt < 3)
+ {
+ points = tri->points;
+ }
+ else
+ {
+ state->pathlen--;
+ }
+ }
if (lwgeom->type == POLYGONTYPE)
{
- poly = lwgeom_as_lwpoly(lwgeom);
+ poly = (LWPOLY *)lwgeom;
if (state->pt == poly->rings[state->ring]->npoints)
{
@@ -175,13 +194,15 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
state->ring++;
state->pathlen--;
}
- if (state->pt == 0 && state->ring < poly->nrings)
- {
- state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
- state->pathlen++;
- }
+
if (state->ring < poly->nrings)
{
+ if (state->pt == 0)
+ {
+ state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
+ state->pathlen++;
+ }
+
if (state->pt < poly->rings[state->ring]->npoints - 1)
{
points = poly->rings[state->ring];
@@ -229,7 +250,8 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
}
}
- if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE || lwgeom->type == MULTIPOLYGONTYPE)
+ if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE ||
+ lwgeom->type == MULTIPOLYGONTYPE || lwgeom->type == TINTYPE)
{
lwcoll = (LWCOLLECTION *)node->geom;
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 652f204..3991021 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -41,3 +41,33 @@ FROM (
)'::geometry AS geom
) AS g
) j;
+
+SELECT 'dumpsegments11', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'TRIANGLE((
+ 0 0,
+ 0 9,
+ 9 0,
+ 0 0
+ ))'::geometry AS geom
+ ) AS g
+ ) j;
+
+SELECT 'dumpsegments12', path, ST_AsEWKT(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'TIN(((
+ 0 0 0,
+ 0 0 1,
+ 0 1 0,
+ 0 0 0
+ )), ((
+ 0 0 0,
+ 0 1 0,
+ 1 1 0,
+ 0 0 0
+ ))
+ )'::geometry AS geom
+ ) AS g
+ ) j;
diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected
index 5abbbe9..5d1c8d3 100644
--- a/regress/core/dumpsegments_expected
+++ b/regress/core/dumpsegments_expected
@@ -24,3 +24,12 @@ dumpsegments10|{1,1}|LINESTRING(1 1,3 3)
dumpsegments10|{2,1,1}|LINESTRING(4 4,5 5)
dumpsegments10|{2,1,2}|LINESTRING(5 5,6 6)
dumpsegments10|{2,1,3}|LINESTRING(6 6,4 4)
+dumpsegments11|{1,1}|LINESTRING(0 0,0 9)
+dumpsegments11|{1,2}|LINESTRING(0 9,9 0)
+dumpsegments11|{1,3}|LINESTRING(9 0,0 0)
+dumpsegments12|{1,1,1}|LINESTRING(0 0 0,0 0 1)
+dumpsegments12|{1,1,2}|LINESTRING(0 0 1,0 1 0)
+dumpsegments12|{1,1,3}|LINESTRING(0 1 0,0 0 0)
+dumpsegments12|{2,1,1}|LINESTRING(0 0 0,0 1 0)
+dumpsegments12|{2,1,2}|LINESTRING(0 1 0,1 1 0)
+dumpsegments12|{2,1,3}|LINESTRING(1 1 0,0 0 0)
commit b8f3067f6f14024b94f93cc1c50d42adc403537e
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 20:39:27 2021 +0300
add availability
diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in
index 98e2e78..41ac569 100644
--- a/postgis/postgis.sql.in
+++ b/postgis/postgis.sql.in
@@ -1960,6 +1960,7 @@ CREATE OR REPLACE FUNCTION ST_DumpPoints(geometry)
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
_COST_HIGH;
+-- Availability: 3.2.0
CREATE OR REPLACE FUNCTION ST_DumpSegments(geometry)
RETURNS SETOF geometry_dump
AS 'MODULE_PATHNAME', 'LWGEOM_dumpsegments'
commit 29852831a2e68f599f024af1e56fd9914d6c2036
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 03:57:42 2021 +0300
fix
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index 7490cd9..d6e7b9c 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -256,6 +256,5 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
if (--state->stacklen == 0)
SRF_RETURN_DONE(funcctx);
state->pathlen--;
- state->stack[state->stacklen - 1].idx++;
}
}
commit 791e686d7d58e78a9c551bad335855357ca2d44d
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 02:23:16 2021 +0300
refactoring
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 4112627..652f204 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -1,21 +1,18 @@
SELECT 'dumpsegments01', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpSegments(g.geom)).*
- FROM
- (SELECT 'LINESTRING(0 0, 0 9, 9 9, 9 0, 0 0)'::geometry AS geom) AS g
- ) j;
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'LINESTRING(0 0, 0 9, 9 9, 9 0, 0 0)'::geometry AS geom) AS g
+ ) j;
SELECT 'dumpsegments02', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpSegments(g.geom)).*
- FROM
- (SELECT
- 'GEOMETRYCOLLECTION(
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'GEOMETRYCOLLECTION(
LINESTRING(1 1, 3 3),
MULTILINESTRING((4 4, 5 5, 6 6, 7 7), (8 8, 9 9, 10 10))
)'::geometry AS geom
- ) AS g
- ) j;
+ ) AS g
+ ) j;
SELECT 'dumpsegments03', ST_DumpSegments('POLYGON EMPTY'::geometry);
SELECT 'dumpsegments04', ST_DumpSegments('MULTIPOLYGON EMPTY'::geometry);
@@ -25,26 +22,22 @@ SELECT 'dumpsegments07', ST_DumpSegments('GEOMETRYCOLLECTION EMPTY'::geometry);
SELECT 'dumpsegments08', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpSegments(g.geom)).*
- FROM
- (SELECT 'POLYGON((4 4, 5 5, 6 6, 4 4), (8 8, 9 9, 10 10, 8 8))'::geometry AS geom) AS g
- ) j;
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'POLYGON((4 4, 5 5, 6 6, 4 4), (8 8, 9 9, 10 10, 8 8))'::geometry AS geom) AS g
+ ) j;
SELECT 'dumpsegments09', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpSegments(g.geom)).*
- FROM
- (SELECT 'MULTIPOLYGON(((4 4, 5 5, 6 6, 4 4)), ((8 8, 9 9, 10 10, 8 8)))'::geometry AS geom) AS g
- ) j;
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'MULTIPOLYGON(((4 4, 5 5, 6 6, 4 4)), ((8 8, 9 9, 10 10, 8 8)))'::geometry AS geom) AS g
+ ) j;
SELECT 'dumpsegments10', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpSegments(g.geom)).*
- FROM
- (SELECT
- 'GEOMETRYCOLLECTION(
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM (SELECT 'GEOMETRYCOLLECTION(
LINESTRING(1 1, 3 3),
POLYGON((4 4, 5 5, 6 6, 4 4))
)'::geometry AS geom
- ) AS g
- ) j;
+ ) AS g
+ ) j;
commit 35ea0c3957af12e955e48fff16540e9d89ea7402
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 02:20:18 2021 +0300
refactoring
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index 585cde3..7490cd9 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -113,7 +113,6 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
/*
* Push a struct dumpnode on the state stack
*/
-
state->stack[0].idx = 0;
state->stack[0].geom = lwgeom;
state->stacklen++;
@@ -145,7 +144,7 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
while (1)
{
- POINTARRAY *points;
+ POINTARRAY *points = NULL;
LWLINE *line;
LWPOLY *poly;
POINT4D pt_start, pt_end;
@@ -165,13 +164,6 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
{
points = line->points;
}
- else
- {
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- continue;
- }
}
if (lwgeom->type == POLYGONTYPE)
{
@@ -188,43 +180,53 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
state->pathlen++;
}
- if (state->ring == poly->nrings)
- {
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- continue;
- }
- else if (state->pt < poly->rings[state->ring]->npoints - 1)
+ if (state->ring < poly->nrings)
{
- points = poly->rings[state->ring];
- }
- else
- {
- state->pt++;
- continue;
+ if (state->pt < poly->rings[state->ring]->npoints - 1)
+ {
+ points = poly->rings[state->ring];
+ }
+ else
+ {
+ state->pt++;
+ continue;
+ }
}
}
- getPoint4d_p(points, state->pt, &pt_start);
- getPoint4d_p(points, state->pt + 1, &pt_end);
+ if (points)
+ {
+ getPoint4d_p(points, state->pt, &pt_start);
+ getPoint4d_p(points, state->pt + 1, &pt_end);
- segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
- ptarray_set_point4d(segment_pa, 0, &pt_start);
- ptarray_set_point4d(segment_pa, 1, &pt_end);
+ segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
+ ptarray_set_point4d(segment_pa, 0, &pt_start);
+ ptarray_set_point4d(segment_pa, 1, &pt_end);
- segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
+ segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
- state->pt++;
+ state->pt++;
- state->path[state->pathlen] = Int32GetDatum(state->pt);
- pathpt[0] = PointerGetDatum(construct_array(
- state->path, state->pathlen + 1, INT4OID, state->typlen, state->byval, state->align));
- pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
+ state->path[state->pathlen] = Int32GetDatum(state->pt);
+ pathpt[0] = PointerGetDatum(construct_array(state->path,
+ state->pathlen + 1,
+ INT4OID,
+ state->typlen,
+ state->byval,
+ state->align));
+ pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
- tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
- result = HeapTupleGetDatum(tuple);
- SRF_RETURN_NEXT(funcctx, result);
+ tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
+ result = HeapTupleGetDatum(tuple);
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
}
if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE || lwgeom->type == MULTIPOLYGONTYPE)
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 3e0259e..4112627 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -2,15 +2,7 @@ SELECT 'dumpsegments01', path, ST_AsText(geom)
FROM (
SELECT (ST_DumpSegments(g.geom)).*
FROM
- (SELECT
- 'LINESTRING(
- 0 0,
- 0 9,
- 9 9,
- 9 0,
- 0 0
- )'::geometry AS geom
- ) AS g
+ (SELECT 'LINESTRING(0 0, 0 9, 9 9, 9 0, 0 0)'::geometry AS geom) AS g
) j;
SELECT 'dumpsegments02', path, ST_AsText(geom)
@@ -35,38 +27,14 @@ SELECT 'dumpsegments08', path, ST_AsText(geom)
FROM (
SELECT (ST_DumpSegments(g.geom)).*
FROM
- (SELECT
- 'POLYGON((
- 4 4,
- 5 5,
- 6 6,
- 4 4
- ), (
- 8 8,
- 9 9,
- 10 10,
- 8 8
- ))'::geometry AS geom
- ) AS g
+ (SELECT 'POLYGON((4 4, 5 5, 6 6, 4 4), (8 8, 9 9, 10 10, 8 8))'::geometry AS geom) AS g
) j;
SELECT 'dumpsegments09', path, ST_AsText(geom)
FROM (
SELECT (ST_DumpSegments(g.geom)).*
FROM
- (SELECT
- 'MULTIPOLYGON(((
- 4 4,
- 5 5,
- 6 6,
- 4 4
- )), ((
- 8 8,
- 9 9,
- 10 10,
- 8 8
- )))'::geometry AS geom
- ) AS g
+ (SELECT 'MULTIPOLYGON(((4 4, 5 5, 6 6, 4 4)), ((8 8, 9 9, 10 10, 8 8)))'::geometry AS geom) AS g
) j;
SELECT 'dumpsegments10', path, ST_AsText(geom)
commit 8488dccb895cd6afc7b5113e1c33699b2e48fbf0
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 00:52:03 2021 +0300
fix
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index 5471a5d..585cde3 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -145,9 +145,6 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
while (1)
{
- node = &state->stack[state->stacklen - 1];
- lwgeom = node->geom;
-
POINTARRAY *points;
LWLINE *line;
LWPOLY *poly;
@@ -155,6 +152,9 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
POINTARRAY *segment_pa;
LWLINE *segment;
+ node = &state->stack[state->stacklen - 1];
+ lwgeom = node->geom;
+
if (lwgeom->type == LINETYPE || lwgeom->type == POLYGONTYPE)
{
if (lwgeom->type == LINETYPE)
commit 22c55934836f841931413d810dab2d7f4f93a9b4
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 00:47:45 2021 +0300
fix
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index 30c5e63..5471a5d 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -149,12 +149,17 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
lwgeom = node->geom;
POINTARRAY *points;
+ LWLINE *line;
+ LWPOLY *poly;
+ POINT4D pt_start, pt_end;
+ POINTARRAY *segment_pa;
+ LWLINE *segment;
- if (!lwgeom_is_collection(lwgeom))
+ if (lwgeom->type == LINETYPE || lwgeom->type == POLYGONTYPE)
{
if (lwgeom->type == LINETYPE)
{
- LWLINE *line = lwgeom_as_lwline(lwgeom);
+ line = lwgeom_as_lwline(lwgeom);
if (state->pt < line->points->npoints - 1)
{
@@ -170,7 +175,7 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
}
if (lwgeom->type == POLYGONTYPE)
{
- LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);
+ poly = lwgeom_as_lwpoly(lwgeom);
if (state->pt == poly->rings[state->ring]->npoints)
{
@@ -201,15 +206,14 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
}
}
- POINT4D pt_start, pt_end;
getPoint4d_p(points, state->pt, &pt_start);
getPoint4d_p(points, state->pt + 1, &pt_end);
- POINTARRAY *segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
+ segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
ptarray_set_point4d(segment_pa, 0, &pt_start);
ptarray_set_point4d(segment_pa, 1, &pt_end);
- LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
+ segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
state->pt++;
commit 181d5fb3981393ab40374b62c7685b4673bbea08
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 00:32:41 2021 +0300
more tests
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 21621a1..3e0259e 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -49,3 +49,34 @@ FROM (
))'::geometry AS geom
) AS g
) j;
+
+SELECT 'dumpsegments09', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM
+ (SELECT
+ 'MULTIPOLYGON(((
+ 4 4,
+ 5 5,
+ 6 6,
+ 4 4
+ )), ((
+ 8 8,
+ 9 9,
+ 10 10,
+ 8 8
+ )))'::geometry AS geom
+ ) AS g
+ ) j;
+
+SELECT 'dumpsegments10', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM
+ (SELECT
+ 'GEOMETRYCOLLECTION(
+ LINESTRING(1 1, 3 3),
+ POLYGON((4 4, 5 5, 6 6, 4 4))
+ )'::geometry AS geom
+ ) AS g
+ ) j;
diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected
index ff06d45..5abbbe9 100644
--- a/regress/core/dumpsegments_expected
+++ b/regress/core/dumpsegments_expected
@@ -14,3 +14,13 @@ dumpsegments08|{1,3}|LINESTRING(6 6,4 4)
dumpsegments08|{2,1}|LINESTRING(8 8,9 9)
dumpsegments08|{2,2}|LINESTRING(9 9,10 10)
dumpsegments08|{2,3}|LINESTRING(10 10,8 8)
+dumpsegments09|{1,1,1}|LINESTRING(4 4,5 5)
+dumpsegments09|{1,1,2}|LINESTRING(5 5,6 6)
+dumpsegments09|{1,1,3}|LINESTRING(6 6,4 4)
+dumpsegments09|{2,1,1}|LINESTRING(8 8,9 9)
+dumpsegments09|{2,1,2}|LINESTRING(9 9,10 10)
+dumpsegments09|{2,1,3}|LINESTRING(10 10,8 8)
+dumpsegments10|{1,1}|LINESTRING(1 1,3 3)
+dumpsegments10|{2,1,1}|LINESTRING(4 4,5 5)
+dumpsegments10|{2,1,2}|LINESTRING(5 5,6 6)
+dumpsegments10|{2,1,3}|LINESTRING(6 6,4 4)
commit 77cb26589d5cc889b9d427c932b67226ed11a041
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Tue May 18 00:22:54 2021 +0300
refactoring
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index daad231..30c5e63 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -148,103 +148,79 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
node = &state->stack[state->stacklen - 1];
lwgeom = node->geom;
- if (lwgeom->type == LINETYPE)
- {
- LWLINE *line = lwgeom_as_lwline(lwgeom);
+ POINTARRAY *points;
- if (state->pt < line->points->npoints - 1)
- {
- POINT4D pt_start, pt_end;
- getPoint4d_p(line->points, state->pt, &pt_start);
- getPoint4d_p(line->points, state->pt + 1, &pt_end);
-
- POINTARRAY *segment_pa =
- ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
- ptarray_set_point4d(segment_pa, 0, &pt_start);
- ptarray_set_point4d(segment_pa, 1, &pt_end);
-
- LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
-
- state->pt++;
-
- state->path[state->pathlen] = Int32GetDatum(state->pt);
- pathpt[0] = PointerGetDatum(construct_array(state->path,
- state->pathlen + 1,
- INT4OID,
- state->typlen,
- state->byval,
- state->align));
- pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
-
- tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
- result = HeapTupleGetDatum(tuple);
- SRF_RETURN_NEXT(funcctx, result);
- }
- else
- {
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- continue;
- }
- }
- if (lwgeom->type == POLYGONTYPE)
+ if (!lwgeom_is_collection(lwgeom))
{
- LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);
-
- if (state->pt == poly->rings[state->ring]->npoints)
+ if (lwgeom->type == LINETYPE)
{
- state->pt = 0;
- state->ring++;
- state->pathlen--;
+ LWLINE *line = lwgeom_as_lwline(lwgeom);
+
+ if (state->pt < line->points->npoints - 1)
+ {
+ points = line->points;
+ }
+ else
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
}
- if (state->pt == 0 && state->ring < poly->nrings)
+ if (lwgeom->type == POLYGONTYPE)
{
- state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
- state->pathlen++;
+ LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);
+
+ if (state->pt == poly->rings[state->ring]->npoints)
+ {
+ state->pt = 0;
+ state->ring++;
+ state->pathlen--;
+ }
+ if (state->pt == 0 && state->ring < poly->nrings)
+ {
+ state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
+ state->pathlen++;
+ }
+ if (state->ring == poly->nrings)
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
+ else if (state->pt < poly->rings[state->ring]->npoints - 1)
+ {
+ points = poly->rings[state->ring];
+ }
+ else
+ {
+ state->pt++;
+ continue;
+ }
}
- if (state->ring == poly->nrings)
- {
- if (--state->stacklen == 0)
- SRF_RETURN_DONE(funcctx);
- state->pathlen--;
- continue;
- }
- else if (state->pt < poly->rings[state->ring]->npoints - 1)
- {
- POINTARRAY *points = poly->rings[state->ring];
- POINT4D pt_start, pt_end;
- getPoint4d_p(points, state->pt, &pt_start);
- getPoint4d_p(points, state->pt + 1, &pt_end);
+ POINT4D pt_start, pt_end;
+ getPoint4d_p(points, state->pt, &pt_start);
+ getPoint4d_p(points, state->pt + 1, &pt_end);
- POINTARRAY *segment_pa =
- ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
- ptarray_set_point4d(segment_pa, 0, &pt_start);
- ptarray_set_point4d(segment_pa, 1, &pt_end);
+ POINTARRAY *segment_pa = ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
+ ptarray_set_point4d(segment_pa, 0, &pt_start);
+ ptarray_set_point4d(segment_pa, 1, &pt_end);
- LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
+ LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
- state->pt++;
+ state->pt++;
- state->path[state->pathlen] = Int32GetDatum(state->pt);
- pathpt[0] = PointerGetDatum(construct_array(state->path,
- state->pathlen + 1,
- INT4OID,
- state->typlen,
- state->byval,
- state->align));
- pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
+ state->path[state->pathlen] = Int32GetDatum(state->pt);
+ pathpt[0] = PointerGetDatum(construct_array(
+ state->path, state->pathlen + 1, INT4OID, state->typlen, state->byval, state->align));
+ pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
- tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
- result = HeapTupleGetDatum(tuple);
- SRF_RETURN_NEXT(funcctx, result);
- }
- else
- {
- state->pt++;
- continue;
- }
+ tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
+ result = HeapTupleGetDatum(tuple);
+ SRF_RETURN_NEXT(funcctx, result);
}
if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE || lwgeom->type == MULTIPOLYGONTYPE)
commit aa018f66b4938ba60ec825b3f478327d2be93382
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Mon May 17 23:57:05 2021 +0300
dumpsegments for polygon
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
index c8b26b7..daad231 100644
--- a/postgis/lwgeom_dumpsegments.c
+++ b/postgis/lwgeom_dumpsegments.c
@@ -158,11 +158,12 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
getPoint4d_p(line->points, state->pt, &pt_start);
getPoint4d_p(line->points, state->pt + 1, &pt_end);
- POINTARRAY *segment_pa = ptarray_construct(lwgeom_has_z(line), lwgeom_has_m(line), 2);
+ POINTARRAY *segment_pa =
+ ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
ptarray_set_point4d(segment_pa, 0, &pt_start);
ptarray_set_point4d(segment_pa, 1, &pt_end);
- LWLINE *segment = lwline_construct(line->srid, NULL, segment_pa);
+ LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
state->pt++;
@@ -187,8 +188,66 @@ Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
continue;
}
}
+ if (lwgeom->type == POLYGONTYPE)
+ {
+ LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);
+
+ if (state->pt == poly->rings[state->ring]->npoints)
+ {
+ state->pt = 0;
+ state->ring++;
+ state->pathlen--;
+ }
+ if (state->pt == 0 && state->ring < poly->nrings)
+ {
+ state->path[state->pathlen] = Int32GetDatum(state->ring + 1);
+ state->pathlen++;
+ }
+ if (state->ring == poly->nrings)
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
+ else if (state->pt < poly->rings[state->ring]->npoints - 1)
+ {
+ POINTARRAY *points = poly->rings[state->ring];
+
+ POINT4D pt_start, pt_end;
+ getPoint4d_p(points, state->pt, &pt_start);
+ getPoint4d_p(points, state->pt + 1, &pt_end);
+
+ POINTARRAY *segment_pa =
+ ptarray_construct(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
+ ptarray_set_point4d(segment_pa, 0, &pt_start);
+ ptarray_set_point4d(segment_pa, 1, &pt_end);
+
+ LWLINE *segment = lwline_construct(lwgeom->srid, NULL, segment_pa);
+
+ state->pt++;
+
+ state->path[state->pathlen] = Int32GetDatum(state->pt);
+ pathpt[0] = PointerGetDatum(construct_array(state->path,
+ state->pathlen + 1,
+ INT4OID,
+ state->typlen,
+ state->byval,
+ state->align));
+ pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
+
+ tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
+ result = HeapTupleGetDatum(tuple);
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ state->pt++;
+ continue;
+ }
+ }
- if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE)
+ if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE || lwgeom->type == MULTIPOLYGONTYPE)
{
lwcoll = (LWCOLLECTION *)node->geom;
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
index 8aaefd5..21621a1 100644
--- a/regress/core/dumpsegments.sql
+++ b/regress/core/dumpsegments.sql
@@ -1,9 +1,9 @@
SELECT 'dumpsegments01', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpPoints(g.geom)).*
+ SELECT (ST_DumpSegments(g.geom)).*
FROM
(SELECT
- 'LINESTRING (
+ 'LINESTRING(
0 0,
0 9,
9 9,
@@ -15,7 +15,7 @@ FROM (
SELECT 'dumpsegments02', path, ST_AsText(geom)
FROM (
- SELECT (ST_DumpPoints(g.geom)).*
+ SELECT (ST_DumpSegments(g.geom)).*
FROM
(SELECT
'GEOMETRYCOLLECTION(
@@ -25,8 +25,27 @@ FROM (
) AS g
) j;
-SELECT 'dumpsegments03', ST_DumpPoints('POLYGON EMPTY'::geometry);
-SELECT 'dumpsegments04', ST_DumpPoints('MULTIPOLYGON EMPTY'::geometry);
-SELECT 'dumpsegments05', ST_DumpPoints('MULTILINESTRING EMPTY'::geometry);
-SELECT 'dumpsegments06', ST_DumpPoints('LINESTRING EMPTY'::geometry);
-SELECT 'dumpsegments07', ST_DumpPoints('GEOMETRYCOLLECTION EMPTY'::geometry);
+SELECT 'dumpsegments03', ST_DumpSegments('POLYGON EMPTY'::geometry);
+SELECT 'dumpsegments04', ST_DumpSegments('MULTIPOLYGON EMPTY'::geometry);
+SELECT 'dumpsegments05', ST_DumpSegments('MULTILINESTRING EMPTY'::geometry);
+SELECT 'dumpsegments06', ST_DumpSegments('LINESTRING EMPTY'::geometry);
+SELECT 'dumpsegments07', ST_DumpSegments('GEOMETRYCOLLECTION EMPTY'::geometry);
+
+SELECT 'dumpsegments08', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpSegments(g.geom)).*
+ FROM
+ (SELECT
+ 'POLYGON((
+ 4 4,
+ 5 5,
+ 6 6,
+ 4 4
+ ), (
+ 8 8,
+ 9 9,
+ 10 10,
+ 8 8
+ ))'::geometry AS geom
+ ) AS g
+ ) j;
diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected
index 5971f54..ff06d45 100644
--- a/regress/core/dumpsegments_expected
+++ b/regress/core/dumpsegments_expected
@@ -8,3 +8,9 @@ dumpsegments02|{2,1,2}|LINESTRING(5 5,6 6)
dumpsegments02|{2,1,3}|LINESTRING(6 6,7 7)
dumpsegments02|{2,2,1}|LINESTRING(8 8,9 9)
dumpsegments02|{2,2,2}|LINESTRING(9 9,10 10)
+dumpsegments08|{1,1}|LINESTRING(4 4,5 5)
+dumpsegments08|{1,2}|LINESTRING(5 5,6 6)
+dumpsegments08|{1,3}|LINESTRING(6 6,4 4)
+dumpsegments08|{2,1}|LINESTRING(8 8,9 9)
+dumpsegments08|{2,2}|LINESTRING(9 9,10 10)
+dumpsegments08|{2,3}|LINESTRING(10 10,8 8)
commit 115203f9b0c4286ec6382c6e1bbe5535772caeb5
Author: kalenikaliaksandr <kalenik.aliaksandr at gmail.com>
Date: Mon May 17 20:18:51 2021 +0300
dumpsegments
diff --git a/postgis/Makefile.in b/postgis/Makefile.in
index 9e42c2e..a4e0de7 100644
--- a/postgis/Makefile.in
+++ b/postgis/Makefile.in
@@ -93,6 +93,7 @@ PG_OBJS= \
lwgeom_triggers.o \
lwgeom_dump.o \
lwgeom_dumppoints.o \
+ lwgeom_dumpsegments.o \
lwgeom_functions_lrs.o \
lwgeom_functions_temporal.o \
lwgeom_rectree.o \
diff --git a/postgis/lwgeom_dumpsegments.c b/postgis/lwgeom_dumpsegments.c
new file mode 100644
index 0000000..c8b26b7
--- /dev/null
+++ b/postgis/lwgeom_dumpsegments.c
@@ -0,0 +1,220 @@
+/**********************************************************************
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.net
+ *
+ * PostGIS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * PostGIS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ **********************************************************************
+ *
+ * ^copyright^
+ *
+ **********************************************************************/
+
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/elog.h"
+#include "utils/array.h"
+#include "utils/geo_decls.h"
+#include "utils/lsyscache.h"
+#include "catalog/pg_type.h"
+#include "funcapi.h"
+
+#include "../postgis_config.h"
+#include "lwgeom_pg.h"
+
+#include "access/htup_details.h"
+
+#include "liblwgeom.h"
+
+Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS);
+
+struct dumpnode {
+ LWGEOM *geom;
+ uint32_t idx; /* which member geom we're working on */
+};
+
+/* 32 is the max depth for st_dump, so it seems reasonable
+ * to use the same here
+ */
+#define MAXDEPTH 32
+struct dumpstate {
+ LWGEOM *root;
+ int stacklen; /* collections/geoms on stack */
+ int pathlen; /* polygon rings and such need extra path info */
+ struct dumpnode stack[MAXDEPTH];
+ Datum path[34]; /* two more than max depth, for ring and point */
+
+ /* used to cache the type attributes for integer arrays */
+ int16 typlen;
+ bool byval;
+ char align;
+
+ uint32_t ring; /* ring of top polygon */
+ uint32_t pt; /* point of top geom or current ring */
+};
+
+PG_FUNCTION_INFO_V1(LWGEOM_dumpsegments);
+Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ MemoryContext oldcontext, newcontext;
+
+ GSERIALIZED *pglwgeom;
+ LWCOLLECTION *lwcoll;
+ LWGEOM *lwgeom;
+ struct dumpstate *state;
+ struct dumpnode *node;
+
+ HeapTuple tuple;
+ Datum pathpt[2]; /* used to construct the composite return value */
+ bool isnull[2] = {0, 0}; /* needed to say neither value is null */
+ Datum result; /* the actual composite return value */
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ funcctx = SRF_FIRSTCALL_INIT();
+
+ newcontext = funcctx->multi_call_memory_ctx;
+ oldcontext = MemoryContextSwitchTo(newcontext);
+
+ pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
+ lwgeom = lwgeom_from_gserialized(pglwgeom);
+
+ /* return early if nothing to do */
+ if (!lwgeom || lwgeom_is_empty(lwgeom))
+ {
+ MemoryContextSwitchTo(oldcontext);
+ funcctx = SRF_PERCALL_SETUP();
+ SRF_RETURN_DONE(funcctx);
+ }
+
+ /* Create function state */
+ state = lwalloc(sizeof *state);
+ state->root = lwgeom;
+ state->stacklen = 0;
+ state->pathlen = 0;
+ state->pt = 0;
+ state->ring = 0;
+
+ funcctx->user_fctx = state;
+
+ /*
+ * Push a struct dumpnode on the state stack
+ */
+
+ state->stack[0].idx = 0;
+ state->stack[0].geom = lwgeom;
+ state->stacklen++;
+
+ /*
+ * get tuple description for return type
+ */
+ if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("set-valued function called in context that cannot accept a set")));
+ }
+
+ BlessTupleDesc(funcctx->tuple_desc);
+
+ /* get and cache data for constructing int4 arrays */
+ get_typlenbyvalalign(INT4OID, &state->typlen, &state->byval, &state->align);
+
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* stuff done on every call of the function */
+ funcctx = SRF_PERCALL_SETUP();
+ newcontext = funcctx->multi_call_memory_ctx;
+
+ /* get state */
+ state = funcctx->user_fctx;
+
+ while (1)
+ {
+ node = &state->stack[state->stacklen - 1];
+ lwgeom = node->geom;
+
+ if (lwgeom->type == LINETYPE)
+ {
+ LWLINE *line = lwgeom_as_lwline(lwgeom);
+
+ if (state->pt < line->points->npoints - 1)
+ {
+ POINT4D pt_start, pt_end;
+ getPoint4d_p(line->points, state->pt, &pt_start);
+ getPoint4d_p(line->points, state->pt + 1, &pt_end);
+
+ POINTARRAY *segment_pa = ptarray_construct(lwgeom_has_z(line), lwgeom_has_m(line), 2);
+ ptarray_set_point4d(segment_pa, 0, &pt_start);
+ ptarray_set_point4d(segment_pa, 1, &pt_end);
+
+ LWLINE *segment = lwline_construct(line->srid, NULL, segment_pa);
+
+ state->pt++;
+
+ state->path[state->pathlen] = Int32GetDatum(state->pt);
+ pathpt[0] = PointerGetDatum(construct_array(state->path,
+ state->pathlen + 1,
+ INT4OID,
+ state->typlen,
+ state->byval,
+ state->align));
+ pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM *)segment));
+
+ tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
+ result = HeapTupleGetDatum(tuple);
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ continue;
+ }
+ }
+
+ if (lwgeom->type == COLLECTIONTYPE || lwgeom->type == MULTILINETYPE)
+ {
+ lwcoll = (LWCOLLECTION *)node->geom;
+
+ /* if a collection and we have more geoms */
+ if (node->idx < lwcoll->ngeoms)
+ {
+ /* push the next geom on the path and the stack */
+ lwgeom = lwcoll->geoms[node->idx++];
+ state->path[state->pathlen++] = Int32GetDatum(node->idx);
+
+ node = &state->stack[state->stacklen++];
+ node->idx = 0;
+ node->geom = lwgeom;
+
+ state->pt = 0;
+ state->ring = 0;
+
+ /* loop back to beginning, which will then check whatever node we just pushed */
+ continue;
+ }
+ }
+
+ /* no more geometries in the current collection */
+ if (--state->stacklen == 0)
+ SRF_RETURN_DONE(funcctx);
+ state->pathlen--;
+ state->stack[state->stacklen - 1].idx++;
+ }
+}
diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in
index 1ef5d29..98e2e78 100644
--- a/postgis/postgis.sql.in
+++ b/postgis/postgis.sql.in
@@ -1960,6 +1960,12 @@ CREATE OR REPLACE FUNCTION ST_DumpPoints(geometry)
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
_COST_HIGH;
+CREATE OR REPLACE FUNCTION ST_DumpSegments(geometry)
+ RETURNS SETOF geometry_dump
+ AS 'MODULE_PATHNAME', 'LWGEOM_dumpsegments'
+ LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
+ _COST_HIGH;
+
-------------------------------------------------------------------
-- SPATIAL_REF_SYS
-------------------------------------------------------------------
diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql
new file mode 100644
index 0000000..8aaefd5
--- /dev/null
+++ b/regress/core/dumpsegments.sql
@@ -0,0 +1,32 @@
+SELECT 'dumpsegments01', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpPoints(g.geom)).*
+ FROM
+ (SELECT
+ 'LINESTRING (
+ 0 0,
+ 0 9,
+ 9 9,
+ 9 0,
+ 0 0
+ )'::geometry AS geom
+ ) AS g
+ ) j;
+
+SELECT 'dumpsegments02', path, ST_AsText(geom)
+FROM (
+ SELECT (ST_DumpPoints(g.geom)).*
+ FROM
+ (SELECT
+ 'GEOMETRYCOLLECTION(
+ LINESTRING(1 1, 3 3),
+ MULTILINESTRING((4 4, 5 5, 6 6, 7 7), (8 8, 9 9, 10 10))
+ )'::geometry AS geom
+ ) AS g
+ ) j;
+
+SELECT 'dumpsegments03', ST_DumpPoints('POLYGON EMPTY'::geometry);
+SELECT 'dumpsegments04', ST_DumpPoints('MULTIPOLYGON EMPTY'::geometry);
+SELECT 'dumpsegments05', ST_DumpPoints('MULTILINESTRING EMPTY'::geometry);
+SELECT 'dumpsegments06', ST_DumpPoints('LINESTRING EMPTY'::geometry);
+SELECT 'dumpsegments07', ST_DumpPoints('GEOMETRYCOLLECTION EMPTY'::geometry);
diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected
new file mode 100644
index 0000000..5971f54
--- /dev/null
+++ b/regress/core/dumpsegments_expected
@@ -0,0 +1,10 @@
+dumpsegments01|{1}|LINESTRING(0 0,0 9)
+dumpsegments01|{2}|LINESTRING(0 9,9 9)
+dumpsegments01|{3}|LINESTRING(9 9,9 0)
+dumpsegments01|{4}|LINESTRING(9 0,0 0)
+dumpsegments02|{1,1}|LINESTRING(1 1,3 3)
+dumpsegments02|{2,1,1}|LINESTRING(4 4,5 5)
+dumpsegments02|{2,1,2}|LINESTRING(5 5,6 6)
+dumpsegments02|{2,1,3}|LINESTRING(6 6,7 7)
+dumpsegments02|{2,2,1}|LINESTRING(8 8,9 9)
+dumpsegments02|{2,2,2}|LINESTRING(9 9,10 10)
diff --git a/regress/core/tests.mk.in b/regress/core/tests.mk.in
index 28e6fe8..0948190 100644
--- a/regress/core/tests.mk.in
+++ b/regress/core/tests.mk.in
@@ -39,6 +39,7 @@ TESTS += \
$(topsrcdir)/regress/core/curvetoline \
$(topsrcdir)/regress/core/dump \
$(topsrcdir)/regress/core/dumppoints \
+ $(topsrcdir)/regress/core/dumpsegments \
$(topsrcdir)/regress/core/empty \
$(topsrcdir)/regress/core/estimatedextent \
$(topsrcdir)/regress/core/forcecurve \
diff --git a/utils/postgis_restore.pl.in b/utils/postgis_restore.pl.in
index 8498c54..93577b9 100644
--- a/utils/postgis_restore.pl.in
+++ b/utils/postgis_restore.pl.in
@@ -2232,6 +2232,7 @@ FUNCTION st_dump(geometry)
FUNCTION st_dumppoints(geometry)
FUNCTION _st_dumppoints(geometry,integer[])
FUNCTION st_dumprings(geometry)
+FUNCTION st_dumpsegments(geometry)
FUNCTION st_dwithin(geography,geography,double precision)
FUNCTION _st_dwithin(geography,geography,double precision,boolean)
FUNCTION st_dwithin(geography,geography,double precision,boolean)
-----------------------------------------------------------------------
Summary of changes:
NEWS | 1 +
doc/reference_accessor.xml | 131 ++++++++++++++++++++++
postgis/lwgeom_dumppoints.c | 215 +++++++++++++++++++++++++++++++++++++
postgis/postgis.sql.in | 7 ++
regress/core/dumpsegments.sql | 73 +++++++++++++
regress/core/dumpsegments_expected | 35 ++++++
regress/core/tests.mk.in | 1 +
utils/postgis_restore.pl.in | 1 +
8 files changed, 464 insertions(+)
create mode 100644 regress/core/dumpsegments.sql
create mode 100644 regress/core/dumpsegments_expected
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list