return rv;
}
-int ptarray_calculate_gbox_cartesian(const POINTARRAY *pa, GBOX *gbox )
+static void
+ptarray_calculate_gbox_cartesian_2d(const POINTARRAY *pa, GBOX *gbox)
{
- uint32_t i;
- POINT4D p;
- int has_z, has_m;
+ const POINT2D *p = getPoint2d_cp(pa, 0);
+
+ gbox->xmax = gbox->xmin = p->x;
+ gbox->ymax = gbox->ymin = p->y;
+
+ for (uint32_t i = 1; i < pa->npoints; i++)
+ {
+ p = getPoint2d_cp(pa, i);
+ gbox->xmin = FP_MIN(gbox->xmin, p->x);
+ gbox->xmax = FP_MAX(gbox->xmax, p->x);
+ gbox->ymin = FP_MIN(gbox->ymin, p->y);
+ gbox->ymax = FP_MAX(gbox->ymax, p->y);
+ }
+}
+
+/* Works with X/Y/Z. Needs to be adjusted after if X/Y/M was required */
+static void
+ptarray_calculate_gbox_cartesian_3d(const POINTARRAY *pa, GBOX *gbox)
+{
+ const POINT3D *p = getPoint3d_cp(pa, 0);
+
+ gbox->xmax = gbox->xmin = p->x;
+ gbox->ymax = gbox->ymin = p->y;
+ gbox->zmax = gbox->zmin = p->z;
+
+ for (uint32_t i = 1; i < pa->npoints; i++)
+ {
+ p = getPoint3d_cp(pa, i);
+ gbox->xmin = FP_MIN(gbox->xmin, p->x);
+ gbox->xmax = FP_MAX(gbox->xmax, p->x);
+ gbox->ymin = FP_MIN(gbox->ymin, p->y);
+ gbox->ymax = FP_MAX(gbox->ymax, p->y);
+ gbox->zmin = FP_MIN(gbox->zmin, p->z);
+ gbox->zmax = FP_MAX(gbox->zmax, p->z);
+ }
+}
+
+static void
+ptarray_calculate_gbox_cartesian_4d(const POINTARRAY *pa, GBOX *gbox)
+{
+ const POINT4D *p = getPoint4d_cp(pa, 0);
+
+ gbox->xmax = gbox->xmin = p->x;
+ gbox->ymax = gbox->ymin = p->y;
+ gbox->zmax = gbox->zmin = p->z;
+ gbox->mmax = gbox->mmin = p->m;
- if ( ! pa ) return LW_FAILURE;
- if ( ! gbox ) return LW_FAILURE;
- if ( pa->npoints < 1 ) return LW_FAILURE;
+ for (uint32_t i = 1; i < pa->npoints; i++)
+ {
+ p = getPoint4d_cp(pa, i);
+ gbox->xmin = FP_MIN(gbox->xmin, p->x);
+ gbox->xmax = FP_MAX(gbox->xmax, p->x);
+ gbox->ymin = FP_MIN(gbox->ymin, p->y);
+ gbox->ymax = FP_MAX(gbox->ymax, p->y);
+ gbox->zmin = FP_MIN(gbox->zmin, p->z);
+ gbox->zmax = FP_MAX(gbox->zmax, p->z);
+ gbox->mmin = FP_MIN(gbox->mmin, p->m);
+ gbox->mmax = FP_MAX(gbox->mmax, p->m);
+ }
+}
+
+int
+ptarray_calculate_gbox_cartesian(const POINTARRAY *pa, GBOX *gbox)
+{
+ if (!pa || pa->npoints == 0)
+ return LW_FAILURE;
+ if (!gbox)
+ return LW_FAILURE;
- has_z = FLAGS_GET_Z(pa->flags);
- has_m = FLAGS_GET_M(pa->flags);
+ int has_z = FLAGS_GET_Z(pa->flags);
+ int has_m = FLAGS_GET_M(pa->flags);
gbox->flags = lwflags(has_z, has_m, 0);
LWDEBUGF(4, "ptarray_calculate_gbox Z: %d M: %d", has_z, has_m);
+ int coordinates = 2 + has_z + has_m;
- getPoint4d_p(pa, 0, &p);
- gbox->xmin = gbox->xmax = p.x;
- gbox->ymin = gbox->ymax = p.y;
- if ( has_z )
- gbox->zmin = gbox->zmax = p.z;
- if ( has_m )
- gbox->mmin = gbox->mmax = p.m;
-
- for ( i = 1 ; i < pa->npoints; i++ )
- {
- getPoint4d_p(pa, i, &p);
- gbox->xmin = FP_MIN(gbox->xmin, p.x);
- gbox->xmax = FP_MAX(gbox->xmax, p.x);
- gbox->ymin = FP_MIN(gbox->ymin, p.y);
- gbox->ymax = FP_MAX(gbox->ymax, p.y);
- if ( has_z )
+ switch (coordinates)
+ {
+ case 2:
+ {
+ ptarray_calculate_gbox_cartesian_2d(pa, gbox);
+ break;
+ }
+ case 3:
+ {
+ if (has_z)
{
- gbox->zmin = FP_MIN(gbox->zmin, p.z);
- gbox->zmax = FP_MAX(gbox->zmax, p.z);
+ ptarray_calculate_gbox_cartesian_3d(pa, gbox);
}
- if ( has_m )
+ else
{
- gbox->mmin = FP_MIN(gbox->mmin, p.m);
- gbox->mmax = FP_MAX(gbox->mmax, p.m);
+ double zmin = gbox->zmin;
+ double zmax = gbox->zmax;
+ ptarray_calculate_gbox_cartesian_3d(pa, gbox);
+ gbox->mmin = gbox->zmin;
+ gbox->mmax = gbox->zmax;
+ gbox->zmin = zmin;
+ gbox->zmax = zmax;
}
+ break;
+ }
+ default:
+ {
+ ptarray_calculate_gbox_cartesian_4d(pa, gbox);
+ break;
+ }
}
return LW_SUCCESS;
}
static inline const POINT2D *
getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
{
- if (!pa)
- return 0;
-
return (const POINT2D *)getPoint_internal(pa, n);
}
+/**
+ * Returns a POINT2D pointer into the POINTARRAY serialized_ptlist,
+ * suitable for reading from. This is very high performance
+ * and declared const because you aren't allowed to muck with the
+ * values, only read them.
+ */
+static inline const POINT3D *
+getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
+{
+ return (const POINT3D *)getPoint_internal(pa, n);
+}
+
+/**
+ * Returns a POINT2D pointer into the POINTARRAY serialized_ptlist,
+ * suitable for reading from. This is very high performance
+ * and declared const because you aren't allowed to muck with the
+ * values, only read them.
+ */
+static inline const POINT4D *
+getPoint4d_cp(const POINTARRAY *pa, uint32_t n)
+{
+ return (const POINT4D *)getPoint_internal(pa, n);
+}
+
static inline LWPOINT *
lwgeom_as_lwpoint(const LWGEOM *lwgeom)
{