#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
}
// 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))
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;
+
}
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;
}
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;
}
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
{
int size;
+#if PARANOIA_LEVEL > 0
if ( pa == NULL ) {
lwerror("getPoint got NULL pointarray");
return NULL;
{
return NULL; //error
}
+#endif
size = pointArray_ptsize(pa);