- have lwgeom_collect (or lwcollection_construct) use widest dimensions
- based on input dimensions.
+ based on input dimensions (really?).
- makeline, makepoly: aggregates on single types or functions on multitypes ?
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);
+extern LWLINE *lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
+extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
// Return a char string with ASCII versionf of type flags
extern const char *lwgeom_typeflags(unsigned char type);
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_makepoint(PG_FUNCTION_ARGS);
Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS);
Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS);
+Datum LWGEOM_makeline(PG_FUNCTION_ARGS);
/*------------------------------------------------------------------*/
PG_RETURN_POINTER(result);
}
+/*
+ * makeline ( GEOMETRY ) returns a LINE formed by
+ * all the points in the in given multipoint.
+ */
+PG_FUNCTION_INFO_V1(LWGEOM_makeline);
+Datum LWGEOM_makeline(PG_FUNCTION_ARGS)
+{
+ PG_LWGEOM *ingeom, *result;
+ LWLINE *lwline;
+ LWMPOINT *mpoint;
+ size_t size;
+
+#ifdef DEBUG
+ elog(NOTICE, "LWGEOM_makeline called");
+#endif
+
+ /* Get input PG_LWGEOM and deserialize it */
+ ingeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+ if ( TYPE_GETTYPE(ingeom->type) != MULTIPOINTTYPE )
+ {
+ elog(ERROR, "makeline: input must be a multipoint");
+ PG_RETURN_NULL(); // input is not a multipoint
+ }
+
+ mpoint = lwmpoint_deserialize(SERIALIZED_FORM(ingeom));
+ lwline = lwline_from_lwmpoint(-1, mpoint);
+ if ( ! lwline )
+ {
+ elog(ERROR, "makeline: lwline_from_lwmpoint returned NULL");
+ PG_RETURN_NULL();
+ }
+
+ size = lwline_serialize_size(lwline);
+ result = palloc(size+4);
+ result->size = (size+4);
+ lwline_serialize_buf(lwline, 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);
+}
+
/*
* makeline_garray ( GEOMETRY[] ) returns a LINE formed by
* all the point geometries in given array.
elog(NOTICE, "LWGEOM_makeline_garray: point elements: %d", npoints);
#endif
- outlwg = (LWGEOM *)make_lwline(-1, npoints, lwpoints);
+ outlwg = (LWGEOM *)lwline_from_lwpointarray(-1, npoints, lwpoints);
size = lwgeom_serialize_size(outlwg);
//lwnotice("lwgeom_serialize_size returned %d", size);
/*
* Construct a LWLINE from an array of LWPOINTs
- * LWLINE dimensions are large enought to host all input dimensions.
+ * LWLINE dimensions are large enough to host all input dimensions.
*/
LWLINE *
-make_lwline(int SRID, unsigned int npoints, LWPOINT **points)
+lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
{
int zmflag=0;
unsigned int i;
{
if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE )
{
- lwerror("make_lwline: invalid input type: %s",
+ lwerror("lwline_from_lwpointarray: invalid input type: %s",
lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
return NULL;
}
pa = ptarray_construct(zmflag&2, zmflag&1, npoints);
#ifdef DEBUG
- lwnotice("make_lwline: constructed pointarray for %d points, %d zmflag",
+ lwnotice("lwline_from_lwpointarray: constructed pointarray for %d points, %d zmflag",
npoints, zmflag);
#endif
break;
default:
- lwerror ("make_lwline: unespected ZMflag: %d", zmflag);
+ lwerror ("lwline_from_lwpointarray: unespected ZMflag: %d", zmflag);
+ return NULL;
+ }
+
+ return lwline_construct(SRID, NULL, pa);
+}
+
+/*
+ * Construct a LWLINE from a LWMPOINT
+ */
+LWLINE *
+lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint)
+{
+ unsigned int i;
+ POINTARRAY *pa;
+ char zmflag = TYPE_GETZM(mpoint->type);
+
+ /* Allocate space for output pointarray */
+ pa = ptarray_construct(TYPE_HASZ(mpoint->type),
+ TYPE_HASM(mpoint->type), mpoint->ngeoms);
+
+#ifdef DEBUG
+ lwnotice("lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
+#endif
+
+ /*
+ * Fill pointarray
+ */
+ switch (zmflag)
+ {
+ case 0: // 2d
+ for (i=0; i<mpoint->ngeoms; i++)
+ getPoint2d_p(mpoint->geoms[i]->point, 0,
+ (POINT2D *)getPoint(pa, i));
+ break;
+
+ case 1: // 3dm
+ for (i=0; i<mpoint->ngeoms; i++)
+ getPoint3dm_p(mpoint->geoms[i]->point, 0,
+ (POINT3DM *)getPoint(pa, i));
+ break;
+
+ case 2: // 3dz
+ for (i=0; i<mpoint->ngeoms; i++)
+ getPoint3dz_p(mpoint->geoms[i]->point, 0,
+ (POINT3DZ *)getPoint(pa, i));
+ break;
+
+ case 3: // 4d
+ for (i=0; i<mpoint->ngeoms; i++)
+ getPoint4d_p(mpoint->geoms[i]->point, 0,
+ (POINT4D *)getPoint(pa, i));
+ break;
+
+ default:
+ lwerror ("lwline_from_lwmpoint: unespected ZMflag: %d", zmflag);
return NULL;
}
AS '@MODULE_FILENAME@', 'LWGEOM_makeline_garray'
LANGUAGE 'C';
-CREATE AGGREGATE makeLine (
+CREATEFUNCTION makeline_from_multipoint(geometry)
+ RETURNS geometry
+ AS '@MODULE_FILENAME@', 'LWGEOM_makeline'
+ LANGUAGE 'C';
+
+CREATE AGGREGATE makeline (
sfunc = geom_accum,
basetype = geometry,
stype = geometry[],