</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, [<position>])</term>
<listitem>
- <para>Creates a LineString from a MultiPoint geometry.</para>
+ <para>Adds a point to a LineString at position <pos>.
+ 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>
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);
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);
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);
/*------------------------------------------------------------------*/
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);
+
+}
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;
+}
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);
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;
+}
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,
#include "liblwgeom.h"
+//#define DEBUG 1
+
POINTARRAY *
ptarray_construct(char hasz, char hasm, unsigned int npoints)
{
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;
+}