From e82d7e29ac7217c5ee61a31ad6f3da56e0c30c57 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 28 Sep 2004 08:22:20 +0000 Subject: [PATCH] Added reverse(geometry) and support functions git-svn-id: http://svn.osgeo.org/postgis/trunk@900 b70326c6-7e19-0410-871a-916f4a2858ee --- lwgeom/lwgeom_functions_basic.c | 108 +++++++++++++++++++++++++++++++- lwgeom/lwpostgis.sql.in | 5 ++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index cc836fd18..46a2371f8 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -44,12 +44,15 @@ Datum LWGEOM_to_BOX(PG_FUNCTION_ARGS); Datum LWGEOM_envelope(PG_FUNCTION_ARGS); Datum LWGEOM_isempty(PG_FUNCTION_ARGS); Datum LWGEOM_segmentize2d(PG_FUNCTION_ARGS); +Datum LWGEOM_reverse(PG_FUNCTION_ARGS); // internal char * lwgeom_summary_recursive(char *serialized, int offset); int32 lwgeom_nrings_recursive(char *serialized); void dump_lwexploded(LWGEOM_EXPLODED *exploded); - +POINTARRAY *ptarray_reverse(const POINTARRAY *pa); +LWLINE *lwline_reverse(const LWLINE *line); +LWPOLY *lwpoly_reverse(const LWPOLY *poly); /*------------------------------------------------------------------*/ @@ -752,6 +755,57 @@ lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad) } +POINTARRAY * +ptarray_reverse(const POINTARRAY *ipa) +{ + POINTARRAY *opa; + uint32 i, j; + int ptsize; + + opa = (POINTARRAY *)palloc(sizeof(POINTARRAY)); + opa->ndims = ipa->ndims; + opa->npoints = ipa->npoints; + ptsize = pointArray_ptsize(ipa); + opa->serialized_pointlist = palloc(ipa->npoints*ptsize); + + for (i=0, j=ipa->npoints-1; inpoints; i++, j--) + { + memcpy(getPoint(opa, j), getPoint(ipa, i), ptsize); + } + + return opa; +} + +LWLINE * +lwline_reverse(const LWLINE *iline) +{ + LWLINE *oline; + POINTARRAY *rpa = ptarray_reverse(iline->points); + + oline = lwline_construct(iline->ndims, iline->SRID, rpa); + return oline; +} + +LWPOLY * +lwpoly_reverse(const LWPOLY *ipoly) +{ + LWPOLY *opoly; + POINTARRAY **rpa; + int i; + + rpa = palloc(sizeof(POINTARRAY *)*ipoly->nrings); + + for (i=0; inrings; i++) + { + rpa[i] = ptarray_reverse(ipoly->rings[i]); + } + + opoly = lwpoly_construct(ipoly->ndims, ipoly->SRID, + ipoly->nrings, rpa); + + return opoly; +} + /*------------------------------------------------------------------*/ //find the size of geometry @@ -2726,3 +2780,55 @@ Datum LWGEOM_segmentize2d(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } + +// Reverse vertex order of geometry +PG_FUNCTION_INFO_V1(LWGEOM_reverse); +Datum LWGEOM_reverse(PG_FUNCTION_ARGS) +{ + LWGEOM *geom; + LWGEOM *result = NULL; + LWGEOM_EXPLODED *exp; + int size; + int wantbbox; + int i; + + geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + + if ( lwgeom_getType(geom->type) == COLLECTIONTYPE ) + { + elog(ERROR, "Collection reversing is not supported"); + PG_RETURN_NULL(); + } + + wantbbox = lwgeom_hasBBOX(geom->type); + exp = lwgeom_explode(SERIALIZED_FORM(geom)); + + for (i=0; inlines; i++) + { + LWLINE *line = lwline_deserialize(exp->lines[i]); + LWLINE *rline = lwline_reverse(line); + pfree_line(line); + exp->lines[i] = lwline_serialize(rline); + } + + for (i=0; inpolys; i++) + { + LWPOLY *poly = lwpoly_deserialize(exp->polys[i]); + LWPOLY *rpoly = lwpoly_reverse(poly); + pfree_polygon(poly); + exp->polys[i] = lwpoly_serialize(rpoly); + } + + size = lwexploded_findlength(exp, wantbbox); + result = palloc(size+4); + result->size = (size+4); + lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size); + + if ( result->size != (size+4) ) + { + elog(ERROR, "lwexploded_serialize_buf wrote %d bytes, lwexploded_findlength returned %d", size, result->size-4); + PG_RETURN_NULL(); + } + + PG_RETURN_POINTER(result); +} diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in index 29d67754c..bf280f33d 100644 --- a/lwgeom/lwpostgis.sql.in +++ b/lwgeom/lwpostgis.sql.in @@ -1607,6 +1607,11 @@ CREATEFUNCTION envelope(geometry) AS '@MODULE_FILENAME@', 'LWGEOM_envelope' LANGUAGE 'C' WITH (iscachable,isstrict); +CREATEFUNCTION reverse(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@', 'LWGEOM_reverse' + LANGUAGE 'C' WITH (iscachable,isstrict); + ------------------------------------------------------------------------ -- -- 2.50.1