]> granicus.if.org Git - postgis/commitdiff
makeline_from_multipoint() implemented and exposed.
authorSandro Santilli <strk@keybit.net>
Fri, 15 Oct 2004 16:21:33 +0000 (16:21 +0000)
committerSandro Santilli <strk@keybit.net>
Fri, 15 Oct 2004 16:21:33 +0000 (16:21 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1017 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/TODO
lwgeom/liblwgeom.h
lwgeom/lwgeom.h
lwgeom/lwgeom_functions_basic.c
lwgeom/lwline.c
lwgeom/lwpostgis.sql.in

index 5c05e028cc171e8ec4da4ce016a23c5df085a96d..ec12de518f2095552aa62e75b7552e20ef0a4e02 100644 (file)
@@ -1,5 +1,5 @@
 - 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 ?
 
index 72c2156474c0b565dbfd32aea7a3ddfa237ee3f9..ecd5e6bf81310bdbd14934c891dc4136b69c7b71 100644 (file)
@@ -990,7 +990,8 @@ extern LWPOINT *make_lwpoint2d(int SRID, double x, double y);
 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);
index 30e99272345962e0fb54f53a4d99a9136617ae30..55590be1d8317abf4a84a58f50bee43650d66790 100644 (file)
@@ -38,7 +38,6 @@ extern LWGEOM make_lwpoint2d(int SRID, double x, double y);
 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);
index 6254cbbef2492b6e7c74962c2e9e99ad05154f8a..1f445f7cb3a9a5d457799d55394a8b6eb91b3b6e 100644 (file)
@@ -53,6 +53,7 @@ Datum LWGEOM_zmflag(PG_FUNCTION_ARGS);
 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);
 
 
 /*------------------------------------------------------------------*/
@@ -1757,6 +1758,53 @@ Datum LWGEOM_collect_garray(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.
@@ -1845,7 +1893,7 @@ Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
        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);
index f167f097be5447213f231654ba38b71d278169cb..f0ec7084d76fb7d20cfe3714e89b1aa2abc901e2 100644 (file)
@@ -376,10 +376,10 @@ lwline_same(const LWLINE *l1, const LWLINE *l2)
 
 /*
  * 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;
@@ -392,7 +392,7 @@ make_lwline(int SRID, unsigned int npoints, LWPOINT **points)
        {
                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;
                }
@@ -405,7 +405,7 @@ make_lwline(int SRID, unsigned int npoints, LWPOINT **points)
        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
 
@@ -439,7 +439,62 @@ make_lwline(int SRID, unsigned int npoints, LWPOINT **points)
                        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;
        }
 
index f8ddc5cd23bee706a3302802678de7bc18d06d04..3f47cb3a3615016bf811b973fe4e49e96f067bb4 100644 (file)
@@ -1677,7 +1677,12 @@ CREATEFUNCTION makeline_garray (geometry[])
        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[],