]> 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:29:41 +0000 (21:29 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 22 Nov 2005 21:29:41 +0000 (21:29 +0000)
fixing bugs in force_{3dm,3dz,4d}() user functions, for which
tests have been added in regress dir.
Wrapped paranoid checks in PARANOIA_LEVEL preprocessor blocks.
Updated release notes and CHANGES file.

git-svn-id: http://svn.osgeo.org/postgis/trunk@2053 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 092b12e00bc764c36bdb5f5a53abb380aabf70b6..730a0ba52dd71db876325a021358df61ddbb0fb9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -35,6 +35,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 b1f9fc8905b6f6b8bb13cbf0f62e53f3f906a141..7a8aba99629e6b12ba4a5b35045d978937759db8 100644 (file)
@@ -5016,6 +5016,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 9232d182dd796a72ecbe0552e2f94ff694e3cedd..5692dc0508573c23c7da6ea408872eab4980dcdf 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 e517b6f1069406caa0d4614848fdef464d89ec86..41498939bc0e0774a063de7fc80d2f784f6800d9 100644 (file)
@@ -8,6 +8,11 @@
 #include "liblwgeom.h"
 #include "wktparse.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
@@ -427,14 +432,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))
@@ -442,11 +449,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;
+
 }
 
 
@@ -479,64 +516,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;
 }
 
@@ -548,17 +630,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;
 }
 
@@ -568,21 +640,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
@@ -593,6 +663,7 @@ getPoint_internal(const POINTARRAY *pa, int n)
 {
        int size;
 
+#if PARANOIA_LEVEL > 0
        if ( pa == NULL ) {
                lwerror("getPoint got NULL pointarray");
                return NULL;
@@ -602,6 +673,7 @@ getPoint_internal(const POINTARRAY *pa, int n)
        {
                return NULL; //error
        }
+#endif
 
        size = pointArray_ptsize(pa);
 
index 9ed6f2bd303ffdeb09479ad4f9e984115df87820..2e9a59cff4b6fbad18616ecf0b287e8242ba6684 100644 (file)
@@ -238,4 +238,9 @@ 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)'));
+
 select '144', asewkt(linemerge('GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), LINESTRING(4 4, 1 1), LINESTRING(-5 -5, 0 0))'::geometry));
index 42e899c1450bd3803946c0a7e5ae375b13e36e87..c98a3080b23872e79a9ee82a3cb4b1f7d5400e11 100644 (file)
@@ -143,4 +143,8 @@ 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)
 144|LINESTRING(-5 -5,0 0,1 1,4 4)