]> granicus.if.org Git - postgis/commitdiff
Fixed a bug in getPoint{3dm,3dz,4d}_p() api calls automatically
authorSandro Santilli <strk@keybit.net>
Tue, 22 Nov 2005 21:26:39 +0000 (21:26 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 22 Nov 2005 21:26:39 +0000 (21:26 +0000)
fixing bugs in force_{3dm,3dz,4d}() user functions.
Wrapped paranoid checks in PARANOIA_LEVEL preprocessor blocks.
Updated release notes and CHANGES file.

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

CHANGES
doc/postgis.xml
lwgeom/liblwgeom.h
lwgeom/lwgeom_api.c
regress/regress.sql
regress/regress_expected

diff --git a/CHANGES b/CHANGES
index 4591cff73a72fb8f1fb5275f5206c264af6ed009..bec3919af1e49df2499a9cbf4ac0be8b94861532 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,7 @@ PostGIS 1.0.5CVS
        - Fixed a small bug in the getPoint4d_p() low-level function
        - Fixed memory alignment problems
        - Speedup of serializer functions
+       - Bug fix in force_4d, force_3dm and force_3dz functions
 
 PostGIS 1.0.4
 2005/09/09
index 1c7d8b3433fe01213da53599430ba446af127d2f..7375b52b995ed1ce2f33245f1cb7f51dd34c3a9a 100644 (file)
@@ -4873,6 +4873,7 @@ standards (return 0 on success).
        <para>Fixed computation of null values fraction in analyzer</para>
        <para>Fixed a small bug in the getPoint4d_p() low-level function</para>
        <para>Speedup of serializer functions</para>
+       <para>Fixed a bug in force_3dm(), force_3dz() and force_4d()</para>
                        </sect2>
 
                        <sect2>
index d5bfefabf9bc61e2f36f655021a8532b3ebc0c09..2632edcb9b63579e70696506d57b3401a99bfd54 100644 (file)
@@ -269,7 +269,7 @@ extern void lwgeom_dropSRID(LWGEOM *lwgeom);
 
 // 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
+// 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);
 
index 15c363e3d7078f24c7b60034f6a5a4412790ffea..e6fc8534da77e392a638013a8a869b118ff84fff 100644 (file)
@@ -7,6 +7,11 @@
 
 #include "liblwgeom.h"
 
+/*
+ * Lower this to reduce integrity checks
+ */
+#define PARANOIA_LEVEL 1
+
 //#define PGIS_DEBUG 1
 
 // This is an implementation of the functions defined in lwgeom.h
@@ -426,14 +431,16 @@ 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
+// will set point's z=NO_Z_VALUE  if pa is 2d
+// will set point's m=NO_M_VALUE  if pa is 3d or 2d
 // NOTE: this will modify the point4d pointed to by 'point'.
 int
-getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
+getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *op)
 {
-       int size;
+       uchar *ptr;
+       int zmflag;
 
+#if PARANOIA_LEVEL > 0
        if ( ! pa ) return 0;
 
        if ( (n<0) || (n>=pa->npoints))
@@ -441,11 +448,41 @@ getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
                lwerror("getPoint4d_p: point offset out of range");
                return 0; //error
        }
+#endif
+
+       /* Get a pointer to nth point offset and zmflag */
+       ptr=getPoint_internal(pa, n);
+       zmflag=TYPE_GETZM(pa->dims);
+
+       switch (zmflag)
+       {
+               case 0: // 2d 
+                       memcpy(op, ptr, sizeof(POINT2D));
+                       op->m=NO_M_VALUE;
+                       op->z=NO_Z_VALUE;
+                       break;
+
+               case 3: // ZM
+                       memcpy(op, ptr, sizeof(POINT4D));
+                       break;
+
+               case 2: // Z
+                       memcpy(op, ptr, sizeof(POINT3DZ));
+                       op->m=NO_M_VALUE;
+                       break;
+
+               case 1: // M
+                       memcpy(op, ptr, sizeof(POINT3DM));
+                       op->m=op->z; // we use Z as temporary storage
+                       op->z=NO_Z_VALUE;
+                       break;
+
+               default:
+                       lwerror("Unkown ZM flag ??");
+       }
 
-       memset(point, 0, sizeof(POINT4D));
-       size = pointArray_ptsize(pa);
-       memcpy(point, getPoint_internal(pa, n), size);
        return 1;
+
 }
 
 
@@ -478,64 +515,109 @@ getPoint3dm(const POINTARRAY *pa, int n)
 int
 getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *op)
 {
-       int size;
+       uchar *ptr;
 
+#if PARANOIA_LEVEL > 0
        if ( ! pa ) return 0;
 
+       if ( (n<0) || (n>=pa->npoints))
+       {
+               lwnotice("%d out of numpoint range (%d)", n, pa->npoints);
+               return 0; //error
+       }
+#endif
+
 #ifdef PGIS_DEBUG
        lwnotice("getPoint3dz_p called on array of %d-dimensions / %u pts",
                TYPE_NDIMS(pa->dims), pa->npoints);
 #endif
 
-       if ( (n<0) || (n>=pa->npoints))
+       /* Get a pointer to nth point offset */
+       ptr=getPoint_internal(pa, n);
+
+       /*
+        * if input POINTARRAY has the Z, it is always
+        * at third position so make a single copy
+        */
+       if ( TYPE_HASZ(pa->dims) )
        {
-               lwnotice("%d out of numpoint range (%d)", n, pa->npoints);
-               return 0; //error
+               memcpy(op, ptr, sizeof(POINT3DZ));
        }
 
-       /* initialize point */
-       memset(op, 0, sizeof(POINT3DZ));
+       /*
+        * Otherwise copy the 2d part and initialize
+        * Z to NO_Z_VALUE
+        */
+       else
+       {
+               memcpy(op, ptr, sizeof(POINT2D));
+               op->z=NO_Z_VALUE;
+       }
 
-       /* copy */
-       size = pointArray_ptsize(pa);
-#ifdef PGIS_DEBUG
-       lwnotice("getPoint3dz_p: point size: %d", size);
-#endif
-       memcpy(op, getPoint_internal(pa, n), size);
        return 1;
 
 }
 
 // copies a point from the point array into the parameter point
-// will set point's m=NO_Z_VALUE if pa has no M
+// will set point's m=NO_M_VALUE if pa has no M
 // NOTE: this will modify the point3dm pointed to by 'point'.
 int
 getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *op)
 {
-       int size;
+       uchar *ptr;
+       int zmflag;
 
+#if PARANOIA_LEVEL > 0
        if ( ! pa ) return 0;
 
+       if ( (n<0) || (n>=pa->npoints))
+       {
+               lwerror("%d out of numpoint range (%d)", n, pa->npoints);
+               return 0; //error
+       }
+#endif 
+
 #ifdef PGIS_DEBUG
        lwnotice("getPoint3dm_p(%d) called on array of %d-dimensions / %u pts",
                n, TYPE_NDIMS(pa->dims), pa->npoints);
 #endif
 
-       if ( (n<0) || (n>=pa->npoints))
+
+       /* Get a pointer to nth point offset and zmflag */
+       ptr=getPoint_internal(pa, n);
+       zmflag=TYPE_GETZM(pa->dims);
+
+       /*
+        * if input POINTARRAY has the M and NO Z,
+        * we can issue a single memcpy
+        */
+       if ( zmflag == 1 )
        {
-               lwerror("%d out of numpoint range (%d)", n, pa->npoints);
-               return 0; //error
+               memcpy(op, ptr, sizeof(POINT3DM));
+               return 1;
        }
 
-       /* initialize point */
-       memset(op, 0, sizeof(POINT3DM));
+       /*
+        * Otherwise copy the 2d part and 
+        * initialize M to NO_M_VALUE
+        */
+       memcpy(op, ptr, sizeof(POINT2D));
+
+       /*
+        * Then, if input has Z skip it and
+        * copy next double, otherwise initialize
+        * M to NO_M_VALUE
+        */
+       if ( zmflag == 3 )
+       {
+               ptr+=sizeof(POINT3DZ);
+               memcpy(&(op->m), ptr, sizeof(double));
+       }
+       else
+       {
+               op->m=NO_M_VALUE;
+       }
 
-       /* copy */
-       size = pointArray_ptsize(pa);
-#ifdef PGIS_DEBUG
-       lwnotice("getPoint3dz_p: point size: %d", size);
-#endif
-       memcpy(op, getPoint_internal(pa, n), size);
        return 1;
 }
 
@@ -547,17 +629,7 @@ POINT2D
 getPoint2d(const POINTARRAY *pa, int n)
 {
        POINT2D result;
-       int size;
-
-       if ( (n<0) || (n>=pa->npoints))
-       {
-               return result; //error
-       }
-
-       size = pointArray_ptsize(pa);
-
-       // this does x,y
-       memcpy(&result.x, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
+       getPoint2d_p(pa, n, &result);
        return result;
 }
 
@@ -567,21 +639,19 @@ getPoint2d(const POINTARRAY *pa, int n)
 int
 getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
 {
-        int size;
-
+#if PARANOIA_LEVEL > 0
        if ( ! pa ) return 0;
 
-        if ( (n<0) || (n>=pa->npoints))
-        {
-                lwerror("getPoint2d_p: point offset out of range");
-                return 0; //error
-        }
-
-        size = pointArray_ptsize(pa);
+       if ( (n<0) || (n>=pa->npoints))
+       {
+               lwerror("getPoint2d_p: point offset out of range");
+               return 0; //error
+       }
+#endif
 
-        // this does x,y
-        memcpy(point, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
-        return 1;
+       // this does x,y
+       memcpy(point, getPoint_internal(pa, n), sizeof(POINT2D));
+       return 1;
 }
 
 // get a pointer to nth point of a POINTARRAY
@@ -592,6 +662,7 @@ getPoint_internal(const POINTARRAY *pa, int n)
 {
        int size;
 
+#if PARANOIA_LEVEL > 0
        if ( pa == NULL ) {
                lwerror("getPoint got NULL pointarray");
                return NULL;
@@ -601,6 +672,7 @@ getPoint_internal(const POINTARRAY *pa, int n)
        {
                return NULL; //error
        }
+#endif
 
        size = pointArray_ptsize(pa);
 
index f69c120ab51745510a880429699680f3555d55fa..917198e455fecf3fefe61ca906f0d75e5585b406 100644 (file)
@@ -237,3 +237,8 @@ select '140', asewkt(multi(setsrid('POINT(2 2)'::geometry, 3)));
 select '141', asewkt(multi(setsrid('LINESTRING(2 2, 3 3)'::geometry, 4)));
 select '142', asewkt(multi(setsrid('LINESTRING(2 2, 3 3)'::geometry, 5)));
 select '143', asewkt(multi(setsrid('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'::geometry, 6)));
+
+select '144', asewkt(force_3dm('POINT(1 2 3)'));
+select '145', asewkt(force_3dz('POINTM(1 2 3)'));
+select '146', asewkt(force_4d('POINTM(1 2 3)'));
+select '147', asewkt(force_4d('POINT(1 2 3)'));
index 61e77f03f9c34264221dee69da1bb0578cbe2c55..51874638a1031f8770b839975aae9e1fdbaaacd8 100644 (file)
@@ -143,3 +143,7 @@ ERROR:  POSTGIS2GEOS conversion failed
 141|SRID=4;MULTILINESTRING((2 2,3 3))
 142|SRID=5;MULTILINESTRING((2 2,3 3))
 143|SRID=6;MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))
+144|POINTM(1 2 0)
+145|POINT(1 2 0)
+146|POINT(1 2 0 3)
+147|POINT(1 2 3 0)