extern LWPOINT *make_lwpoint3dz(int SRID, double x, double y, double z);
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 *make_lwline(int SRID, unsigned int npoints, LWPOINT **points);
// Return a char string with ASCII versionf of type flags
extern const char *lwgeom_typeflags(unsigned char type);
// Construct an empty pointarray
extern POINTARRAY *ptarray_construct(char hasz, char hasm, unsigned int npoints);
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 int32 lwgeom_nrings_recursive(char *serialized);
extern void dump_lwexploded(LWGEOM_EXPLODED *exploded);
extern LWGEOM make_lwpoint3dz(int SRID, double x, double y, double z);
extern LWGEOM make_lwpoint3dm(int SRID, double x, double y, double m);
extern LWGEOM make_lwpoint4d(int SRID, double x, double y, double z, double m);
+extern LWGEOM make_lwline(int SRID, unsigned int npoints, LWGEOM *points);
// Spatial functions
extern void lwgeom_reverse(LWGEOM lwgeom);
Datum LWGEOM_noop(PG_FUNCTION_ARGS);
Datum LWGEOM_zmflag(PG_FUNCTION_ARGS);
Datum LWGEOM_makepoint(PG_FUNCTION_ARGS);
-Datum LWGEOM_makepointm(PG_FUNCTION_ARGS);
+Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS);
+Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS);
/*------------------------------------------------------------------*/
PG_RETURN_POINTER(result);
}
+/*
+ * makeline_garray ( GEOMETRY[] ) returns a LINE formed by
+ * all the point geometries in given array.
+ * array elements that are NOT points are discarded..
+ */
+PG_FUNCTION_INFO_V1(LWGEOM_makeline_garray);
+Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
+{
+ Datum datum;
+ ArrayType *array;
+ int nelems;
+ PG_LWGEOM **geoms;
+ PG_LWGEOM *result=NULL;
+ LWPOINT **lwpoints;
+ LWGEOM *outlwg;
+ size_t size;
+ unsigned int npoints;
+ int i;
+
+//elog(NOTICE, "LWGEOM_makeline_garray called");
+
+ /* Get input datum */
+ datum = PG_GETARG_DATUM(0);
+
+ /* Return null on null input */
+ if ( (Pointer *)datum == NULL )
+ {
+ elog(NOTICE, "NULL input");
+ PG_RETURN_NULL();
+ }
+
+ /* Get actual ArrayType */
+ array = (ArrayType *) PG_DETOAST_DATUM(datum);
+
+ /* Get number of geometries in array */
+ nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
+
+ /* Return null on 0-elements input array */
+ if ( nelems == 0 )
+ {
+ elog(NOTICE, "0 elements input array");
+ PG_RETURN_NULL();
+ }
+
+ /* Get pointer to GEOMETRY pointers array */
+ geoms = (PG_LWGEOM **)ARR_DATA_PTR(array);
+
+ /*
+ * Deserialize all point geometries in array into the
+ * lwpoints pointers array.
+ * Count actual number of points.
+ */
+
+ // possibly more then required
+ lwpoints = palloc(sizeof(LWGEOM *)*nelems);
+ npoints = 0;
+ for (i=0; i<nelems; i++)
+ {
+ if ( TYPE_GETTYPE(geoms[i]->type) != POINTTYPE ) continue;
+ lwpoints[npoints++] =
+ lwpoint_deserialize(SERIALIZED_FORM(geoms[i]));
+ }
+
+ /* Return null on 0-points input array */
+ if ( npoints == 0 )
+ {
+ elog(NOTICE, "No points in input array");
+ PG_RETURN_NULL();
+ }
+
+ outlwg = (LWGEOM *)make_lwline(-1, npoints, lwpoints);
+
+ size = lwgeom_serialize_size(outlwg);
+ //lwnotice("lwgeom_serialize_size returned %d", size);
+ result = palloc(size+4);
+ result->size = (size+4);
+ lwgeom_serialize_buf(outlwg, SERIALIZED_FORM(result), &size);
+ if ( size != result->size-4 )
+ {
+ lwerror("lwgeom_serialize size:%d, lwgeom_serialize_size:%d",
+ size, result->size-4);
+ PG_RETURN_NULL();
+ }
+
+ PG_RETURN_POINTER(result);
+}
+
// makes a polygon of the expanded features bvol - 1st point = LL 3rd=UR
// 2d only. (3d might be worth adding).
// create new geometry of type polygon, 1 ring, 5 points
Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS)
{
double x,y,m;
- int SRID;
LWPOINT *point;
PG_LWGEOM *result;
size_t size;
y = PG_GETARG_FLOAT8(1);
m = PG_GETARG_FLOAT8(2);
- point = make_lwpoint3dm(SRID, x, y, m);
+ point = make_lwpoint3dm(-1, x, y, m);
size = lwpoint_serialize_size(point);
result = (PG_LWGEOM *)palloc(size+4);
return ptarray_same(l1->points, l2->points);
}
+/*
+ * Construct a LWLINE from an array of LWPOINTs
+ * LWLINE dimensions are large enought to host all input dimensions.
+ */
+LWLINE *
+make_lwline(int SRID, unsigned int npoints, LWPOINT **points)
+{
+ int zmflag=0;
+ unsigned int i;
+ POINTARRAY *pa;
+
+ /*
+ * Find output dimensions
+ */
+ for (i=0; i<npoints; i++)
+ {
+ zmflag = TYPE_GETZM(points[i]->type);
+ if ( zmflag == 3 ) break;
+ }
+
+ /* Allocate space for output pointarray */
+ pa = ptarray_construct(zmflag&2, zmflag&1, npoints);
+
+ /*
+ * Fill pointarray
+ */
+ switch (zmflag)
+ {
+ case 0: // 2d
+ for (i=0; i<npoints; i++)
+ getPoint2d_p(points[i]->point, 0,
+ (POINT2D *)getPoint(pa, i));
+ case 1: // 3dm
+ for (i=0; i<npoints; i++)
+ getPoint3dm_p(points[i]->point, 0,
+ (POINT3DM *)getPoint(pa, i));
+ case 2: // 3dz
+ for (i=0; i<npoints; i++)
+ getPoint3dz_p(points[i]->point, 0,
+ (POINT3DZ *)getPoint(pa, i));
+ default: // 4d
+ for (i=0; i<npoints; i++)
+ getPoint4d_p(points[i]->point, 0,
+ (POINT4D *)getPoint(pa, i));
+ }
+
+ return lwline_construct(SRID, NULL, pa);
+}
+
-- CONSTRUCTORS
------------------------------------------------------------------------
-CREATEFUNCTION makepoint(float8, float8)
+CREATEFUNCTION makePoint(float8, float8)
RETURNS geometry
AS '@MODULE_FILENAME@', 'LWGEOM_makepoint'
LANGUAGE 'C' WITH (iscachable,isstrict);
-CREATEFUNCTION makepoint(float8, float8, float8)
+CREATEFUNCTION makePoint(float8, float8, float8)
RETURNS geometry
AS '@MODULE_FILENAME@', 'LWGEOM_makepoint'
LANGUAGE 'C' WITH (iscachable,isstrict);
-CREATEFUNCTION makepoint(float8, float8, float8, float8)
+CREATEFUNCTION makePoint(float8, float8, float8, float8)
RETURNS geometry
AS '@MODULE_FILENAME@', 'LWGEOM_makepoint'
LANGUAGE 'C' WITH (iscachable,isstrict);
AS '@MODULE_FILENAME@', 'LWGEOM_makepoint3dm'
LANGUAGE 'C' WITH (iscachable,isstrict);
+CREATEFUNCTION makeline_garray (geometry[])
+ RETURNS geometry
+ AS '@MODULE_FILENAME@', 'LWGEOM_makeline_garray'
+ LANGUAGE 'C';
+
+CREATE AGGREGATE makeLine (
+ sfunc = geom_accum,
+ basetype = geometry,
+ stype = geometry[],
+ finalfunc = makeline_garray
+ );
+
------------------------------------------------------------------------
--
return pa;
}
+POINTARRAY *
+ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts)
+{
+ POINTARRAY *pa = ptarray_construct(1, 0, npoints);
+ uint32 i;
+
+ for (i=0; i<npoints; i++)
+ {
+ POINT3DZ *pap = (POINT3DZ *)getPoint(pa, i);
+ pap->x = pts[i].x;
+ pap->y = pts[i].y;
+ pap->z = pts[i].z;
+ }
+
+ return pa;
+}
+
+POINTARRAY *
+ptarray_construct3dm(uint32 npoints, const POINT3DM *pts)
+{
+ POINTARRAY *pa = ptarray_construct(0, 1, npoints);
+ uint32 i;
+
+ for (i=0; i<npoints; i++)
+ {
+ POINT3DM *pap = (POINT3DM *)getPoint(pa, i);
+ pap->x = pts[i].x;
+ pap->y = pts[i].y;
+ pap->m = pts[i].m;
+ }
+
+ return pa;
+}
+
+POINTARRAY *
+ptarray_construct4d(uint32 npoints, const POINT4D *pts)
+{
+ POINTARRAY *pa = ptarray_construct(0, 1, npoints);
+ uint32 i;
+
+ for (i=0; i<npoints; i++)
+ {
+ POINT4D *pap = (POINT4D *)getPoint(pa, i);
+ pap->x = pts[i].x;
+ pap->y = pts[i].y;
+ pap->z = pts[i].z;
+ pap->m = pts[i].m;
+ }
+
+ return pa;
+}
+
void
ptarray_reverse(POINTARRAY *pa)
{