]> granicus.if.org Git - postgis/commitdiff
Added missing liblwgeom.c file.
authorSandro Santilli <strk@keybit.net>
Thu, 30 Sep 2004 08:18:06 +0000 (08:18 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 30 Sep 2004 08:18:06 +0000 (08:18 +0000)
Made LWMPOINT, LWMLINE, LWMPOLY compatible with LWCOLLECTION.
Fixed reverse() and forcerhr() to maintain geometry structure.

git-svn-id: http://svn.osgeo.org/postgis/trunk@912 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/liblwgeom.c [new file with mode: 0644]
lwgeom/liblwgeom.h
lwgeom/lwgeom.c
lwgeom/lwgeom.h
lwgeom/lwgeom_api.c
lwgeom/lwgeom_functions_basic.c
lwgeom/lwmline.c
lwgeom/lwmpoint.c
lwgeom/lwmpoly.c

diff --git a/lwgeom/liblwgeom.c b/lwgeom/liblwgeom.c
new file mode 100644 (file)
index 0000000..a3b6883
--- /dev/null
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "lwgeom_pg.h"
+#include "liblwgeom.h"
+
+#define CONTEXT_PG 0
+#define CONTEXT_SA 1
+
+#define DEFAULT_CONTEXT CONTEXT_PG
+
+/* Global variables */
+#if DEFAULT_CONTEXT == SA
+lwallocator lwalloc = default_allocator;
+lwreallocator lwrealloc = default_reallocator;
+lwfreeor lwfree = default_freeor;
+lwreporter lwerror = default_errorreporter;
+lwreporter lwnotice = default_noticereporter;
+#else
+lwallocator lwalloc = pg_alloc;
+lwreallocator lwrealloc = pg_realloc;
+lwfreeor lwfree = pg_free;
+lwreporter lwerror = pg_error;
+lwreporter lwnotice = pg_notice;
+#endif
+
+
+void *
+default_allocator(size_t size)
+{
+       void *mem = malloc(size);
+       return mem;
+}
+
+void
+default_freeor(void *mem)
+{
+       free(mem);
+}
+
+void *
+default_reallocator(void *mem, size_t size)
+{
+       void *ret = realloc(mem, size);
+       return ret;
+}
+
+void
+default_noticereporter(const char *fmt, ...)
+{
+       char *msg;
+       va_list ap;
+
+       va_start (ap, fmt);
+
+       /*
+       * This is a GNU extension.
+       * Dunno how to handle errors here.
+       */
+       if (!vasprintf (&msg, fmt, ap))
+       {
+               va_end (ap);
+               return;
+       }
+       va_end(ap);
+       printf("%s", msg);
+       free(msg);
+}
+
+void
+default_errorreporter(const char *fmt, ...)
+{
+       char *msg;
+       va_list ap;
+
+       va_start (ap, fmt);
+
+       /*
+       * This is a GNU extension.
+       * Dunno how to handle errors here.
+       */
+       if (!vasprintf (&msg, fmt, ap))
+       {
+               va_end (ap);
+               return;
+       }
+       va_end(ap);
+       fprintf(stderr, "%s", msg);
+       free(msg);
+}
index 31a041c93fece74169383aa4a720485ae1def3bd..0ec1b1ea7facbd9c34788e0315840646cc4ec242 100644 (file)
@@ -363,7 +363,7 @@ extern BOX3D *lwline_findbbox(LWLINE *line);
 
 typedef struct
 {
-       char type;
+       int type;
        int32 SRID;
        char ndims;
        int  nrings;
@@ -402,8 +402,8 @@ typedef struct
        int type;
        int32 SRID;
        char ndims;
-       int  npoints;
-       LWPOINT **points;
+       int  ngeoms;
+       LWPOINT **geoms;
 } LWMPOINT; 
 
 extern size_t lwmpoint_serialize_size(LWMPOINT *mpoint);
@@ -415,8 +415,8 @@ typedef struct
        int type;
        int32 SRID;
        char ndims;
-       int  nlines;
-       LWLINE **lines;
+       int  ngeoms;
+       LWLINE **geoms;
 } LWMLINE; 
 
 extern size_t lwmline_serialize_size(LWMLINE *mline);
@@ -428,8 +428,8 @@ typedef struct
        int type;
        int32 SRID;
        char ndims;
-       int  npolys;
-       LWPOLY **polys;
+       int  ngeoms;
+       LWPOLY **geoms;
 } LWMPOLY; 
 
 extern size_t lwmpoly_serialize_size(LWMPOLY *mpoly);
@@ -494,7 +494,7 @@ typedef struct
        const char  *serialized_form; // orginal structure
        unsigned char  type;            // 8-bit type for the LWGEOM
        int ngeometries;        // number of sub-geometries
-       char * * const sub_geoms;  // list of pointers (into serialized_form) of the sub-geoms
+       char **sub_geoms;  // list of pointers (into serialized_form) of the sub-geoms
 } LWGEOM_INSPECTED;
 
 extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number);
@@ -861,5 +861,10 @@ extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad)
 extern POINTARRAY *segmentize2d_ptarray(POINTARRAY *ipa, double dist);
 extern int32 lwgeom_npoints(char *serialized);
 extern char ptarray_isccw(const POINTARRAY *pa);
+extern void lwgeom_reverse(LWGEOM *lwgeom);
+extern void lwline_reverse(LWLINE *line);
+extern void lwpoly_reverse(LWPOLY *poly);
+extern void lwpoly_forceRHR(LWPOLY *poly);
+extern void lwgeom_forceRHR(LWGEOM *lwgeom);
 
 #endif // !defined _LIBLWGEOM_H 
index 2f163b8fc7744c55ad160e3306ecc1385d998d40..67e5997857595aaa919923bfe2e321ecc984881d 100644 (file)
@@ -128,3 +128,50 @@ lwgeom_serialize(LWGEOM *lwgeom, char wantbbox)
        return serialized;
 }
 
+// Force Right-hand-rule on LWGEOM polygons
+void
+lwgeom_forceRHR(LWGEOM *lwgeom)
+{
+       LWCOLLECTION *coll;
+       int i;
+
+       switch (lwgeom->type)
+       {
+               case POLYGONTYPE:
+                       lwpoly_reverse((LWPOLY *)lwgeom);
+                       return;
+
+               case MULTIPOLYGONTYPE:
+               case COLLECTIONTYPE:
+                       coll = (LWCOLLECTION *)lwgeom;
+                       for (i=0; i<coll->ngeoms; i++)
+                               lwgeom_forceRHR(coll->geoms[i]);
+                       return;
+       }
+}
+
+// Reverse vertex order of LWGEOM
+void
+lwgeom_reverse(LWGEOM *lwgeom)
+{
+       int i;
+       LWCOLLECTION *col;
+
+       switch (lwgeom->type)
+       {
+               case LINETYPE:
+                       lwline_reverse((LWLINE *)lwgeom);
+                       return;
+               case POLYGONTYPE:
+                       lwpoly_reverse((LWPOLY *)lwgeom);
+                       return;
+               case MULTILINETYPE:
+               case MULTIPOLYGONTYPE:
+               case COLLECTIONTYPE:
+                       col = (LWCOLLECTION *)lwgeom;
+                       for (i=0; i<col->ngeoms; i++)
+                               lwgeom_reverse(col->geoms[i]);
+                       return;
+       }
+}
+
index 2cb8d0d2aca9d06711724a55c444a707b31ea788..70f5ca78d8eeb3dc205423e73d1f5ec0b96252a2 100644 (file)
@@ -1,826 +1,4 @@
-//lwgeom.h
+typedef struct LWGEOM_T LWGEOM;
 
-// basic API for handling the LWGEOM, BOX2DFLOAT4, LWPOINT, LWLINE, and LWPOLY.
-// See below for other support types like POINTARRAY and LWGEOM_INSPECTED
-
-#include <sys/types.h>
-#include "utils/geo_decls.h"
-
-
-typedef struct
-{
-       float xmin;
-       float ymin;
-       float xmax;
-       float ymax;
-} BOX2DFLOAT4;
-
-typedef struct
-{
-        double xmin, ymin, zmin;
-        double xmax, ymax, zmax;
-} BOX3D;
-
-
-typedef struct chiptag
-{
-       int size; //unused (for use by postgresql)
-
-       int endian_hint;  // the number 1 in the endian of this datastruct
-
-       BOX3D bvol;
-       int SRID;
-       char future[4];
-       float factor;   // Usually 1.0.
-                       // Integer values are multiplied by this number
-                       // to get the actual height value
-                       // (for sub-meter accuracy height data).
-
-       int datatype;   // 1 = float32,
-                       // 5 = 24bit integer,
-                       // 6 = 16bit integer (short)
-                       // 101 = float32 (NDR),
-                       // 105 = 24bit integer (NDR),
-                       // 106=16bit int (NDR)
-
-       int height;
-       int width;
-       int compression;        // 0 = no compression, 1 = differencer
-                               // 0x80 = new value
-                               // 0x7F = nodata
-
-       // this is provided for convenience, it should be set to
-       //  sizeof(chip) bytes into the struct because the serialized form is:
-       //    <header><data>
-       // NULL when serialized
-       void  *data;    // data[0] = bottm left,
-                       // data[width] = 1st pixel, 2nd row (uncompressed)
-
-} CHIP;
-
-/*
- * standard definition of an ellipsoid (what wkt calls a spheroid)
- *    f = (a-b)/a
- *    e_sq = (a*a - b*b)/(a*a)
- *    b = a - fa
- */
-typedef struct
-{
-       double  a;      //semimajor axis
-       double  b;      //semiminor axis
-       double  f;      //flattening
-       double  e;      //eccentricity (first)
-       double  e_sq;   //eccentricity (first), squared
-       char            name[20]; //name of ellipse
-} SPHEROID;
-
-
-// POINT3D already defined in postgis.h
-// ALL LWGEOM structures will use POINT3D as an abstract point.
-// This means a 2d geometry will be stored as (x,y) in its serialized
-// form, but all functions will work on (x,y,0).  This keeps all the
-// analysis functions simple.
-// NOTE: for GEOS integration, we'll probably set z=NaN
-//        so look out - z might be NaN for 2d geometries!
-typedef struct { double        x,y,z; } POINT3D;
-
-
-// type for 2d points.  When you convert this to 3d, the
-//   z component will be either 0 or NaN.
-typedef struct
-{
-        double x;
-        double y;
-} POINT2D;
-
-typedef struct
-{
-        double x;
-        double y;
-        double z;
-        double m;
-} POINT4D;
-
-// Point array abstracts a lot of the complexity of points and point lists.
-// It handles miss-alignment in the serialized form, 2d/3d translation
-//    (2d points converted to 3d will have z=0 or NaN)
-// DONT MIX 2D and 3D POINTS!  *EVERYTHING* is either one or the other
-typedef struct
-{
-    char  *serialized_pointlist; // array of POINT 2D, 3D or 4D.
-                                // probably missaligned.
-                                // points to a double
-    char  ndims;                // 2=2d, 3=3d, 4=4d
-    uint32 npoints;
-}  POINTARRAY;
-
-// copies a point from the point array into the parameter point
-// will set point's z=0 (or NaN) if pa is 2d
-// will set point's m=0 (or NaN( if pa is 3d or 2d
-// NOTE: point is a real POINT3D *not* a pointer
-extern POINT4D getPoint4d(const POINTARRAY *pa, int n);
-
-// copies a point from the point array into the parameter point
-// will set point's z=0 (or NaN) if pa is 2d
-// will set point's m=0 (or NaN) if pa is 3d or 2d
-// NOTE: this will modify the point4d pointed to by 'point'.
-extern void getPoint4d_p(const POINTARRAY *pa, int n, char *point);
-
-// copies a point from the point array into the parameter point
-// will set point's z=0 (or NaN) if pa is 2d
-// NOTE: point is a real POINT3D *not* a pointer
-extern POINT3D getPoint3d(const POINTARRAY *pa, int n);
-
-// copies a point from the point array into the parameter point
-// will set point's z=0 (or NaN) if pa is 2d
-// NOTE: this will modify the point3d pointed to by 'point'.
-extern void getPoint3d_p(const POINTARRAY *pa, int n, char *point);
-
-
-// copies a point from the point array into the parameter point
-// z value (if present is not returned)
-// NOTE: point is a real POINT3D *not* a pointer
-extern POINT2D getPoint2d(const POINTARRAY *pa, int n);
-
-// copies a point from the point array into the parameter point
-// z value (if present is not returned)
-// NOTE: this will modify the point2d pointed to by 'point'.
-extern void getPoint2d_p(const POINTARRAY *pa, int n, char *point);
-
-// get a pointer to nth point of a POINTARRAY
-// You'll need to cast it to appropriate dimensioned point.
-// Note that if you cast to a higher dimensional point you'll
-// possibly corrupt the POINTARRAY.
-extern char *getPoint(const POINTARRAY *pa, int n);
-//--- here is a macro equivalent, for speed...
-//#define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] )
-
-
-// constructs a POINTARRAY.
-// NOTE: points is *not* copied, so be careful about modification (can be aligned/missaligned)
-// NOTE: ndims is descriptive - it describes what type of data 'points'
-//       points to.  No data conversion is done.
-extern POINTARRAY *pointArray_construct(char *points, int ndims, uint32 npoints);
-
-//calculate the bounding box of a set of points
-// returns a 3d box
-// if pa is 2d, then box3d's zmin/zmax will be either 0 or NaN
-// dont call on an empty pa
-extern BOX3D *pointArray_bbox(const POINTARRAY *pa);
-
-//size of point represeneted in the POINTARRAY
-// 16 for 2d, 24 for 3d, 32 for 4d
-extern int pointArray_ptsize(const POINTARRAY *pa);
-
-
-/*
- *
- * LWGEOM types are an 8-bit char in this format:
- *
- * BSDDtttt
- *
- * WHERE
- *    B = 16 byte BOX2DFLOAT4 follows (probably not aligned) [before SRID]
- *    S = 4 byte SRID attached (0= not attached (-1), 1= attached)
- *    DD = dimentionality (0=2d, 1=3d, 2= 4d)
- *    tttt = actual type (as per the WKB type):
- *
- *    enum wkbGeometryType {
- *        wkbPoint = 1,
- *        wkbLineString = 2,
- *        wkbPolygon = 3,
- *        wkbMultiPoint = 4,
- *        wkbMultiLineString = 5,
- *        wkbMultiPolygon = 6,
- *        wkbGeometryCollection = 7
- *    };
- *
- */
-#define        POINTTYPE       1
-#define        LINETYPE        2
-#define        POLYGONTYPE     3
-#define        MULTIPOINTTYPE  4
-#define        MULTILINETYPE   5
-#define        MULTIPOLYGONTYPE        6
-#define        COLLECTIONTYPE  7
-
-#define TYPE_SETTYPE(c,t) (((c)&0xF0)|t)
-#define TYPE_SETDIMS(c,d) (((c)&0xCF)|d)
-#define TYPE_SETHASBBOX(c,b) (((c)&0x7F)|b)
-#define TYPE_SETHASSRID(c,s) (((c)&0xBF)|s)
-
-extern bool lwgeom_hasSRID(unsigned char type); // true iff S bit is set
-extern bool lwgeom_hasBBOX(unsigned char type); // true iff B bit set
-extern int  lwgeom_ndims(unsigned char type);   // returns the DD value
-extern int  lwgeom_getType(unsigned char type); // returns the tttt value
-
-extern unsigned char lwgeom_makeType(int ndims, char hasSRID, int type);
-extern unsigned char lwgeom_makeType_full(int ndims, char hasSRID, int type, bool hasBBOX);
-
-
-
-/*
- * This is the binary representation of lwgeom compatible
- * with postgresql varlena struct
- */
-typedef struct {
-       int32 size;
-       unsigned char type; // encodes ndims, type, bbox presence,
-                           // srid presence
-       char data[1];
-} PG_LWGEOM;
-
-/*
- * Construct a full LWGEOM type (including size header)
- * from a serialized form.
- * The constructed LWGEOM object will be allocated using palloc
- * and the serialized form will be copied.
- * If you specify a SRID other then -1 it will be set.
- * If you request bbox (wantbbox=1) it will be extracted or computed
- * from the serialized form.
- */
-extern PG_LWGEOM *PG_LWGEOM_construct(char *serialized, int SRID, int wantbbox);
-
-/*
- * Use this macro to extract the char * required
- * by most functions from an PG_LWGEOM struct.
- * (which is an PG_LWGEOM w/out int32 size casted to char *)
- */
-#define SERIALIZED_FORM(x) ((char *)(x))+4
-
-
-/*
- * This function computes the size in bytes
- * of the serialized geometries.
- */
-extern int lwgeom_size(const char *serialized_form);
-extern int lwgeom_size_subgeom(const char *serialized_form, int geom_number);
-
-
-//--------------------------------------------------------
-// all the base types (point/line/polygon) will have a
-// basic constructor, basic de-serializer, basic serializer,
-// bounding box finder and (TODO) serialized form size finder.
-//--------------------------------------------------------
-
-typedef struct
-{
-       char ndims;     // 2=2d, 3=3d, 4=4d, 5=undef
-       int SRID;       // spatial ref sys
-       POINTARRAY *point;  // hide 2d/3d (this will be an array of 1 point)
-}  LWPOINT; // "light-weight point"
-
-// construct a new point.  point will NOT be copied
-// use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
-extern LWPOINT  *lwpoint_construct(int ndims, int SRID, POINTARRAY *point);
-
-// given the LWPOINT serialized form (or a pointer into a muli* one)
-// construct a proper LWPOINT.
-// serialized_form should point to the 8bit type format (with type = 1)
-// Returns NULL if serialized form is not a point.
-// See serialized form doc
-extern LWPOINT *lwpoint_deserialize(char *serialized_form);
-
-// Find size this point would get when serialized (no BBOX)
-extern uint32 lwpoint_size(LWPOINT *point);
-
-// convert this point into its serialize form
-// result's first char will be the 8bit type.  See serialized form doc
-extern char  *lwpoint_serialize(LWPOINT *point);
-
-// same as above, writes to buf
-extern void lwpoint_serialize_buf(LWPOINT *point, char *buf, int *size);
-
-// find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
-extern BOX3D *lwpoint_findbbox(LWPOINT *point);
-
-// convenience functions to hide the POINTARRAY
-extern POINT2D lwpoint_getPoint2d(const LWPOINT *point);
-extern POINT3D lwpoint_getPoint3d(const LWPOINT *point);
-
-//--------------------------------------------------------
-
-typedef struct
-{
-       char  ndims; // 2=2d, 3=3d, 4=4d, 5=undef
-       int  SRID;   // spatial ref sys -1=none
-       POINTARRAY    *points; // array of POINT3D
-} LWLINE; //"light-weight line"
-
-// construct a new LWLINE.  points will *NOT* be copied
-// use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
-extern LWLINE *lwline_construct(int ndims, int SRID, POINTARRAY *points);
-
-// given the LWGEOM serialized form (or a pointer into a muli* one)
-// construct a proper LWLINE.
-// serialized_form should point to the 8bit type format (with type = 2)
-// See serialized form doc
-extern LWLINE *lwline_deserialize(char *serialized_form);
-
-// find the size this line would get when serialized (no BBOX)
-extern uint32 lwline_size(LWLINE *line);
-
-// convert this line into its serialize form
-// result's first char will be the 8bit type.  See serialized form doc
-// copies data.
-extern char  *lwline_serialize(LWLINE *line);
-
-// same as above, writes to buf
-extern void lwline_serialize_buf(LWLINE *line, char *buf, int *size);
-
-// find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
-extern BOX3D *lwline_findbbox(LWLINE *line);
-
-//--------------------------------------------------------
-
-typedef struct
-{
-       int32 SRID;
-       char ndims;
-       int  nrings;
-       POINTARRAY **rings; // list of rings (list of points)
-} LWPOLY; // "light-weight polygon"
-
-// construct a new LWPOLY.  arrays (points/points per ring) will NOT be copied
-// use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
-extern LWPOLY *lwpoly_construct(int ndims, int SRID, int nrings,POINTARRAY **points);
-
-// given the LWPOLY serialized form (or a pointer into a muli* one)
-// construct a proper LWPOLY.
-// serialized_form should point to the 8bit type format (with type = 3)
-// See serialized form doc
-extern LWPOLY *lwpoly_deserialize(char *serialized_form);
-
-// find the size this polygon would get when serialized (no bbox!)
-extern uint32 lwpoly_size(LWPOLY *poly);
-
-// create the serialized form of the polygon
-// result's first char will be the 8bit type.  See serialized form doc
-// points copied
-extern char *lwpoly_serialize(LWPOLY *poly);
-
-// same as above, writes to buf
-extern void lwpoly_serialize_buf(LWPOLY *poly, char *buf, int *size);
-
-// find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
-extern BOX3D *lwpoly_findbbox(LWPOLY *poly);
-
-//--------------------------------------------------------
-
-// MULTIPOINTTYPE
-typedef struct
-{
-       int32 SRID;
-       char ndims;
-       int  npoints;
-       LWPOINT **points;
-} LWMPOINT; 
-
-// MULTILINETYPE
-typedef struct
-{
-       int32 SRID;
-       char ndims;
-       int  nlines;
-       LWLINE **lines;
-} LWMLINE; 
-
-// MULTIPOLYGONTYPE
-typedef struct
-{
-       int32 SRID;
-       char ndims;
-       int  npolys;
-       LWPOLY **polys;
-} LWMPOLY; 
-
-// COLLECTIONTYPE
-typedef struct
-{
-       int32 SRID;
-       char ndims;
-       int  ngeoms;
-       struct LWGEOM **geoms;
-} LWCOLLECTION; 
-
-// LWGEOM (any type)
-typedef struct
-{
-       char type;
-       union {
-               LWPOINT *point;
-               LWMPOINT *mpoint;
-               LWLINE *line;
-               LWMLINE *mline;
-               LWPOLY *poly;
-               LWMPOLY *mpoly;
-               LWCOLLECTION *collection;
-       };
-} LWGEOM;
-
-LWGEOM *lwgeom_deserialize(char *serializedform);
-LWMPOINT *lwmpoint_deserialize(char *serializedform);
-
-//------------------------------------------------------
-
-//------------------------------------------------------
-// Multi-geometries
-//
-// These are all handled equivelently so its easy to write iterator code.
-//  NOTE NOTE: you can hand in a non-multigeometry to most of these functions
-//             and get usual behavior (ie. get geometry 0 on a POINT
-//            will return the point).
-//             This makes coding even easier since you dont have to necessarily
-//             differenciate between the multi* and non-multi geometries.
-//
-// NOTE: these usually work directly off the serialized form, so
-//     they're a little more difficult to handle (and slower)
-// NOTE NOTE: the get functions maybe slow, so we may want to have an "analysed"
-//            lwgeom that would just have pointer to the start of each sub-geometry.
-//------------------------------------------------------
-
-
-
-// use this version for speed.  READ-ONLY!
-typedef struct
-{
-       int   SRID;
-       const char  *serialized_form; // orginal structure
-       unsigned char  type;            // 8-bit type for the LWGEOM
-       int ngeometries;        // number of sub-geometries
-       char * * const sub_geoms;  // list of pointers (into serialized_form) of the sub-geoms
-} LWGEOM_INSPECTED;
-
-extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number);
-
-/*
- * This structure is intended to be used for geometry collection construction.
- * Does not allow specification of collection structure
- * (serialization chooses the simpler form)
- */
-typedef struct
-{
-       int SRID;
-       int ndims;
-       uint32 npoints;
-       char **points;
-       uint32 nlines;
-       char **lines;
-       uint32 npolys;
-       char **polys;
-} LWGEOM_EXPLODED;
-
-void pfree_exploded(LWGEOM_EXPLODED *exploded);
-
-// Returns a 'palloced' union of the two input exploded geoms.
-// Returns NULL if SRID or ndims do not match.
-LWGEOM_EXPLODED * lwexploded_sum(LWGEOM_EXPLODED *exp1, LWGEOM_EXPLODED *exp2);
-
-/*
- * This function recursively scan the given serialized geometry
- * and returns a list of _all_ subgeoms in it (deep-first)
- */
-extern LWGEOM_EXPLODED *lwgeom_explode(char *serialized);
-
-/*
- * Return the length of the serialized form corresponding
- * to this exploded structure.
- */
-extern uint32 lwexploded_findlength(LWGEOM_EXPLODED *exp, int wantbbox);
-
-// Serialize an LWGEOM_EXPLODED object.
-// SRID and ndims will be taken from exploded structure.
-// wantbbox will determine result bbox.
-extern char *lwexploded_serialize(LWGEOM_EXPLODED *exploded, int wantbbox);
-
-// Same as lwexploded_serialize but writing to pre-allocated space
-extern void lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox, char *buf, int *retsize);
-
-// note - for a simple type (ie. point), this will have sub_geom[0] = serialized_form.
-// for multi-geomtries sub_geom[0] will be a few bytes into the serialized form
-// This function just computes the length of each sub-object and pre-caches this info.
-// For a geometry collection of multi* geometries, you can inspect the sub-components
-// as well.
-extern LWGEOM_INSPECTED *lwgeom_inspect(const char *serialized_form);
-
-
-// 1st geometry has geom_number = 0
-// if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
-// if there arent enough geometries, return null.
-// this is fine to call on a point (with geom_num=0), multipoint or geometrycollection
-extern LWPOINT *lwgeom_getpoint(char *serialized_form, int geom_number);
-extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-// 1st geometry has geom_number = 0
-// if the actual geometry isnt a LINE, null is returned (see _gettype()).
-// if there arent enough geometries, return null.
-// this is fine to call on a line, multiline or geometrycollection
-extern LWLINE *lwgeom_getline(char *serialized_form, int geom_number);
-extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-// 1st geometry has geom_number = 0
-// if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
-// if there arent enough geometries, return null.
-// this is fine to call on a polygon, multipolygon or geometrycollection
-extern LWPOLY *lwgeom_getpoly(char *serialized_form, int geom_number);
-extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-// this gets the serialized form of a sub-geometry
-// 1st geometry has geom_number = 0
-// if this isnt a multi* geometry, and geom_number ==0 then it returns
-// itself
-// returns null on problems.
-// in the future this is how you would access a muli* portion of a
-// geometry collection.
-//    GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
-//   ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
-//           --> POINT(1 1)
-// you can inspect the sub-geometry as well if you wish.
-extern char *lwgeom_getsubgeometry(const char *serialized_form, int geom_number);
-extern char *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-
-// 1st geometry has geom_number = 0
-//  use geom_number = -1 to find the actual type of the serialized form.
-//    ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
-//                 --> multipoint
-//   ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
-//                 --> point
-// gets the 8bit type of the geometry at location geom_number
-extern char lwgeom_getsubtype(char *serialized_form, int geom_number);
-extern char lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-
-// how many sub-geometries are there?
-//  for point,line,polygon will return 1.
-extern int lwgeom_getnumgeometries(char *serialized_form);
-extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected);
-
-
-
-// set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
-//   (ie. give it 2 points and ask it to be a multipoint)
-//  use SRID=-1 for unknown SRID  (will have 8bit type's S = 0)
-// all subgeometries must have the same SRID
-// if you want to construct an inspected, call this then inspect the result...
-extern char *lwgeom_construct(int SRID,int finalType,int ndims, int nsubgeometries, char **serialized_subs);
-
-
-// construct the empty geometry (GEOMETRYCOLLECTION(EMPTY))
-extern char *lwgeom_constructempty(int SRID,int ndims);
-extern void lwgeom_constructempty_buf(int SRID, int ndims, char *buf, int *size);
-int lwgeom_empty_length(int SRID);
-
-// get the SRID from the LWGEOM
-// none present => -1
-extern int lwgeom_getSRID(PG_LWGEOM *lwgeom);
-extern int lwgeom_getsrid(char *serialized);
-extern PG_LWGEOM *lwgeom_setSRID(PG_LWGEOM *lwgeom, int32 newSRID);
-
-//get bounding box of LWGEOM (automatically calls the sub-geometries bbox generators)
-extern BOX3D *lw_geom_getBB(char *serialized_form);
-extern BOX3D *lw_geom_getBB_inspected(LWGEOM_INSPECTED *inspected);
-
-
-//------------------------------------------------------
-// other stuff
-
-// handle the double-to-float conversion.  The results of this
-// will usually be a slightly bigger box because of the difference
-// between float8 and float4 representations.
-
-extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box);
-extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res);
-extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box);
-extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d);
-
-extern BOX2DFLOAT4 *box_to_box2df(BOX *box);  // postgresql standard type
-extern BOX box2df_to_box(BOX2DFLOAT4 *box);  // postgresql standard type
-extern void box2df_to_box_p(BOX2DFLOAT4 *box, BOX *out); // postgresql standard type
-
-extern BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2);
-
-
-// returns a real entity so it doesnt leak
-// if this has a pre-built BOX2d, then we use it,
-// otherwise we need to compute it.
-// WARNING! the EMPTY geom will result in a random BOX2D returned
-extern BOX2DFLOAT4 getbox2d(char *serialized_form);
-
-// this function writes to 'box' and returns 0 if serialized_form
-// does not have a bounding box (empty geom)
-extern int getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box);
-
-// this function returns a pointer to the 'internal' bounding
-// box of a serialized-form geometry. If the geometry does
-// not have an embedded bounding box the function returns NULL.
-// READ-ONLY!
-extern const BOX2DFLOAT4 * getbox2d_internal(char *serialized_form);
-
-// Expand given box of 'd' units in all directions 
-void expand_box2d(BOX2DFLOAT4 *box, double d);
-void expand_box3d(BOX3D *box, double d);
-
-//****************************************************************
-// memory management -- these only delete the memory associated
-//  directly with the structure - NOT the stuff pointing into
-//  the original de-serialized info
-
-extern void pfree_inspected(LWGEOM_INSPECTED *inspected);
-extern void pfree_point    (LWPOINT *pt);
-extern void pfree_line     (LWLINE  *line);
-extern void pfree_polygon  (LWPOLY  *poly);
-extern void pfree_POINTARRAY(POINTARRAY *pa);
-
-
-//***********************************************************
-// utility
-
-extern uint32 get_uint32(const char *loc);
-extern int32 get_int32(const char *loc);
-extern void printPA(POINTARRAY *pa);
-extern void printLWPOINT(LWPOINT *point);
-extern void printLWLINE(LWLINE *line);
-extern void printLWPOLY(LWPOLY *poly);
-extern void printBYTES(unsigned char *a, int n);
-extern void printMULTI(char *serialized);
-extern void deparse_hex(unsigned char str, unsigned char *result);
-extern void printType(unsigned char str);
-
-
-//------------------------------------------------------------
-//------------------------------------------------------------
-// On serialized form  (see top for the 8bit type implementation)
-
-// NOTE: contrary to the original proposal, bounding boxes are *never*
-//       included in the geometry.  You must either refer to the index
-//       or compute it on demand.
-
-
-// The serialized form is always a stream of bytes.  The first four are always
-// the memory size of the LWGEOM (including the 4 byte memory size).
-
-// The easiest way to describe the serialed form is with examples:
-// (more examples are available in the postgis mailing list)
-
-//3D point w/o bounding box::
-//<int32> size = 29 bytes
-//<char> type:  S=0,D=1, tttt= 1
-//<double> X
-//<double> Y
-//<double> Z
-
-//2D line String
-//<int32> size = ...
-//<char> type:  S=0,D=0, tttt= 2
-//<uint32> npoints
-//<double> X0
-//<double> Y0
-//<double> X1
-//<double> Y1
-//<double> X2
-//<double> Y2
-//...
-
-//3D polygon w/o bounding box
-//<int32> size = ...
-//<char> type:  S=0,D=0, tttt= 3
-//<uint32> nrings
-//<uint32> npoints in ring0
-//<double> X0
-//<double> Y0
-//<double> X1
-//<double> Y1
-//<double> X2
-//<double> Y2
-//...
-//<uint32> npoints in ring1
-//<double> X0
-//<double> Y0
-//<double> X1
-//<double> Y1
-//<double> X2
-//<double> Y2
-//...
-//...
-
-
-// the multi* representations are very simple
-
-//<int32> size = ...
-//<char> type:  ... with  tttt= <multi* or geometrycollection>
-//<int32> ngeometries
-// <geometry zero, serialized form>
-// <geometry one, serialized form>
-// <geometry two, serialzied form>
-// ...
-
-
-
-// see implementation for more exact details.
-
-
-//----------------------------------------------------------------
-// example function (computes total length of the lines in a LWGEOM).
-//   This works for a LINESTRING, MULTILINESTRING, OR GEOMETRYCOLLECTION
-
-
-
-//       char *serialized_form = (char *)  [[get from database]]
-//
-//    double total_length_so_far = 0;
-//    for (int t=0;t< lwgeom_getnumgeometries(serialized_form) ; t++)
-//    {
-//         LWLINE *line = lwgeom_getline(serialized_form, t);
-//         if (line != NULL)
-//                {
-//                     double length = findlength( POINT_ARRAY(line->points) ); //2d/3d aware
-//                 total_length_so_far + = length;
-//         }
-//    }
-//    return total_length_so_far;
-
-
-// using the LWGEOM_INSPECTED way:
-
-
-//       char *serialized_form = (char *)  [[get from datbase]]
-//    LWGEOM_INSPECTED inspected_geom = lwgeom_inspect(serialized_form);
-//
-//    double total_length_so_far = 0;
-//    for (int t=0;t< lwgeom_getnumgeometries(inspected_geom) ; t++)
-//    {
-//         LWLINE *line = lwgeom_getline(inspected_geom, t);
-//         if (line != NULL)
-//                {
-//                      double length = findlength( POINT_ARRAY(line->points) ); //2d/3d aware
-//                 total_length_so_far + = length;
-//         }
-//    }
-//    return total_length_so_far;
-
-
-// the findlength() function could be written like based on functions like:
-//
-//   POINT3D getPoint3d(POINTARRAY pa, int n);  (for a 2d/3d point and 3d length)
-//   POINT2D getPoint2d(POINTARRAY pa, int n);  (for a 2d/3d point and 2d length)
-// NOTE: make sure your findlength() function knows what to do with z=NaN.
-
-
-
-
-// other forwards (for indirect function calls)
-
-extern float LWGEOM_Minf(float a, float b);
-extern float LWGEOM_Maxf(float a, float b);
-extern double LWGEOM_Mind(double a, double b);
-extern double LWGEOM_Maxd(double a, double b);
-
-
-
-extern BOX3D *lw_geom_getBB_simple(char *serialized_form);
-
-extern float  nextDown_f(double d);
-extern float  nextUp_f(double d);
-extern double nextDown_d(float d);
-extern double nextUp_d(float d);
-
-
-
-#if ! defined(__MINGW32__)
-#define max(a,b)               ((a) >  (b) ? (a) : (b))
-#define min(a,b)               ((a) <= (b) ? (a) : (b))
-#endif
-#define abs(a)                 ((a) <  (0) ? (-a) : (a))
-
-
-// general utilities 
-extern double lwgeom_polygon_area(LWPOLY *poly);
-extern double lwgeom_polygon_perimeter(LWPOLY *poly);
-extern double lwgeom_polygon_perimeter2d(LWPOLY *poly);
-extern double lwgeom_pointarray_length2d(POINTARRAY *pts);
-extern double lwgeom_pointarray_length(POINTARRAY *pts);
-extern void lwgeom_force2d_recursive(char *serialized, char *optr, int *retsize);
-extern void lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize);
-extern void lwgeom_force4d_recursive(char *serialized, char *optr, int *retsize);
-extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
-extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
-extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
-extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
-extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
-extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
-extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
-extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
-extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
-extern double distance2d_point_line(LWPOINT *point, LWLINE *line);
-extern double distance2d_line_line(LWLINE *line1, LWLINE *line2);
-extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
-extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
-extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
-extern double lwgeom_mindistance2d_recursive(char *lw1, char *lw2);
-extern void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff);
-extern void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
-extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
-extern POINTARRAY *segmentize2d_ptarray(POINTARRAY *ipa, double dist);
-extern int32 lwgeom_npoints(char *serialized);
-extern bool ptarray_isccw(const POINTARRAY *pa);
+extern void lwgeom_reverse(LWGEOM *lwgeom);
+extern void lwgeom_forceRHR(LWGEOM *lwgeom);
index 887d42e42f3e940b79493449bdb004c3ccb9377e..fa159481e9fcdfadb823ea9bf7e6a95317e674f3 100644 (file)
@@ -939,8 +939,8 @@ lwgeom_inspect(const char *serialized_form)
                //simple geometry (point/line/polygon)-- not multi!
                result->ngeometries = 1;
                sub_geoms = (char**) lwalloc(sizeof(char*));
-               sub_geoms[0] = serialized_form;
-               result->sub_geoms = sub_geoms;
+               sub_geoms[0] = (char *)serialized_form;
+               result->sub_geoms = (char **)sub_geoms;
                return result;
        }
 
@@ -963,7 +963,7 @@ lwgeom_inspect(const char *serialized_form)
 
        sub_geoms = (char**) lwalloc(sizeof(char*) * result->ngeometries );
        result->sub_geoms = sub_geoms;
-       sub_geoms[0] = loc;
+       sub_geoms[0] = (char *)loc;
 #ifdef DEBUG
        lwnotice("subgeom[0] @ %p", sub_geoms[0]);
 #endif
index 6de34d9565963c893af4280dfba1b185d6144711..a717b7eaca1735cbbea37be4c074f6d2c2a5ce98 100644 (file)
@@ -53,10 +53,8 @@ char * lwgeom_summary_recursive(char *serialized, int offset);
 char * lwgeom_summary(LWGEOM *serialized, int offset);
 int32 lwgeom_nrings_recursive(char *serialized);
 void dump_lwexploded(LWGEOM_EXPLODED *exploded);
-POINTARRAY *ptarray_reverse(const POINTARRAY *pa);
-LWLINE *lwline_reverse(const LWLINE *line);
-LWPOLY *lwpoly_reverse(const LWPOLY *poly);
-LWPOLY *lwpoly_forceRHR(const LWPOLY *poly);
+void ptarray_reverse(POINTARRAY *pa);
+
 
 /*------------------------------------------------------------------*/
 
@@ -759,88 +757,59 @@ lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad)
 
 }
 
-POINTARRAY *
-ptarray_reverse(const POINTARRAY *ipa)
+void
+ptarray_reverse(POINTARRAY *pa)
 {
-       POINTARRAY *opa;
-       uint32 i, j;
-       int ptsize;
-
-       opa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY));
-       opa->ndims = ipa->ndims;
-       opa->npoints = ipa->npoints;
-       ptsize = pointArray_ptsize(ipa);
-       opa->serialized_pointlist = lwalloc(ipa->npoints*ptsize);
+       POINT4D pbuf;
+       uint32 i;
+       int ptsize = pointArray_ptsize(pa);
+       int last = pa->npoints-1;
+       int mid = last/2;
 
-       for (i=0, j=ipa->npoints-1; i<ipa->npoints; i++, j--)
+       for (i=0; i<=mid; i++)
        {
-               memcpy(getPoint(opa, j), getPoint(ipa, i), ptsize);
+               char *from, *to;
+               from = getPoint(pa, i);
+               to = getPoint(pa, (last-i));
+               memcpy((char *)&pbuf, to, ptsize);
+               memcpy(to, from, ptsize);
+               memcpy(from, (char *)&pbuf, ptsize);
        }
 
-       return opa;
 }
 
-LWLINE *
-lwline_reverse(const LWLINE *iline)
+void
+lwline_reverse(LWLINE *line)
 {
-       LWLINE *oline;
-       POINTARRAY *rpa = ptarray_reverse(iline->points);
-
-       oline = lwline_construct(iline->ndims, iline->SRID, rpa);
-       return oline;
+       ptarray_reverse(line->points);
 }
 
-LWPOLY *
-lwpoly_reverse(const LWPOLY *ipoly)
+void
+lwpoly_reverse(LWPOLY *poly)
 {
-       LWPOLY *opoly;
-       POINTARRAY **rpa;
        int i;
 
-       rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings);
-
-       for (i=0; i<ipoly->nrings; i++)
-       {
-               rpa[i] = ptarray_reverse(ipoly->rings[i]);
-       }
-
-       opoly = lwpoly_construct(ipoly->ndims, ipoly->SRID,
-               ipoly->nrings, rpa);
-
-       return opoly;
+       for (i=0; i<poly->nrings; i++)
+               ptarray_reverse(poly->rings[i]);
 }
 
-LWPOLY *
-lwpoly_forceRHR(const LWPOLY *ipoly)
+void
+lwpoly_forceRHR(LWPOLY *poly)
 {
-       LWPOLY *opoly;
-       POINTARRAY **rpa;
        int i;
-       POINTARRAY *opa;
 
-       rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings);
-
-       if ( ptarray_isccw(ipoly->rings[0]) )
+       if ( ptarray_isccw(poly->rings[0]) )
        {
-               opa = ipoly->rings[0];
-               rpa[0] = ptarray_reverse(ipoly->rings[0]);
+               ptarray_reverse(poly->rings[0]);
        }
-       else rpa[0] = ipoly->rings[0];
 
-       for (i=1; i<ipoly->nrings; i++)
+       for (i=1; i<poly->nrings; i++)
        {
-               if ( ! ptarray_isccw(ipoly->rings[i]) )
+               if ( ! ptarray_isccw(poly->rings[i]) )
                {
-                       opa = ipoly->rings[i];
-                       rpa[i] = ptarray_reverse(ipoly->rings[i]);
+                       ptarray_reverse(poly->rings[i]);
                }
-               else rpa[i] = ipoly->rings[i];
        }
-
-       opoly = lwpoly_construct(ipoly->ndims, ipoly->SRID,
-               ipoly->nrings, rpa);
-
-       return opoly;
 }
 
 /*------------------------------------------------------------------*/
@@ -917,16 +886,16 @@ lwmpoint_summary(LWMPOINT *mpoint, int offset)
 {
        char *result = lwalloc(60);
        sprintf(result, "Object %d is a MULTIPOINT() with %d points\n",
-               offset, mpoint->npoints);
+               offset, mpoint->ngeoms);
        return result;
 }
 
 char *
 lwmline_summary(LWMLINE *mline, int offset)
 {
-       char *result = lwalloc(60*(mline->nlines+1));
+       char *result = lwalloc(60*(mline->ngeoms+1));
        sprintf(result, "Object %d is a MULTILINE() with %d lines\n",
-               offset, mline->nlines);
+               offset, mline->ngeoms);
        return result;
 }
 
@@ -939,11 +908,11 @@ lwmpoly_summary(LWMPOLY *mpoly, int offset)
        int i;
 
        sprintf(result, "Object %d is a MULTIPOLYGON() with %d polys\n",
-               offset, mpoly->npolys);
+               offset, mpoly->ngeoms);
 
-       for (i=0; i<mpoly->npolys; i++)
+       for (i=0; i<mpoly->ngeoms; i++)
        {
-               tmp = lwpoly_summary(mpoly->polys[i], i);
+               tmp = lwpoly_summary(mpoly->geoms[i], i);
                size += strlen(tmp)+1;
                result = lwrealloc(result, size);
                strcat(result, tmp);
@@ -2977,51 +2946,14 @@ PG_FUNCTION_INFO_V1(LWGEOM_reverse);
 Datum LWGEOM_reverse(PG_FUNCTION_ARGS)
 {
        PG_LWGEOM *geom;
-       PG_LWGEOM *result = NULL;
-       LWGEOM_EXPLODED *exp;
-       int size;
-       int wantbbox;
-       int i;
-
-       geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-
-       if ( lwgeom_getType(geom->type) == COLLECTIONTYPE )
-       {
-               elog(ERROR, "Collection reversing is not supported");
-               PG_RETURN_NULL();
-       }
-
-       wantbbox = lwgeom_hasBBOX(geom->type);
-       exp = lwgeom_explode(SERIALIZED_FORM(geom));
-
-       for (i=0; i<exp->nlines; i++)
-       {
-               LWLINE *line = lwline_deserialize(exp->lines[i]);
-               LWLINE *rline = lwline_reverse(line);
-               pfree_line(line);
-               exp->lines[i] = lwline_serialize(rline);
-       }
+       LWGEOM *lwgeom;
 
-       for (i=0; i<exp->npolys; i++)
-       {
-               LWPOLY *poly = lwpoly_deserialize(exp->polys[i]);
-               LWPOLY *rpoly = lwpoly_reverse(poly);
-               pfree_polygon(poly);
-               exp->polys[i] = lwpoly_serialize(rpoly);
-       }
+       geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
 
-       size = lwexploded_findlength(exp, wantbbox);
-       result = lwalloc(size+4);
-       result->size = (size+4);
-       lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size);
-       
-       if ( result->size != (size+4) )
-       {
-               elog(ERROR, "lwexploded_serialize_buf wrote %d bytes, lwexploded_findlength returned %d", size, result->size-4);
-               PG_RETURN_NULL();
-       }
+       lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
+       lwgeom_reverse(lwgeom);
 
-       PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(geom);
 }
 
 // Force polygons of the collection to obey Right-Hand-Rule
@@ -3029,41 +2961,12 @@ PG_FUNCTION_INFO_V1(LWGEOM_forceRHR_poly);
 Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS)
 {
        PG_LWGEOM *geom;
-       PG_LWGEOM *result = NULL;
-       LWGEOM_EXPLODED *exp;
-       int size;
-       int wantbbox;
-       int i;
-
-       geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-
-       if ( lwgeom_getType(geom->type) != POLYGONTYPE &&
-               lwgeom_getType(geom->type) != MULTIPOLYGONTYPE )
-       {
-               elog(ERROR, "Only polygon|multipolygon supported");
-               PG_RETURN_NULL();
-       }
-
-       wantbbox = lwgeom_hasBBOX(geom->type);
-       exp = lwgeom_explode(SERIALIZED_FORM(geom));
+       LWGEOM *lwgeom;
 
-       for (i=0; i<exp->npolys; i++)
-       {
-               LWPOLY *poly = lwpoly_deserialize(exp->polys[i]);
-               LWPOLY *rpoly = lwpoly_reverse(poly);
-               exp->polys[i] = lwpoly_serialize(rpoly);
-       }
+       geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
 
-       size = lwexploded_findlength(exp, wantbbox);
-       result = lwalloc(size+4);
-       result->size = (size+4);
-       lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size);
-       
-       if ( result->size != (size+4) )
-       {
-               elog(ERROR, "lwexploded_serialize_buf wrote %d bytes, lwexploded_findlength returned %d", size, result->size-4);
-               PG_RETURN_NULL();
-       }
+       lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
+       lwgeom_forceRHR(lwgeom);
 
-       PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(geom);
 }
index 45641efbd4ad07fe8d25a066d14461a38da2b3ef..2b69faba26e01055aa48070a69b3639c18dc0f7a 100644 (file)
@@ -24,16 +24,16 @@ lwmline_deserialize(char *srl)
        result->type = MULTILINETYPE;
        result->SRID = insp->SRID;
        result->ndims = lwgeom_ndims(insp->type);
-       result->nlines = insp->ngeometries;
-       result->lines = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
+       result->ngeoms = insp->ngeometries;
+       result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
 
        for (i=0; i<insp->ngeometries; i++)
        {
-               result->lines[i] = lwline_deserialize(insp->sub_geoms[i]);
-               if ( result->lines[i]->ndims != result->ndims )
+               result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]);
+               if ( result->geoms[i]->ndims != result->ndims )
                {
                        lwerror("Mixed dimensions (multiline:%d, line%d:%d)",
-                               result->ndims, i, result->lines[i]->ndims);
+                               result->ndims, i, result->geoms[i]->ndims);
                        return NULL;
                }
        }
@@ -50,8 +50,8 @@ lwmline_serialize_size(LWMLINE *mline)
 
        if ( mline->SRID != -1 ) size += 4; // SRID
 
-       for (i=0; i<mline->nlines; i++)
-               size += lwline_serialize_size(mline->lines[i]);
+       for (i=0; i<mline->ngeoms; i++)
+               size += lwline_serialize_size(mline->geoms[i]);
 
        return size; 
 }
@@ -83,14 +83,14 @@ lwmline_serialize_buf(LWMLINE *mline, char *buf, int *retsize)
        }
 
        // Write number of subgeoms
-       memcpy(loc, &mline->nlines, 4);
+       memcpy(loc, &mline->ngeoms, 4);
        size += 4;
        loc += 4;
 
        // Serialize subgeoms
-       for (i=0; i<mline->nlines; i++)
+       for (i=0; i<mline->ngeoms; i++)
        {
-               lwline_serialize_buf(mline->lines[i], loc, &subsize);
+               lwline_serialize_buf(mline->geoms[i], loc, &subsize);
                size += subsize;
        }
 
index e02edd947649e7402021a086847a9a5da59f0306..98054666337a3b07e1959ba5dc00a47cb69eb5b4 100644 (file)
@@ -24,16 +24,16 @@ lwmpoint_deserialize(char *srl)
        result->type = MULTIPOINTTYPE;
        result->SRID = insp->SRID;
        result->ndims = lwgeom_ndims(insp->type);
-       result->npoints = insp->ngeometries;
-       result->points = lwalloc(sizeof(LWPOINT *)*result->npoints);
+       result->ngeoms = insp->ngeometries;
+       result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms);
 
        for (i=0; i<insp->ngeometries; i++)
        {
-               result->points[i] = lwpoint_deserialize(insp->sub_geoms[i]);
-               if ( result->points[i]->ndims != result->ndims )
+               result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]);
+               if ( result->geoms[i]->ndims != result->ndims )
                {
                        lwerror("Mixed dimensions (multipoint:%d, point%d:%d)",
-                               result->ndims, i, result->points[i]->ndims);
+                               result->ndims, i, result->geoms[i]->ndims);
                        return NULL;
                }
        }
@@ -50,8 +50,8 @@ lwmpoint_serialize_size(LWMPOINT *mpoint)
 
        if ( mpoint->SRID != -1 ) size += 4; // SRID
 
-       for (i=0; i<mpoint->npoints; i++)
-               size += lwpoint_serialize_size(mpoint->points[i]);
+       for (i=0; i<mpoint->ngeoms; i++)
+               size += lwpoint_serialize_size(mpoint->geoms[i]);
 
        return size; 
 }
@@ -83,14 +83,14 @@ lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *retsize)
        }
 
        // Write number of subgeoms
-       memcpy(loc, &mpoint->npoints, 4);
+       memcpy(loc, &mpoint->ngeoms, 4);
        size += 4;
        loc += 4;
 
        // Serialize subgeoms
-       for (i=0; i<mpoint->npoints; i++)
+       for (i=0; i<mpoint->ngeoms; i++)
        {
-               lwpoint_serialize_buf(mpoint->points[i], loc, &subsize);
+               lwpoint_serialize_buf(mpoint->geoms[i], loc, &subsize);
                size += subsize;
        }
 
index 92b9fc46e41205c91719d27777f03ffa819655bb..dba76d135f9718cbca14226f02afaafafa120cd8 100644 (file)
@@ -3,6 +3,8 @@
 #include <string.h>
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
 LWMPOLY *
 lwmpoly_deserialize(char *srl)
 {
@@ -11,6 +13,10 @@ lwmpoly_deserialize(char *srl)
        int type = lwgeom_getType(srl[0]);
        int i;
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwmpoly_deserialize called");
+#endif
+
        if ( type != MULTIPOLYGONTYPE ) 
        {
                lwerror("lwmpoly_deserialize called on NON multipoly: %d",
@@ -21,20 +27,19 @@ lwmpoly_deserialize(char *srl)
        insp = lwgeom_inspect(srl);
 
        result = lwalloc(sizeof(LWMPOLY));
-       result->type = srl[0];
        result->type = MULTIPOLYGONTYPE;
        result->SRID = insp->SRID;
        result->ndims = lwgeom_ndims(insp->type);
-       result->npolys = insp->ngeometries;
-       result->polys = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
+       result->ngeoms = insp->ngeometries;
+       result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
 
        for (i=0; i<insp->ngeometries; i++)
        {
-               result->polys[i] = lwpoly_deserialize(insp->sub_geoms[i]);
-               if ( result->polys[i]->ndims != result->ndims )
+               result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]);
+               if ( result->geoms[i]->ndims != result->ndims )
                {
                        lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)",
-                               result->ndims, i, result->polys[i]->ndims);
+                               result->ndims, i, result->geoms[i]->ndims);
                        return NULL;
                }
        }
@@ -51,8 +56,8 @@ lwmpoly_serialize_size(LWMPOLY *mpoly)
 
        if ( mpoly->SRID != -1 ) size += 4; // SRID
 
-       for (i=0; i<mpoly->npolys; i++)
-               size += lwpoly_serialize_size(mpoly->polys[i]);
+       for (i=0; i<mpoly->ngeoms; i++)
+               size += lwpoly_serialize_size(mpoly->geoms[i]);
 
        return size; 
 }
@@ -84,14 +89,14 @@ lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *retsize)
        }
 
        // Write number of subgeoms
-       memcpy(loc, &mpoly->npolys, 4);
+       memcpy(loc, &mpoly->ngeoms, 4);
        size += 4;
        loc += 4;
 
        // Serialize subgeoms
-       for (i=0; i<mpoly->npolys; i++)
+       for (i=0; i<mpoly->ngeoms; i++)
        {
-               lwpoly_serialize_buf(mpoly->polys[i], loc, &subsize);
+               lwpoly_serialize_buf(mpoly->geoms[i], loc, &subsize);
                size += subsize;
        }