]> granicus.if.org Git - postgis/commitdiff
Added AddPoint(line, point, [position]) and support API functions.
authorSandro Santilli <strk@keybit.net>
Thu, 28 Oct 2004 09:00:11 +0000 (09:00 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 28 Oct 2004 09:00:11 +0000 (09:00 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1059 b70326c6-7e19-0410-871a-916f4a2858ee

doc/postgis.xml
lwgeom/liblwgeom.h
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_pg.c
lwgeom/lwgeom_pg.h
lwgeom/lwline.c
lwgeom/lwpostgis.sql.in
lwgeom/ptarray.c

index f28dea72a385db0128a64bb51896380b7aa4e0bf..71595142e7c1983025ffeed10f2bfaa817cb4c64 100644 (file)
@@ -3718,20 +3718,31 @@ FROM geometry_table;</literallayout>
                </varlistentry>
 
                <varlistentry>
-                 <term>Polygonize(geometry set)</term>
+                 <term>LineFromMultiPoint(multipoint)</term>
 
                  <listitem>
-                   <para>Aggregate. Creates a MultiPolygon from the costituent
-                   linework of a set of geometries.
-                   Only available when compiled against GEOS >= 2.1.0.</para>
+                   <para>Creates a LineString from a MultiPoint geometry.</para>
                  </listitem>
                </varlistentry>
 
                <varlistentry>
-                 <term>LineFromMultiPoint(multipoint)</term>
+                 <term>AddPoint(linestring, point, [&lt;position&gt;])</term>
 
                  <listitem>
-                   <para>Creates a LineString from a MultiPoint geometry.</para>
+                   <para>Adds a point to a LineString at position &lt;pos&gt;.
+                   Third parameter can be omitted or set to -1 for appending.
+                   </para>
+                 </listitem>
+               </varlistentry>
+
+
+               <varlistentry>
+                 <term>Polygonize(geometry set)</term>
+
+                 <listitem>
+                   <para>Aggregate. Creates a MultiPolygon from the costituent
+                   linework of a set of geometries.
+                   Only available when compiled against GEOS >= 2.1.0.</para>
                  </listitem>
                </varlistentry>
 
index b425f0aee09b1cee55584cfa44b4ef1e527614ae..f25547a1a70830c862f0d016f9b2638bd0f4ba61 100644 (file)
@@ -993,6 +993,7 @@ extern LWPOINT *make_lwpoint3dm(int SRID, double x, double y, double m);
 extern LWPOINT *make_lwpoint4d(int SRID, double x, double y, double z, double m);
 extern LWLINE *lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
 extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
+extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where);
 
 // Return a char string with ASCII versionf of type flags
 extern const char *lwgeom_typeflags(unsigned char type);
@@ -1003,6 +1004,7 @@ extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
 extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts);
 extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts);
 extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts);
+extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, char *p, size_t pdims, unsigned int where);
 
 extern int32 lwgeom_nrings_recursive(char *serialized);
 extern void dump_lwexploded(LWGEOM_EXPLODED *exploded);
index 69f67869bc635340ba4a948502a8041fc39f3ab6..37de87ea9e052afe71ce6bf0ce1e5e493aa3de3e 100644 (file)
@@ -55,6 +55,7 @@ Datum LWGEOM_makepoint(PG_FUNCTION_ARGS);
 Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS);
 Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS);
 Datum LWGEOM_makeline(PG_FUNCTION_ARGS);
+Datum LWGEOM_addpoint(PG_FUNCTION_ARGS);
 
 
 /*------------------------------------------------------------------*/
@@ -2372,3 +2373,39 @@ Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+PG_FUNCTION_INFO_V1(LWGEOM_addpoint);
+Datum LWGEOM_addpoint(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *pglwg1, *pglwg2, *result;
+       LWPOINT *point;
+       LWLINE *line, *outline;
+       int where = -1;
+
+       pglwg1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       pglwg2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+       if ( PG_NARGS() > 2 ) {
+               where = PG_GETARG_INT32(2);
+       }
+
+       if ( ! TYPE_GETTYPE(pglwg1->type) == LINETYPE )
+       {
+               elog(ERROR, "First argument must be a LINESTRING");
+               PG_RETURN_NULL();
+       }
+
+       if ( ! TYPE_GETTYPE(pglwg2->type) == POINTTYPE )
+       {
+               elog(ERROR, "Second argument must be a POINT");
+               PG_RETURN_NULL();
+       }
+
+       line = lwline_deserialize(SERIALIZED_FORM(pglwg1));
+       point = lwpoint_deserialize(SERIALIZED_FORM(pglwg2));
+
+       outline = lwline_addpoint(line, point, where);
+
+       result = pglwgeom_serialize(outline);
+       PG_RETURN_POINTER(result);
+
+}
index bc06e288608ed5a955285424a535b2910f5b1e1c..90439d511603b04e553a53128cf13a9e6f66c3d8 100644 (file)
@@ -100,3 +100,23 @@ init_pg_func()
        lwnotice = pg_notice;
 }
 
+PG_LWGEOM *
+pglwgeom_serialize(LWGEOM *in)
+{
+       size_t size;
+       PG_LWGEOM *result;
+
+       size = lwgeom_serialize_size(in);
+       //lwnotice("lwgeom_serialize_size returned %d", size);
+       result = palloc(size+4);
+       result->size = (size+4);
+       lwgeom_serialize_buf(in, SERIALIZED_FORM(result), &size);
+       if ( size != result->size-4 )
+       {
+               lwerror("lwgeom_serialize size:%d, lwgeom_serialize_size:%d",
+                       size, result->size-4);
+               return NULL;
+       }
+
+       return result;
+}
index 382cf68db0edf309433dd00f6da51b27d1dcaa19..62a94a6768c4641056fc48d5bbe5fb22383bfaf2 100644 (file)
@@ -16,6 +16,9 @@ void pg_free(void *ptr);
 void pg_error(const char *msg, ...);
 void pg_notice(const char *msg, ...);
 
+// Serialize an LWGEOM into a PG_LWGEOM (postgis datatype)
+PG_LWGEOM *pglwgeom_serialize(LWGEOM *lwgeom);
+
 // call this as first thing of any PG function
 void init_pg_func(void);
 
index eeec2ad78603ea0815e4abbde516d4b419414d81..f0ce27836671a14590f83612f8ba20298cb6b343 100644 (file)
@@ -528,3 +528,17 @@ lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint)
 
        return lwline_construct(SRID, NULL, pa);
 }
+
+LWLINE *
+lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where)
+{
+       POINTARRAY *newpa;
+       LWLINE *ret;
+
+       newpa = ptarray_addPoint(line->points, getPoint(point->point, 0),
+               TYPE_NDIMS(point->type), where);
+
+       ret = lwline_construct(line->SRID, NULL, newpa);
+
+       return ret;
+}
index bb6eb981d109c3026cc6e6799e209742073d4a47..8fb88f220e5a175cce9a5c9e3d05c31cd7423e4e 100644 (file)
@@ -1695,7 +1695,17 @@ CREATEFUNCTION makeline_garray (geometry[])
 CREATEFUNCTION LineFromMultiPoint(geometry)
        RETURNS geometry
        AS '@MODULE_FILENAME@', 'LWGEOM_makeline'
-       LANGUAGE 'C';
+       LANGUAGE 'C' WITH (iscachable,isstrict);
+
+CREATEFUNCTION AddPoint(geometry, geometry)
+       RETURNS geometry
+       AS '@MODULE_FILENAME@', 'LWGEOM_addpoint'
+       LANGUAGE 'C' WITH (iscachable,isstrict);
+
+CREATEFUNCTION AddPoint(geometry, geometry, integer)
+       RETURNS geometry
+       AS '@MODULE_FILENAME@', 'LWGEOM_addpoint'
+       LANGUAGE 'C' WITH (iscachable,isstrict);
 
 CREATE AGGREGATE makeline (
        sfunc = geom_accum,
index 2d17236dc71aa38259969ee498e33b911a032e0e..9a27c3b99d4f77d3082d967233811cb22e6bdddf 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "liblwgeom.h"
 
+//#define DEBUG 1
+
 POINTARRAY *
 ptarray_construct(char hasz, char hasm, unsigned int npoints)
 {
@@ -260,3 +262,54 @@ ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
 
        return 1;
 }
+
+/*
+ * Add a point in a pointarray.
+ * 'where' is the offset (starting at 0)
+ * if 'where' == -1 append is required.
+ */
+POINTARRAY *
+ptarray_addPoint(POINTARRAY *pa, char *p, size_t pdims, unsigned int where)
+{
+       POINTARRAY *ret;
+       POINT4D pbuf;
+       size_t ptsize = pointArray_ptsize(pa);
+
+       if ( pdims < 2 || pdims > 4 )
+       {
+               lwerror("ptarray_addPoint: point dimension out of range (%d)",
+                       pdims);
+               return NULL;
+       }
+
+#if DEBUG
+       lwnotice("ptarray_addPoint: called with a %dD point");
+#endif
+       
+       pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0.0;
+       memcpy((char *)&pbuf, p, pdims*sizeof(double));
+
+#if DEBUG
+       lwnotice("ptarray_addPoint: initialized point buffer");
+#endif
+
+       ret = ptarray_construct(TYPE_HASZ(pa->dims),
+               TYPE_HASM(pa->dims), pa->npoints+1);
+       
+       if ( where == -1 ) where = pa->npoints;
+
+       if ( where )
+       {
+               memcpy(getPoint(ret, 0), getPoint(pa, 0), ptsize*where);
+       }
+
+       memcpy(getPoint(ret, where), (char *)&pbuf, ptsize);
+
+       if ( where+1 != ret->npoints )
+       {
+               memcpy(getPoint(ret, where+1), getPoint(pa, where),
+                       ptsize*(pa->npoints-where));
+       }
+
+       return ret;
+}