]> granicus.if.org Git - postgis/commitdiff
Added reverse(geometry) and support functions
authorSandro Santilli <strk@keybit.net>
Tue, 28 Sep 2004 08:22:20 +0000 (08:22 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 28 Sep 2004 08:22:20 +0000 (08:22 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@900 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom_functions_basic.c
lwgeom/lwpostgis.sql.in

index cc836fd1895b9305f50430b9978f5374d9a849a1..46a2371f822ffa3d7584e752713d07815a085512 100644 (file)
@@ -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; i<ipa->npoints; 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; i<ipoly->nrings; 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; i<exp->nlines; 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; i<exp->npolys; 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);
+}
index 29d67754c00fe4cf4a04f5032791e06e4cb81aab..bf280f33dda7b841473f033e9a0bdcd1a4e532ed 100644 (file)
@@ -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);
+
 ------------------------------------------------------------------------
 
 --