[postgis-tickets] r17517 - Further re-organization of gserialized, attempting to hide all knowledge

Paul Ramsey pramsey at cleverelephant.ca
Wed Jun 12 03:04:58 PDT 2019


Author: pramsey
Date: 2019-06-12 15:04:58 -0700 (Wed, 12 Jun 2019)
New Revision: 17517

Modified:
   trunk/liblwgeom/Makefile.in
   trunk/liblwgeom/cunit/cu_geodetic.c
   trunk/liblwgeom/cunit/cu_gserialized1.c
   trunk/liblwgeom/gbox.c
   trunk/liblwgeom/gserialized.h
   trunk/liblwgeom/gserialized1.c
   trunk/liblwgeom/gutil.c
   trunk/liblwgeom/liblwgeom.h.in
   trunk/liblwgeom/lwcircstring.c
   trunk/liblwgeom/lwcollection.c
   trunk/liblwgeom/lwcurvepoly.c
   trunk/liblwgeom/lwgeodetic.c
   trunk/liblwgeom/lwin_twkb.c
   trunk/liblwgeom/lwline.c
   trunk/liblwgeom/lwpoint.c
   trunk/liblwgeom/lwpoly.c
   trunk/liblwgeom/lwspheroid.c
   trunk/liblwgeom/lwtriangle.c
   trunk/liblwgeom/lwutil.c
   trunk/liblwgeom/ptarray.c
   trunk/libpgcommon/gserialized_gist.c
   trunk/libpgcommon/gserialized_gist.h
   trunk/libpgcommon/lwgeom_pg.h
   trunk/postgis/geography_centroid.c
   trunk/postgis/geography_measurement.c
   trunk/postgis/gserialized_gist_nd.c
   trunk/postgis/gserialized_typmod.c
   trunk/postgis/lwgeom_box.c
   trunk/postgis/lwgeom_dumppoints.c
   trunk/postgis/lwgeom_functions_analytic.c
   trunk/postgis/lwgeom_geos.c
   trunk/postgis/lwgeom_in_geohash.c
   trunk/postgis/lwgeom_inout.c
Log:
Further re-organization of gserialized, attempting to hide all knowledge
of the underlying structure behind the API


Modified: trunk/liblwgeom/Makefile.in
===================================================================
--- trunk/liblwgeom/Makefile.in	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/Makefile.in	2019-06-12 22:04:58 UTC (rev 17517)
@@ -96,7 +96,6 @@
 	gserialized.o \
 	gserialized1.o \
 	gserialized2.o \
-	gutil.o \
 	lwgeodetic.o \
 	lwgeodetic_tree.o \
 	lwrandom.o \

Modified: trunk/liblwgeom/cunit/cu_geodetic.c
===================================================================
--- trunk/liblwgeom/cunit/cu_geodetic.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/cunit/cu_geodetic.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -853,7 +853,7 @@
 
 	LWGEOM *geom;
 	int i = 0;
-	GBOX *gbox = gbox_new(gflags(0,0,0));
+	GBOX *gbox = gbox_new(lwflags(0,0,0));
 	BOX3D *box3d;
 
 	char ewkt[][512] =
@@ -1348,7 +1348,7 @@
 	/* Init to WGS84 */
 	spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS);
 
-	gbox.flags = gflags(0, 0, 1);
+	gbox.flags = lwflags(0, 0, 1);
 
 	/* Medford lot test polygon */
 	lwg = lwgeom_from_wkt("POLYGON((-122.848227067007 42.5007249610493,-122.848309475585 42.5007179884263,-122.848327688675 42.500835880696,-122.848245279942 42.5008428533324,-122.848227067007 42.5007249610493))", LW_PARSER_CHECK_NONE);
@@ -1429,7 +1429,7 @@
 	/* Init to WGS84 */
 	spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS);
 
-	gbox.flags = gflags(0, 0, 1);
+	gbox.flags = lwflags(0, 0, 1);
 
 	/* One-degree square by equator */
 	lwg = lwgeom_from_wkt("POLYGON((1 20,1 21,2 21,2 20,1 20))", LW_PARSER_CHECK_NONE);

Modified: trunk/liblwgeom/cunit/cu_gserialized1.c
===================================================================
--- trunk/liblwgeom/cunit/cu_gserialized1.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/cunit/cu_gserialized1.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -102,7 +102,7 @@
 	FLAGS_SET_GEODETIC(flags, 1);
 	CU_ASSERT_EQUAL(1, FLAGS_GET_GEODETIC(flags));
 
-	flags = gflags(1, 0, 1); /* z=1, m=0, geodetic=1 */
+	flags = lwflags(1, 0, 1); /* z=1, m=0, geodetic=1 */
 
 	CU_ASSERT_EQUAL(1, FLAGS_GET_GEODETIC(flags));
 	CU_ASSERT_EQUAL(1, FLAGS_GET_Z(flags));
@@ -109,7 +109,7 @@
 	CU_ASSERT_EQUAL(0, FLAGS_GET_M(flags));
 	CU_ASSERT_EQUAL(2, FLAGS_GET_ZM(flags));
 
-	flags = gflags(1, 1, 1); /* z=1, m=1, geodetic=1 */
+	flags = lwflags(1, 1, 1); /* z=1, m=1, geodetic=1 */
 
 	CU_ASSERT_EQUAL(1, FLAGS_GET_GEODETIC(flags));
 	CU_ASSERT_EQUAL(1, FLAGS_GET_Z(flags));
@@ -116,7 +116,7 @@
 	CU_ASSERT_EQUAL(1, FLAGS_GET_M(flags));
 	CU_ASSERT_EQUAL(3, FLAGS_GET_ZM(flags));
 
-	flags = gflags(0, 1, 0); /* z=0, m=1, geodetic=0 */
+	flags = lwflags(0, 1, 0); /* z=0, m=1, geodetic=0 */
 
 	CU_ASSERT_EQUAL(0, FLAGS_GET_GEODETIC(flags));
 	CU_ASSERT_EQUAL(0, FLAGS_GET_Z(flags));
@@ -236,7 +236,7 @@
 
 static void test_gbox_serialized_size(void)
 {
-	uint8_t flags = gflags(0, 0, 0);
+	uint8_t flags = lwflags(0, 0, 0);
 	CU_ASSERT_EQUAL(gbox_serialized_size(flags),16);
 	FLAGS_SET_BBOX(flags, 1);
 	CU_ASSERT_EQUAL(gbox_serialized_size(flags),16);

Modified: trunk/liblwgeom/gbox.c
===================================================================
--- trunk/liblwgeom/gbox.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/gbox.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -365,7 +365,7 @@
 	const char *ptr = str;
 	char *nextptr;
 	char *gbox_start = strstr(str, "GBOX((");
-	GBOX *gbox = gbox_new(gflags(0,0,1));
+	GBOX *gbox = gbox_new(lwflags(0,0,1));
 	if ( ! gbox_start ) return NULL; /* No header found */
 	ptr += 6;
 	gbox->xmin = strtod(ptr, &nextptr);
@@ -544,7 +544,7 @@
 
 	has_z = FLAGS_GET_Z(pa->flags);
 	has_m = FLAGS_GET_M(pa->flags);
-	gbox->flags = gflags(has_z, has_m, 0);
+	gbox->flags = lwflags(has_z, has_m, 0);
 	LWDEBUGF(4, "ptarray_calculate_gbox Z: %d M: %d", has_z, has_m);
 
 	getPoint4d_p(pa, 0, &p);
@@ -586,7 +586,7 @@
 	if (curve->points->npoints < 3) return LW_FAILURE;
 
 	tmp.flags =
-	    gflags(FLAGS_GET_Z(curve->flags), FLAGS_GET_M(curve->flags), 0);
+	    lwflags(FLAGS_GET_Z(curve->flags), FLAGS_GET_M(curve->flags), 0);
 
 	/* Initialize */
 	gbox->xmin = gbox->ymin = gbox->zmin = gbox->mmin = FLT_MAX;

Modified: trunk/liblwgeom/gserialized.h
===================================================================
--- trunk/liblwgeom/gserialized.h	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/gserialized.h	2019-06-12 22:04:58 UTC (rev 17517)
@@ -0,0 +1,162 @@
+/**********************************************************************
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.net
+ *
+ * PostGIS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * PostGIS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PostGIS.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ **********************************************************************
+ *
+ * Copyright 2019 Paul Ramsey <pramsey at cleverelephant.ca>
+ *
+ **********************************************************************/
+
+/*
+* GSERIALIZED PUBLIC API
+*/
+
+/**
+* Copy a new bounding box into an existing gserialized.
+* If necessary a new #GSERIALIZED will be allocated. Test
+* that input != output before freeing input.
+*/
+GSERIALIZED *gserialized_set_gbox(GSERIALIZED *g, GBOX *gbox);
+
+/**
+* Remove the bounding box from a #GSERIALIZED. Returns a freshly
+* allocated #GSERIALIZED every time.
+*/
+GSERIALIZED* gserialized_drop_gbox(GSERIALIZED *g)
+
+/**
+* Read the box from the #GSERIALIZED or calculate it if necessary.
+* Return #LWFAILURE if box cannot be calculated (NULL or EMPTY
+* input).
+*/
+int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox);
+
+/**
+* Read the box from the #GSERIALIZED or return #LWFAILURE if
+* box is unavailable.
+*/
+int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *gbox);
+
+/**
+* Extract the geometry type from the serialized form (it hides in
+* the anonymous data area, so this is a handy function).
+*/
+extern uint32_t gserialized_get_type(const GSERIALIZED *g);
+
+/**
+* Returns the size in bytes to read from toast to get the basic
+* information from a geometry: GSERIALIZED struct, bbox and type
+*/
+extern uint32_t gserialized_max_header_size(void);
+
+/**
+* Returns a hash code for the srid/type/geometry information
+* in the GSERIALIZED. Ignores metadata like flags and optional
+* boxes, etc.
+*/
+extern uint64_t gserialized_hash(const GSERIALIZED *g);
+
+/**
+* Extract the SRID from the serialized form (it is packed into
+* three bytes so this is a handy function).
+*/
+extern int32_t gserialized_get_srid(const GSERIALIZED *g);
+
+/**
+* Write the SRID into the serialized form (it is packed into
+* three bytes so this is a handy function).
+*/
+extern void gserialized_set_srid(GSERIALIZED *g, int32_t srid);
+
+/**
+* Check if a #GSERIALIZED is empty without deserializing first.
+* Only checks if the number of elements of the parent geometry
+* is zero, will not catch collections of empty, eg:
+* GEOMETRYCOLLECTION(POINT EMPTY)
+*/
+extern int gserialized_is_empty(const GSERIALIZED *g);
+
+/**
+* Check if a #GSERIALIZED has a bounding box without deserializing first.
+*/
+extern int gserialized_has_bbox(const GSERIALIZED *gser);
+
+/**
+* Check if a #GSERIALIZED has a Z ordinate.
+*/
+extern int gserialized_has_z(const GSERIALIZED *gser);
+
+/**
+* Check if a #GSERIALIZED has an M ordinate.
+*/
+extern int gserialized_has_m(const GSERIALIZED *gser);
+
+/**
+* Check if a #GSERIALIZED is a geography.
+*/
+extern int gserialized_is_geodetic(const GSERIALIZED *gser);
+
+/**
+* Return the number of dimensions (2, 3, 4) in a geometry
+*/
+extern int gserialized_ndims(const GSERIALIZED *gser);
+
+/**
+* Return -1 if g1 is "less than" g2, 1 if g1 is "greater than"
+* g2 and 0 if g1 and g2 are the "same". Equality is evaluated
+* with a memcmp and size check. So it is possible that two
+* identical objects where one lacks a bounding box could be
+* evaluated as non-equal initially. Greater and less than
+* are evaluated by calculating a sortable key from the center
+* point of the object bounds.
+*/
+extern int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2);
+
+/**
+* Allocate a new #GSERIALIZED from an #LWGEOM. For all non-point types, a bounding
+* box will be calculated and embedded in the serialization. The geodetic flag is used
+* to control the box calculation (cartesian or geocentric). If set, the size pointer
+* will contain the size of the final output, which is useful for setting the PgSQL
+* VARSIZE information.
+*/
+extern GSERIALIZED* gserialized_from_lwgeom(LWGEOM *geom, size_t *size);
+
+/**
+* Return the memory size a GSERIALIZED will occupy for a given LWGEOM.
+*/
+extern size_t gserialized_from_lwgeom_size(const LWGEOM *geom);
+
+/**
+* Allocate a new #LWGEOM from a #GSERIALIZED. The resulting #LWGEOM will have coordinates
+* that are double aligned and suitable for direct reading using getPoint2d_p_ro
+*/
+extern LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g);
+
+/**
+* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
+* it is not, calculate it from the geometry. If that doesn't work (null
+* or empty) return LW_FAILURE.
+*/
+extern int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box);
+
+/**
+* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
+* it is not, return LW_FAILURE.
+*/
+extern int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *box);
+

Modified: trunk/liblwgeom/gserialized1.c
===================================================================
--- trunk/liblwgeom/gserialized1.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/gserialized1.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -1612,3 +1612,121 @@
 
 	return lwgeom;
 }
+
+const float * gserialized_get_float_box_p(const GSERIALIZED *g, size_t *ndims)
+{
+	if (ndims)
+		*ndims = FLAGS_NDIMS_BOX(g->flags);
+	if (!g) return NULL;
+	if (!gserialized_has_bbox(g)) return NULL;
+	return (const float *)(g->data);
+}
+
+/**
+* Update the bounding box of a #GSERIALIZED, allocating a fresh one
+* if there is not enough space to just write the new box in.
+* <em>WARNING</em> if a new object needs to be created, the
+* input pointer will have to be freed by the caller! Check
+* to see if input == output. Returns null if there's a problem
+* like mismatched dimensions.
+*/
+GSERIALIZED* gserialized_set_gbox(GSERIALIZED *g, GBOX *gbox)
+{
+
+	int g_ndims = FLAGS_NDIMS_BOX(g->flags);
+	int box_ndims = FLAGS_NDIMS_BOX(gbox->flags);
+	GSERIALIZED *g_out = NULL;
+	size_t box_size = 2 * g_ndims * sizeof(float);
+	float *fbox;
+	int fbox_pos = 0;
+
+	/* The dimensionality of the inputs has to match or we are SOL. */
+	if ( g_ndims != box_ndims )
+	{
+		return NULL;
+	}
+
+	/* Serialized already has room for a box. */
+	if (FLAGS_GET_BBOX(g->flags))
+	{
+		g_out = g;
+	}
+	/* Serialized has no box. We need to allocate enough space for the old
+	   data plus the box, and leave a gap in the memory segment to write
+	   the new values into.
+	*/
+	else
+	{
+		size_t varsize_new = SIZE_GET(g->size) + box_size;
+		uint8_t *ptr;
+		g_out = lwalloc(varsize_new);
+		/* Copy the head of g into place */
+		memcpy(g_out, g, 8);
+		/* Copy the body of g into place after leaving space for the box */
+		ptr = g_out->data;
+		ptr += box_size;
+		memcpy(ptr, g->data, SIZE_GET(g->size) - 8);
+		FLAGS_SET_BBOX(g_out->flags, 1);
+		g->size = SIZE_SET(g->size, varsize_new);
+	}
+
+	/* Move bounds to nearest float values */
+	gbox_float_round(gbox);
+	/* Now write the float box values into the memory segement */
+	fbox = (float*)(g_out->data);
+	/* Copy in X/Y */
+	fbox[fbox_pos++] = gbox->xmin;
+	fbox[fbox_pos++] = gbox->xmax;
+	fbox[fbox_pos++] = gbox->ymin;
+	fbox[fbox_pos++] = gbox->ymax;
+	/* Optionally copy in higher dims */
+	if (g_ndims > 2)
+	{
+		fbox[fbox_pos++] = gbox->zmin;
+		fbox[fbox_pos++] = gbox->zmax;
+	}
+	/* Optionally copy in higher dims */
+	if (g_ndims > 3)
+	{
+		fbox[fbox_pos++] = gbox->mmin;
+		fbox[fbox_pos++] = gbox->mmax;
+	}
+
+	return g_out;
+}
+
+
+/**
+* Remove the bounding box from a #GSERIALIZED. Returns a freshly
+* allocated #GSERIALIZED every time.
+*/
+GSERIALIZED* gserialized_drop_gbox(GSERIALIZED *g)
+{
+	int g_ndims = FLAGS_NDIMS_BOX(g->flags);
+	size_t box_size = 2 * g_ndims * sizeof(float);
+	size_t g_out_size = SIZE_GET(g->size) - box_size;
+	GSERIALIZED *g_out = lwalloc(g_out_size);
+
+	/* Copy the contents while omitting the box */
+	if ( FLAGS_GET_BBOX(g->flags) )
+	{
+		uint8_t *outptr = (uint8_t*)g_out;
+		uint8_t *inptr = (uint8_t*)g;
+		/* Copy the header (size+type) of g into place */
+		memcpy(outptr, inptr, 8);
+		outptr += 8;
+		inptr += 8 + box_size;
+		/* Copy parts after the box into place */
+		memcpy(outptr, inptr, g_out_size - 8);
+		FLAGS_SET_BBOX(g_out->flags, 0);
+		g_out->size = SIZE_SET(g_out->size, g_out_size);
+	}
+	/* No box? Nothing to do but copy and return. */
+	else
+	{
+		memcpy(g_out, g, g_out_size);
+	}
+
+	return g_out;
+}
+

Modified: trunk/liblwgeom/gutil.c
===================================================================
--- trunk/liblwgeom/gutil.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/gutil.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -22,210 +22,3 @@
  *
  **********************************************************************/
 
-
-#include <ctype.h>
-
-#include "liblwgeom_internal.h"
-
-/* Structure for the type array */
-struct geomtype_struct
-{
-	char *typename;
-	int type;
-	int z;
-	int m;
-};
-
-/* Type array. Note that the order of this array is important in
-   that any typename in the list must *NOT* occur within an entry
-   before it. Otherwise if we search for "POINT" at the top of the
-   list we would also match MULTIPOINT, for example. */
-
-struct geomtype_struct geomtype_struct_array[] =
-{
-	{ "GEOMETRYCOLLECTIONZM", COLLECTIONTYPE, 1, 1 },
-	{ "GEOMETRYCOLLECTIONZ", COLLECTIONTYPE, 1, 0 },
-	{ "GEOMETRYCOLLECTIONM", COLLECTIONTYPE, 0, 1 },
-	{ "GEOMETRYCOLLECTION", COLLECTIONTYPE, 0, 0 },
-
-	{ "GEOMETRYZM", 0, 1, 1 },
-	{ "GEOMETRYZ", 0, 1, 0 },
-	{ "GEOMETRYM", 0, 0, 1 },
-	{ "GEOMETRY", 0, 0, 0 },
-
-	{ "POLYHEDRALSURFACEZM", POLYHEDRALSURFACETYPE, 1, 1 },
-	{ "POLYHEDRALSURFACEZ", POLYHEDRALSURFACETYPE, 1, 0 },
-	{ "POLYHEDRALSURFACEM", POLYHEDRALSURFACETYPE, 0, 1 },
-	{ "POLYHEDRALSURFACE", POLYHEDRALSURFACETYPE, 0, 0 },
-
-	{ "TINZM", TINTYPE, 1, 1 },
-	{ "TINZ", TINTYPE, 1, 0 },
-	{ "TINM", TINTYPE, 0, 1 },
-	{ "TIN", TINTYPE, 0, 0 },
-
-	{ "CIRCULARSTRINGZM", CIRCSTRINGTYPE, 1, 1 },
-	{ "CIRCULARSTRINGZ", CIRCSTRINGTYPE, 1, 0 },
-	{ "CIRCULARSTRINGM", CIRCSTRINGTYPE, 0, 1 },
-	{ "CIRCULARSTRING", CIRCSTRINGTYPE, 0, 0 },
-
-	{ "COMPOUNDCURVEZM", COMPOUNDTYPE, 1, 1 },
-	{ "COMPOUNDCURVEZ", COMPOUNDTYPE, 1, 0 },
-	{ "COMPOUNDCURVEM", COMPOUNDTYPE, 0, 1 },
-	{ "COMPOUNDCURVE", COMPOUNDTYPE, 0, 0 },
-
-	{ "CURVEPOLYGONZM", CURVEPOLYTYPE, 1, 1 },
-	{ "CURVEPOLYGONZ", CURVEPOLYTYPE, 1, 0 },
-	{ "CURVEPOLYGONM", CURVEPOLYTYPE, 0, 1 },
-	{ "CURVEPOLYGON", CURVEPOLYTYPE, 0, 0 },
-
-	{ "MULTICURVEZM", MULTICURVETYPE, 1, 1 },
-	{ "MULTICURVEZ", MULTICURVETYPE, 1, 0 },
-	{ "MULTICURVEM", MULTICURVETYPE, 0, 1 },
-	{ "MULTICURVE", MULTICURVETYPE, 0, 0 },
-
-	{ "MULTISURFACEZM", MULTISURFACETYPE, 1, 1 },
-	{ "MULTISURFACEZ", MULTISURFACETYPE, 1, 0 },
-	{ "MULTISURFACEM", MULTISURFACETYPE, 0, 1 },
-	{ "MULTISURFACE", MULTISURFACETYPE, 0, 0 },
-
-	{ "MULTILINESTRINGZM", MULTILINETYPE, 1, 1 },
-	{ "MULTILINESTRINGZ", MULTILINETYPE, 1, 0 },
-	{ "MULTILINESTRINGM", MULTILINETYPE, 0, 1 },
-	{ "MULTILINESTRING", MULTILINETYPE, 0, 0 },
-
-	{ "MULTIPOLYGONZM", MULTIPOLYGONTYPE, 1, 1 },
-	{ "MULTIPOLYGONZ", MULTIPOLYGONTYPE, 1, 0 },
-	{ "MULTIPOLYGONM", MULTIPOLYGONTYPE, 0, 1 },
-	{ "MULTIPOLYGON", MULTIPOLYGONTYPE, 0, 0 },
-
-	{ "MULTIPOINTZM", MULTIPOINTTYPE, 1, 1 },
-	{ "MULTIPOINTZ", MULTIPOINTTYPE, 1, 0 },
-	{ "MULTIPOINTM", MULTIPOINTTYPE, 0, 1 },
-	{ "MULTIPOINT", MULTIPOINTTYPE, 0, 0 },
-
-	{ "LINESTRINGZM", LINETYPE, 1, 1 },
-	{ "LINESTRINGZ", LINETYPE, 1, 0 },
-	{ "LINESTRINGM", LINETYPE, 0, 1 },
-	{ "LINESTRING", LINETYPE, 0, 0 },
-
-	{ "TRIANGLEZM", TRIANGLETYPE, 1, 1 },
-	{ "TRIANGLEZ", TRIANGLETYPE, 1, 0 },
-	{ "TRIANGLEM", TRIANGLETYPE, 0, 1 },
-	{ "TRIANGLE", TRIANGLETYPE, 0, 0 },
-
-	{ "POLYGONZM", POLYGONTYPE, 1, 1 },
-	{ "POLYGONZ", POLYGONTYPE, 1, 0 },
-	{ "POLYGONM", POLYGONTYPE, 0, 1 },
-	{ "POLYGON", POLYGONTYPE, 0, 0 },
-
-	{ "POINTZM", POINTTYPE, 1, 1 },
-	{ "POINTZ", POINTTYPE, 1, 0 },
-	{ "POINTM", POINTTYPE, 0, 1 },
-	{ "POINT", POINTTYPE, 0, 0 }
-
-};
-#define GEOMTYPE_STRUCT_ARRAY_LEN (sizeof geomtype_struct_array/sizeof(struct geomtype_struct))
-
-/*
-* We use a very simple upper case mapper here, because the system toupper() function
-* is locale dependent and may have trouble mapping lower case strings to the upper
-* case ones we expect (see, the "Turkisk I", http://www.i18nguy.com/unicode/turkish-i18n.html)
-* We could also count on PgSQL sending us *lower* case inputs, as it seems to do that
-* regardless of the case the user provides for the type arguments.
-*/
-const char dumb_upper_map[128] = "................................................0123456789.......ABCDEFGHIJKLMNOPQRSTUVWXYZ......ABCDEFGHIJKLMNOPQRSTUVWXYZ.....";
-
-static char dump_toupper(int in)
-{
-	if ( in < 0 || in > 127 )
-		return '.';
-	return dumb_upper_map[in];
-}
-
-uint8_t gflags(int hasz, int hasm, int geodetic)
-{
-	uint8_t flags = 0;
-	if ( hasz )
-		FLAGS_SET_Z(flags, 1);
-	if ( hasm )
-		FLAGS_SET_M(flags, 1);
-	if ( geodetic )
-		FLAGS_SET_GEODETIC(flags, 1);
-	return flags;
-}
-
-/**
-* Calculate type integer and dimensional flags from string input.
-* Case insensitive, and insensitive to spaces at front and back.
-* Type == 0 in the case of the string "GEOMETRY" or "GEOGRAPHY".
-* Return LW_SUCCESS for success.
-*/
-int geometry_type_from_string(const char *str, uint8_t *type, int *z, int *m)
-{
-	char *tmpstr;
-	size_t tmpstartpos, tmpendpos;
-	size_t i;
-
-	assert(str);
-	assert(type);
-	assert(z);
-	assert(m);
-
-	/* Initialize. */
-	*type = 0;
-	*z = 0;
-	*m = 0;
-
-	/* Locate any leading/trailing spaces */
-	tmpstartpos = 0;
-	for (i = 0; i < strlen(str); i++)
-	{
-		if (str[i] != ' ')
-		{
-			tmpstartpos = i;
-			break;
-		}
-	}
-
-	tmpendpos = strlen(str) - 1;
-	for (i = strlen(str) - 1; i != 0; i--)
-	{
-		if (str[i] != ' ')
-		{
-			tmpendpos = i;
-			break;
-		}
-	}
-
-	/* Copy and convert to upper case for comparison */
-	tmpstr = lwalloc(tmpendpos - tmpstartpos + 2);
-	for (i = tmpstartpos; i <= tmpendpos; i++)
-		tmpstr[i - tmpstartpos] = dump_toupper(str[i]);
-
-	/* Add NULL to terminate */
-	tmpstr[i - tmpstartpos] = '\0';
-
-	/* Now check for the type */
-	for (i = 0; i < GEOMTYPE_STRUCT_ARRAY_LEN; i++)
-	{
-		if (!strcmp(tmpstr, geomtype_struct_array[i].typename))
-		{
-			*type = geomtype_struct_array[i].type;
-			*z = geomtype_struct_array[i].z;
-			*m = geomtype_struct_array[i].m;
-
-			lwfree(tmpstr);
-
-			return LW_SUCCESS;
-		}
-
-	}
-
-	lwfree(tmpstr);
-
-	return LW_FAILURE;
-}
-
-
-
-

Modified: trunk/liblwgeom/liblwgeom.h.in
===================================================================
--- trunk/liblwgeom/liblwgeom.h.in	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/liblwgeom.h.in	2019-06-12 22:04:58 UTC (rev 17517)
@@ -669,15 +669,22 @@
 
 extern LWCOLLECTION* lwcollection_concat_in_place(LWCOLLECTION* col1, const LWCOLLECTION* col2);
 
+/**
+* Construct a new flags char.
+*/
+extern uint8_t lwflags(int hasz, int hasm, int geodetic);
 
+
+
 /***********************************************************************
-** Utility functions for flag byte and srid_flag integer.
+** GSERIALIZED API
 */
 
 /**
-* Construct a new flags char.
+* Access to the float bounding box, if there is one.
+* NULL if there is not.
 */
-extern uint8_t gflags(int hasz, int hasm, int geodetic);
+extern const float * gserialized_get_float_box_p(const GSERIALIZED *g, size_t *ndims);
 
 /**
 * Extract the geometry type from the serialized form (it hides in
@@ -755,6 +762,50 @@
 extern int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2);
 
 /**
+* Allocate a new #GSERIALIZED from an #LWGEOM. For all non-point types, a bounding
+* box will be calculated and embedded in the serialization. The geodetic flag is used
+* to control the box calculation (cartesian or geocentric). If set, the size pointer
+* will contain the size of the final output, which is useful for setting the PgSQL
+* VARSIZE information.
+*/
+extern GSERIALIZED* gserialized_from_lwgeom(LWGEOM *geom, size_t *size);
+
+/**
+* Allocate a new #LWGEOM from a #GSERIALIZED. The resulting #LWGEOM will have coordinates
+* that are double aligned and suitable for direct reading using getPoint2d_p_ro
+*/
+extern LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g);
+
+/**
+* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
+* it is not, calculate it from the geometry. If that doesn't work (null
+* or empty) return LW_FAILURE.
+*/
+extern int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box);
+
+/**
+* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
+* it is not, return LW_FAILURE.
+*/
+extern int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *box);
+
+/**
+* Copy a new bounding box into an existing gserialized.
+* If necessary a new #GSERIALIZED will be allocated. Test
+* that input != output before freeing input.
+*/
+extern GSERIALIZED *gserialized_set_gbox(GSERIALIZED *g, GBOX *gbox);
+
+/**
+* Remove the bounding box from a #GSERIALIZED. Returns a freshly
+* allocated #GSERIALIZED every time.
+*/
+extern GSERIALIZED* gserialized_drop_gbox(GSERIALIZED *g);
+
+/*****************************************************************************/
+
+
+/**
 * Call this function to drop BBOX and SRID
 * from LWGEOM. If LWGEOM type is *not* flagged
 * with the HASBBOX flag and has a bbox, it
@@ -1962,35 +2013,6 @@
 extern int geometry_type_from_string(const char *str, uint8_t *type, int *z, int *m);
 
 /**
-* Allocate a new #GSERIALIZED from an #LWGEOM. For all non-point types, a bounding
-* box will be calculated and embedded in the serialization. The geodetic flag is used
-* to control the box calculation (cartesian or geocentric). If set, the size pointer
-* will contain the size of the final output, which is useful for setting the PgSQL
-* VARSIZE information.
-*/
-extern GSERIALIZED* gserialized_from_lwgeom(LWGEOM *geom, size_t *size);
-
-/**
-* Allocate a new #LWGEOM from a #GSERIALIZED. The resulting #LWGEOM will have coordinates
-* that are double aligned and suitable for direct reading using getPoint2d_p_ro
-*/
-extern LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g);
-
-/**
-* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
-* it is not, calculate it from the geometry. If that doesn't work (null
-* or empty) return LW_FAILURE.
-*/
-extern int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box);
-
-/**
-* Pull a #GBOX from the header of a #GSERIALIZED, if one is available. If
-* it is not, return LW_FAILURE.
-*/
-extern int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *box);
-
-
-/**
  * Parser check flags
  *
  *  @see lwgeom_from_wkb

Modified: trunk/liblwgeom/lwcircstring.c
===================================================================
--- trunk/liblwgeom/lwcircstring.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwcircstring.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -80,7 +80,7 @@
 {
 	LWCIRCSTRING *result = lwalloc(sizeof(LWCIRCSTRING));
 	result->type = CIRCSTRINGTYPE;
-	result->flags = gflags(hasz,hasm,0);
+	result->flags = lwflags(hasz,hasm,0);
 	result->srid = srid;
 	result->points = ptarray_construct_empty(hasz, hasm, 1);
 	result->bbox = NULL;

Modified: trunk/liblwgeom/lwcollection.c
===================================================================
--- trunk/liblwgeom/lwcollection.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwcollection.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -77,7 +77,7 @@
 
 	ret = lwalloc(sizeof(LWCOLLECTION));
 	ret->type = type;
-	ret->flags = gflags(hasz,hasm,0);
+	ret->flags = lwflags(hasz,hasm,0);
 	FLAGS_SET_BBOX(ret->flags, bbox?1:0);
 	ret->srid = srid;
 	ret->ngeoms = ngeoms;
@@ -97,7 +97,7 @@
 
 	ret = lwalloc(sizeof(LWCOLLECTION));
 	ret->type = type;
-	ret->flags = gflags(hasz,hasm,0);
+	ret->flags = lwflags(hasz,hasm,0);
 	ret->srid = srid;
 	ret->ngeoms = 0;
 	ret->maxgeoms = 1; /* Allocate room for sub-members, just in case. */

Modified: trunk/liblwgeom/lwcurvepoly.c
===================================================================
--- trunk/liblwgeom/lwcurvepoly.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwcurvepoly.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -38,7 +38,7 @@
 
 	ret = lwalloc(sizeof(LWCURVEPOLY));
 	ret->type = CURVEPOLYTYPE;
-	ret->flags = gflags(hasz, hasm, 0);
+	ret->flags = lwflags(hasz, hasm, 0);
 	ret->srid = srid;
 	ret->nrings = 0;
 	ret->maxrings = 1; /* Allocate room for sub-members, just in case. */

Modified: trunk/liblwgeom/lwgeodetic.c
===================================================================
--- trunk/liblwgeom/lwgeodetic.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwgeodetic.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -2952,7 +2952,7 @@
 	LWDEBUGF(4, "got type %d", geom->type);
 
 	/* Add a geodetic flag to the incoming gbox */
-	gbox->flags = gflags(FLAGS_GET_Z(geom->flags),FLAGS_GET_M(geom->flags),1);
+	gbox->flags = lwflags(FLAGS_GET_Z(geom->flags),FLAGS_GET_M(geom->flags),1);
 
 	switch (geom->type)
 	{

Modified: trunk/liblwgeom/lwin_twkb.c
===================================================================
--- trunk/liblwgeom/lwin_twkb.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwin_twkb.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -583,7 +583,7 @@
 		/* Initialize */
 		has_bbox = s->has_bbox;
 		memset(&bbox, 0, sizeof(GBOX));
-		bbox.flags = gflags(s->has_z, s->has_m, 0);
+		bbox.flags = lwflags(s->has_z, s->has_m, 0);
 
 		/* X */
 		bbox.xmin = twkb_parse_state_double(s, s->factor);

Modified: trunk/liblwgeom/lwline.c
===================================================================
--- trunk/liblwgeom/lwline.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwline.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -65,7 +65,7 @@
 {
 	LWLINE *result = lwalloc(sizeof(LWLINE));
 	result->type = LINETYPE;
-	result->flags = gflags(hasz,hasm,0);
+	result->flags = lwflags(hasz,hasm,0);
 	result->srid = srid;
 	result->points = ptarray_construct_empty(hasz, hasm, 1);
 	result->bbox = NULL;

Modified: trunk/liblwgeom/lwpoint.c
===================================================================
--- trunk/liblwgeom/lwpoint.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwpoint.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -152,7 +152,7 @@
 {
 	LWPOINT *result = lwalloc(sizeof(LWPOINT));
 	result->type = POINTTYPE;
-	result->flags = gflags(hasz, hasm, 0);
+	result->flags = lwflags(hasz, hasm, 0);
 	result->srid = srid;
 	result->point = ptarray_construct(hasz, hasm, 0);
 	result->bbox = NULL;

Modified: trunk/liblwgeom/lwpoly.c
===================================================================
--- trunk/liblwgeom/lwpoly.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwpoly.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -65,7 +65,7 @@
 
 	result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
 	result->type = POLYGONTYPE;
-	result->flags = gflags(hasz, hasm, 0);
+	result->flags = lwflags(hasz, hasm, 0);
 	FLAGS_SET_BBOX(result->flags, bbox?1:0);
 	result->srid = srid;
 	result->nrings = nrings;
@@ -162,7 +162,7 @@
 {
 	LWPOLY *result = lwalloc(sizeof(LWPOLY));
 	result->type = POLYGONTYPE;
-	result->flags = gflags(hasz,hasm,0);
+	result->flags = lwflags(hasz,hasm,0);
 	result->srid = srid;
 	result->nrings = 0;
 	result->maxrings = 1; /* Allocate room for ring, just in case. */

Modified: trunk/liblwgeom/lwspheroid.c
===================================================================
--- trunk/liblwgeom/lwspheroid.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwspheroid.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -502,7 +502,7 @@
 	double delta_lon_tolerance;
 	double latitude_min;
 
-	gbox2d.flags = gflags(0, 0, 0);
+	gbox2d.flags = lwflags(0, 0, 0);
 
 	/* Return zero on non-sensical inputs */
 	if ( ! pa || pa->npoints < 4 )

Modified: trunk/liblwgeom/lwtriangle.c
===================================================================
--- trunk/liblwgeom/lwtriangle.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwtriangle.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -59,7 +59,7 @@
 {
 	LWTRIANGLE *result = lwalloc(sizeof(LWTRIANGLE));
 	result->type = TRIANGLETYPE;
-	result->flags = gflags(hasz,hasm,0);
+	result->flags = lwflags(hasz,hasm,0);
 	result->srid = srid;
 	result->points = ptarray_construct_empty(hasz, hasm, 1);
 	result->bbox = NULL;

Modified: trunk/liblwgeom/lwutil.c
===================================================================
--- trunk/liblwgeom/lwutil.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/lwutil.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -370,3 +370,210 @@
 	return newsrid;
 }
 
+
+
+
+/* Structure for the type array */
+struct geomtype_struct
+{
+	char *typename;
+	int type;
+	int z;
+	int m;
+};
+
+/* Type array. Note that the order of this array is important in
+   that any typename in the list must *NOT* occur within an entry
+   before it. Otherwise if we search for "POINT" at the top of the
+   list we would also match MULTIPOINT, for example. */
+
+struct geomtype_struct geomtype_struct_array[] =
+{
+	{ "GEOMETRYCOLLECTIONZM", COLLECTIONTYPE, 1, 1 },
+	{ "GEOMETRYCOLLECTIONZ", COLLECTIONTYPE, 1, 0 },
+	{ "GEOMETRYCOLLECTIONM", COLLECTIONTYPE, 0, 1 },
+	{ "GEOMETRYCOLLECTION", COLLECTIONTYPE, 0, 0 },
+
+	{ "GEOMETRYZM", 0, 1, 1 },
+	{ "GEOMETRYZ", 0, 1, 0 },
+	{ "GEOMETRYM", 0, 0, 1 },
+	{ "GEOMETRY", 0, 0, 0 },
+
+	{ "POLYHEDRALSURFACEZM", POLYHEDRALSURFACETYPE, 1, 1 },
+	{ "POLYHEDRALSURFACEZ", POLYHEDRALSURFACETYPE, 1, 0 },
+	{ "POLYHEDRALSURFACEM", POLYHEDRALSURFACETYPE, 0, 1 },
+	{ "POLYHEDRALSURFACE", POLYHEDRALSURFACETYPE, 0, 0 },
+
+	{ "TINZM", TINTYPE, 1, 1 },
+	{ "TINZ", TINTYPE, 1, 0 },
+	{ "TINM", TINTYPE, 0, 1 },
+	{ "TIN", TINTYPE, 0, 0 },
+
+	{ "CIRCULARSTRINGZM", CIRCSTRINGTYPE, 1, 1 },
+	{ "CIRCULARSTRINGZ", CIRCSTRINGTYPE, 1, 0 },
+	{ "CIRCULARSTRINGM", CIRCSTRINGTYPE, 0, 1 },
+	{ "CIRCULARSTRING", CIRCSTRINGTYPE, 0, 0 },
+
+	{ "COMPOUNDCURVEZM", COMPOUNDTYPE, 1, 1 },
+	{ "COMPOUNDCURVEZ", COMPOUNDTYPE, 1, 0 },
+	{ "COMPOUNDCURVEM", COMPOUNDTYPE, 0, 1 },
+	{ "COMPOUNDCURVE", COMPOUNDTYPE, 0, 0 },
+
+	{ "CURVEPOLYGONZM", CURVEPOLYTYPE, 1, 1 },
+	{ "CURVEPOLYGONZ", CURVEPOLYTYPE, 1, 0 },
+	{ "CURVEPOLYGONM", CURVEPOLYTYPE, 0, 1 },
+	{ "CURVEPOLYGON", CURVEPOLYTYPE, 0, 0 },
+
+	{ "MULTICURVEZM", MULTICURVETYPE, 1, 1 },
+	{ "MULTICURVEZ", MULTICURVETYPE, 1, 0 },
+	{ "MULTICURVEM", MULTICURVETYPE, 0, 1 },
+	{ "MULTICURVE", MULTICURVETYPE, 0, 0 },
+
+	{ "MULTISURFACEZM", MULTISURFACETYPE, 1, 1 },
+	{ "MULTISURFACEZ", MULTISURFACETYPE, 1, 0 },
+	{ "MULTISURFACEM", MULTISURFACETYPE, 0, 1 },
+	{ "MULTISURFACE", MULTISURFACETYPE, 0, 0 },
+
+	{ "MULTILINESTRINGZM", MULTILINETYPE, 1, 1 },
+	{ "MULTILINESTRINGZ", MULTILINETYPE, 1, 0 },
+	{ "MULTILINESTRINGM", MULTILINETYPE, 0, 1 },
+	{ "MULTILINESTRING", MULTILINETYPE, 0, 0 },
+
+	{ "MULTIPOLYGONZM", MULTIPOLYGONTYPE, 1, 1 },
+	{ "MULTIPOLYGONZ", MULTIPOLYGONTYPE, 1, 0 },
+	{ "MULTIPOLYGONM", MULTIPOLYGONTYPE, 0, 1 },
+	{ "MULTIPOLYGON", MULTIPOLYGONTYPE, 0, 0 },
+
+	{ "MULTIPOINTZM", MULTIPOINTTYPE, 1, 1 },
+	{ "MULTIPOINTZ", MULTIPOINTTYPE, 1, 0 },
+	{ "MULTIPOINTM", MULTIPOINTTYPE, 0, 1 },
+	{ "MULTIPOINT", MULTIPOINTTYPE, 0, 0 },
+
+	{ "LINESTRINGZM", LINETYPE, 1, 1 },
+	{ "LINESTRINGZ", LINETYPE, 1, 0 },
+	{ "LINESTRINGM", LINETYPE, 0, 1 },
+	{ "LINESTRING", LINETYPE, 0, 0 },
+
+	{ "TRIANGLEZM", TRIANGLETYPE, 1, 1 },
+	{ "TRIANGLEZ", TRIANGLETYPE, 1, 0 },
+	{ "TRIANGLEM", TRIANGLETYPE, 0, 1 },
+	{ "TRIANGLE", TRIANGLETYPE, 0, 0 },
+
+	{ "POLYGONZM", POLYGONTYPE, 1, 1 },
+	{ "POLYGONZ", POLYGONTYPE, 1, 0 },
+	{ "POLYGONM", POLYGONTYPE, 0, 1 },
+	{ "POLYGON", POLYGONTYPE, 0, 0 },
+
+	{ "POINTZM", POINTTYPE, 1, 1 },
+	{ "POINTZ", POINTTYPE, 1, 0 },
+	{ "POINTM", POINTTYPE, 0, 1 },
+	{ "POINT", POINTTYPE, 0, 0 }
+
+};
+#define GEOMTYPE_STRUCT_ARRAY_LEN (sizeof geomtype_struct_array/sizeof(struct geomtype_struct))
+
+/*
+* We use a very simple upper case mapper here, because the system toupper() function
+* is locale dependent and may have trouble mapping lower case strings to the upper
+* case ones we expect (see, the "Turkisk I", http://www.i18nguy.com/unicode/turkish-i18n.html)
+* We could also count on PgSQL sending us *lower* case inputs, as it seems to do that
+* regardless of the case the user provides for the type arguments.
+*/
+const char dumb_upper_map[128] = "................................................0123456789.......ABCDEFGHIJKLMNOPQRSTUVWXYZ......ABCDEFGHIJKLMNOPQRSTUVWXYZ.....";
+
+static char dumb_toupper(int in)
+{
+	if ( in < 0 || in > 127 )
+		return '.';
+	return dumb_upper_map[in];
+}
+
+uint8_t lwflags(int hasz, int hasm, int geodetic)
+{
+	uint8_t flags = 0;
+	if ( hasz )
+		FLAGS_SET_Z(flags, 1);
+	if ( hasm )
+		FLAGS_SET_M(flags, 1);
+	if ( geodetic )
+		FLAGS_SET_GEODETIC(flags, 1);
+	return flags;
+}
+
+/**
+* Calculate type integer and dimensional flags from string input.
+* Case insensitive, and insensitive to spaces at front and back.
+* Type == 0 in the case of the string "GEOMETRY" or "GEOGRAPHY".
+* Return LW_SUCCESS for success.
+*/
+int geometry_type_from_string(const char *str, uint8_t *type, int *z, int *m)
+{
+	char *tmpstr;
+	size_t tmpstartpos, tmpendpos;
+	size_t i;
+
+	assert(str);
+	assert(type);
+	assert(z);
+	assert(m);
+
+	/* Initialize. */
+	*type = 0;
+	*z = 0;
+	*m = 0;
+
+	/* Locate any leading/trailing spaces */
+	tmpstartpos = 0;
+	for (i = 0; i < strlen(str); i++)
+	{
+		if (str[i] != ' ')
+		{
+			tmpstartpos = i;
+			break;
+		}
+	}
+
+	tmpendpos = strlen(str) - 1;
+	for (i = strlen(str) - 1; i != 0; i--)
+	{
+		if (str[i] != ' ')
+		{
+			tmpendpos = i;
+			break;
+		}
+	}
+
+	/* Copy and convert to upper case for comparison */
+	tmpstr = lwalloc(tmpendpos - tmpstartpos + 2);
+	for (i = tmpstartpos; i <= tmpendpos; i++)
+		tmpstr[i - tmpstartpos] = dumb_toupper(str[i]);
+
+	/* Add NULL to terminate */
+	tmpstr[i - tmpstartpos] = '\0';
+
+	/* Now check for the type */
+	for (i = 0; i < GEOMTYPE_STRUCT_ARRAY_LEN; i++)
+	{
+		if (!strcmp(tmpstr, geomtype_struct_array[i].typename))
+		{
+			*type = geomtype_struct_array[i].type;
+			*z = geomtype_struct_array[i].z;
+			*m = geomtype_struct_array[i].m;
+
+			lwfree(tmpstr);
+
+			return LW_SUCCESS;
+		}
+
+	}
+
+	lwfree(tmpstr);
+
+	return LW_FAILURE;
+}
+
+
+
+
+
+

Modified: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/liblwgeom/ptarray.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -62,7 +62,7 @@
 	pa->serialized_pointlist = NULL;
 
 	/* Set our dimensionality info on the bitmap */
-	pa->flags = gflags(hasz, hasm, 0);
+	pa->flags = lwflags(hasz, hasm, 0);
 
 	/* We will be allocating a bit of room */
 	pa->npoints = 0;
@@ -283,7 +283,7 @@
 {
 	POINTARRAY *pa = lwalloc(sizeof(POINTARRAY));
 	LWDEBUGF(5, "hasz = %d, hasm = %d, npoints = %d, ptlist = %p", hasz, hasm, npoints, ptlist);
-	pa->flags = gflags(hasz, hasm, 0);
+	pa->flags = lwflags(hasz, hasm, 0);
 	FLAGS_SET_READONLY(pa->flags, 1); /* We don't own this memory, so we can't alter or free it. */
 	pa->npoints = npoints;
 	pa->maxpoints = npoints;
@@ -297,7 +297,7 @@
 {
 	POINTARRAY *pa = lwalloc(sizeof(POINTARRAY));
 
-	pa->flags = gflags(hasz, hasm, 0);
+	pa->flags = lwflags(hasz, hasm, 0);
 	pa->npoints = npoints;
 	pa->maxpoints = npoints;
 

Modified: trunk/libpgcommon/gserialized_gist.c
===================================================================
--- trunk/libpgcommon/gserialized_gist.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/libpgcommon/gserialized_gist.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -56,6 +56,16 @@
 	return rv;
 }
 
+/* Allocates a new GIDX on the heap of the requested dimensionality */
+GIDX* gidx_new(int ndims)
+{
+	size_t size = GIDX_SIZE(ndims);
+	GIDX *g = (GIDX*)palloc(size);
+	Assert( (ndims <= GIDX_MAX_DIM) && (size <= GIDX_MAX_SIZE) );
+	POSTGIS_DEBUGF(5,"created new gidx of %d dimensions, size %d", ndims, (int)size);
+	SET_VARSIZE(g, size);
+	return g;
+}
 
 static uint8_t
 gserialized_datum_get_flags(Datum gsdatum)
@@ -158,92 +168,6 @@
 
 
 /**
-* Update the bounding box of a #GSERIALIZED, allocating a fresh one
-* if there is not enough space to just write the new box in.
-* <em>WARNING</em> if a new object needs to be created, the
-* input pointer will have to be freed by the caller! Check
-* to see if input == output. Returns null if there's a problem
-* like mismatched dimensions.
-*/
-GSERIALIZED* gserialized_set_gidx(GSERIALIZED *g, GIDX *gidx)
-{
-	int g_ndims = FLAGS_NDIMS_BOX(g->flags);
-	int box_ndims = GIDX_NDIMS(gidx);
-	GSERIALIZED *g_out = NULL;
-	size_t box_size = 2 * g_ndims * sizeof(float);
-
-	/* The dimensionality of the inputs has to match or we are SOL. */
-	if ( g_ndims != box_ndims )
-	{
-		return NULL;
-	}
-
-	/* Serialized already has room for a box. */
-	if ( FLAGS_GET_BBOX(g->flags) )
-	{
-		g_out = g;
-	}
-	/* Serialized has no box. We need to allocate enough space for the old
-	   data plus the box, and leave a gap in the memory segment to write
-	   the new values into.
-	*/
-	else
-	{
-		size_t varsize_new = VARSIZE(g) + box_size;
-		uint8_t *ptr;
-		g_out = palloc(varsize_new);
-		/* Copy the head of g into place */
-		memcpy(g_out, g, 8);
-		/* Copy the body of g into place after leaving space for the box */
-		ptr = g_out->data;
-		ptr += box_size;
-		memcpy(ptr, g->data, VARSIZE(g) - 8);
-		FLAGS_SET_BBOX(g_out->flags, 1);
-		SET_VARSIZE(g_out, varsize_new);
-	}
-
-	/* Now write the gidx values into the memory segement */
-	memcpy(g_out->data, gidx->c, box_size);
-
-	return g_out;
-}
-
-
-/**
-* Remove the bounding box from a #GSERIALIZED. Returns a freshly
-* allocated #GSERIALIZED every time.
-*/
-GSERIALIZED* gserialized_drop_gidx(GSERIALIZED *g)
-{
-	int g_ndims = FLAGS_NDIMS_BOX(g->flags);
-	size_t box_size = 2 * g_ndims * sizeof(float);
-	size_t g_out_size = VARSIZE(g) - box_size;
-	GSERIALIZED *g_out = palloc(g_out_size);
-
-	/* Copy the contents while omitting the box */
-	if ( FLAGS_GET_BBOX(g->flags) )
-	{
-		uint8_t *outptr = (uint8_t*)g_out;
-		uint8_t *inptr = (uint8_t*)g;
-		/* Copy the header (size+type) of g into place */
-		memcpy(outptr, inptr, 8);
-		outptr += 8;
-		inptr += 8 + box_size;
-		/* Copy parts after the box into place */
-		memcpy(outptr, inptr, g_out_size - 8);
-		FLAGS_SET_BBOX(g_out->flags, 0);
-		SET_VARSIZE(g_out, g_out_size);
-	}
-	/* No box? Nothing to do but copy and return. */
-	else
-	{
-		memcpy(g_out, g, g_out_size);
-	}
-
-	return g_out;
-}
-
-/**
 * Peak into a #GSERIALIZED datum to find the bounding box. If the
 * box is there, copy it out and return it. If not, calculate the box from the
 * full object and return the box based on that. If no box is available,
@@ -263,17 +187,21 @@
 	*/
 	gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 40);
 
-	POSTGIS_DEBUGF(4, "got flags %d", gpart->flags);
-
 	/* Do we even have a serialized bounding box? */
-	if ( FLAGS_GET_BBOX(gpart->flags) )
+	if (gserialized_has_bbox(gpart))
 	{
 		/* Yes! Copy it out into the GIDX! */
 		size_t size = gbox_serialized_size(gpart->flags);
-		POSTGIS_DEBUG(4, "copying box out of serialization");
-		memcpy(gidx->c, gpart->data, size);
+		size_t ndims, dim;
+		const float *f = gserialized_get_float_box_p(gpart, &ndims);
+		if (!f) return LW_FAILURE;
+		for (dim = 0; dim < ndims; dim++)
+		{
+			GIDX_SET_MIN(gidx, dim, f[2*dim]);
+			GIDX_SET_MAX(gidx, dim, f[2*dim+1]);
+		}
 		/* if M is present but Z is not, pad Z and shift M */
-		if ( FLAGS_GET_M(gpart->flags) && ! FLAGS_GET_Z(gpart->flags) )
+		if (gserialized_has_m(gpart) && ! gserialized_has_z(gpart))
 		{
 			size += 2 * sizeof(float);
 			GIDX_SET_MIN(gidx,3,GIDX_GET_MIN(gidx,2));
@@ -289,7 +217,7 @@
 		GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum);
 		LWGEOM *lwgeom = lwgeom_from_gserialized(g);
 		GBOX gbox;
-		if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE )
+		if (lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE)
 		{
 			POSTGIS_DEBUG(4, "could not calculate bbox, returning failure");
 			lwgeom_free(lwgeom);
@@ -301,81 +229,10 @@
 		POSTGIS_FREE_IF_COPY_P(g, gsdatum);
 		gidx_from_gbox_p(gbox, gidx);
 	}
-
 	POSTGIS_FREE_IF_COPY_P(gpart, gsdatum);
-
 	POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx));
-
 	return LW_SUCCESS;
 }
 
 
-/*
-** Peak into a geography to find the bounding box. If the
-** box is there, copy it out and return it. If not, calculate the box from the
-** full geography and return the box based on that. If no box is available,
-** return LW_FAILURE, otherwise LW_SUCCESS.
-*/
-int gserialized_get_gidx_p(const GSERIALIZED *g, GIDX *gidx)
-{
-	POSTGIS_DEBUG(4, "entered function");
-	POSTGIS_DEBUGF(4, "got flags %d", g->flags);
 
-	if ( FLAGS_GET_BBOX(g->flags) )
-	{
-		int ndims = FLAGS_NDIMS_GIDX(g->flags);
-		const size_t size = 2 * ndims * sizeof(float);
-		POSTGIS_DEBUG(4, "copying box out of serialization");
-		memcpy(gidx->c, g->data, size);
-		SET_VARSIZE(gidx, VARHDRSZ + size);
-	}
-	else
-	{
-		/* No, we need to calculate it from the full object. */
-		LWGEOM *lwgeom = lwgeom_from_gserialized(g);
-		GBOX gbox;
-		if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE )
-		{
-			POSTGIS_DEBUG(4, "could not calculate bbox, returning failure");
-			lwgeom_free(lwgeom);
-			return LW_FAILURE;
-		}
-		lwgeom_free(lwgeom);
-		gidx_from_gbox_p(gbox, gidx);
-	}
-	POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx));
-
-	return LW_SUCCESS;
-}
-
-
-/*
-** GIDX expansion, make d units bigger in all dimensions.
-*/
-void gidx_expand(GIDX *a, float d)
-{
-	uint32_t i;
-
-	POSTGIS_DEBUG(5, "entered function");
-
-	if ( a == NULL ) return;
-
-	for (i = 0; i < GIDX_NDIMS(a); i++)
-	{
-		GIDX_SET_MIN(a, i, GIDX_GET_MIN(a, i) - d);
-		GIDX_SET_MAX(a, i, GIDX_GET_MAX(a, i) + d);
-	}
-}
-
-
-/* Allocates a new GIDX on the heap of the requested dimensionality */
-GIDX* gidx_new(int ndims)
-{
-	size_t size = GIDX_SIZE(ndims);
-	GIDX *g = (GIDX*)palloc(size);
-	Assert( (ndims <= GIDX_MAX_DIM) && (size <= GIDX_MAX_SIZE) );
-	POSTGIS_DEBUGF(5,"created new gidx of %d dimensions, size %d", ndims, (int)size);
-	SET_VARSIZE(g, size);
-	return g;
-}
-

Modified: trunk/libpgcommon/gserialized_gist.h
===================================================================
--- trunk/libpgcommon/gserialized_gist.h	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/libpgcommon/gserialized_gist.h	2019-06-12 22:04:58 UTC (rev 17517)
@@ -62,9 +62,6 @@
 /* allocate a new gidx object on the heap */
 GIDX *gidx_new(int ndims);
 
-/* Increase the size of a GIDX */
-void gidx_expand(GIDX *a, float d);
-
 /* Note empty GIDX */
 bool gidx_is_unknown(const GIDX *a);
 
@@ -118,16 +115,6 @@
 /* Pull out the #GIDX bounding box with a absolute minimum system overhead */
 int gserialized_datum_get_gidx_p(Datum gserialized_datum, GIDX *gidx);
 
-/* Pull out the gidx bounding box from an already de-toasted geography */
-int gserialized_get_gidx_p(const GSERIALIZED *g, GIDX *gidx);
-/* Copy a new bounding box into an existing gserialized */
-GSERIALIZED *gserialized_set_gidx(GSERIALIZED *g, GIDX *gidx);
-
-/* Given two datums, do they overlap? Computed very fast using embedded boxes. */
-/* int gserialized_datum_overlaps(Datum gs1, Datum gs2); */
-/* Remove the box from a disk serialization */
-GSERIALIZED *gserialized_drop_gidx(GSERIALIZED *g);
-
 bool box2df_contains(const BOX2DF *a, const BOX2DF *b);
 void box2df_set_empty(BOX2DF *a);
 void box2df_set_finite(BOX2DF *a);

Modified: trunk/libpgcommon/lwgeom_pg.h
===================================================================
--- trunk/libpgcommon/lwgeom_pg.h	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/libpgcommon/lwgeom_pg.h	2019-06-12 22:04:58 UTC (rev 17517)
@@ -43,27 +43,27 @@
 /* Display a simple message at NOTICE level */
 /* from PgSQL utils/elog.h, LOG is 15, and DEBUG5 is 10 and everything else is in between */
 #define POSTGIS_DEBUG(level, msg) \
-        do { \
-                if (POSTGIS_DEBUG_LEVEL >= level) \
-                        ereport((level < 1 || level > 5) ? DEBUG5 : (LOG - level), (errmsg_internal("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__))); \
-        } while (0);
+		do { \
+				if (POSTGIS_DEBUG_LEVEL >= level) \
+						ereport((level < 1 || level > 5) ? DEBUG5 : (LOG - level), (errmsg_internal("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__))); \
+		} while (0);
 
 /* Display a formatted message at NOTICE level (like printf, with variadic arguments) */
 #define POSTGIS_DEBUGF(level, msg, ...) \
-        do { \
-                if (POSTGIS_DEBUG_LEVEL >= level) \
-                        ereport((level < 1 || level > 5) ? DEBUG5 : (LOG - level), (errmsg_internal("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__))); \
-        } while (0);
+		do { \
+				if (POSTGIS_DEBUG_LEVEL >= level) \
+						ereport((level < 1 || level > 5) ? DEBUG5 : (LOG - level), (errmsg_internal("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__))); \
+		} while (0);
 
 #else /* POSTGIS_DEBUG_LEVEL */
 
 /* Empty prototype that can be optimised away by the compiler for non-debug builds */
 #define POSTGIS_DEBUG(level, msg) \
-        ((void) 0)
+		((void) 0)
 
 /* Empty prototype that can be optimised away by the compiler for non-debug builds */
 #define POSTGIS_DEBUGF(level, msg, ...) \
-        ((void) 0)
+		((void) 0)
 
 #endif /* POSTGIS_DEBUG_LEVEL */
 
@@ -83,17 +83,17 @@
 extern void pg_unparser_errhint(LWGEOM_UNPARSER_RESULT *lwg_unparser_result);
 
 #define PG_PARSER_ERROR(lwg_parser_result) \
-        do { \
-                pg_parser_errhint(&lwg_parser_result); \
-        } while(0);
+		do { \
+				pg_parser_errhint(&lwg_parser_result); \
+		} while(0);
 
 /*
  * Standard macro for reporting unparser errors to PostgreSQL
  */
 #define PG_UNPARSER_ERROR(lwg_unparser_result) \
-        do { \
-                pg_unparser_errhint(&lwg_unparser_result); \
-        } while(0);
+		do { \
+				pg_unparser_errhint(&lwg_unparser_result); \
+		} while(0);
 
 /* TODO: only cancel the interrupt if inside an outer call ? */
 #define LWGEOM_INIT() { \
@@ -100,17 +100,7 @@
   lwgeom_cancel_interrupt(); \
 }
 
-
-/*
-** GSERIALIED prototypes used outside the index functions
-*/
-
 /**
-* Remove the embedded bounding box
-*/
-GSERIALIZED* gserialized_drop_gidx(GSERIALIZED *g);
-
-/**
 * Utility method to call the serialization and then set the
 * PgSQL varsize header appropriately with the serialized size.
 */

Modified: trunk/postgis/geography_centroid.c
===================================================================
--- trunk/postgis/geography_centroid.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/geography_centroid.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -78,7 +78,7 @@
 		LWCOLLECTION* empty = lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
 	 	lwgeom_out = lwcollection_as_lwgeom(empty);
 		lwgeom_set_geodetic(lwgeom_out, true);
-		g_out = gserialized_from_lwgeom(lwgeom_out, 0);
+		g_out = geography_serialize(lwgeom_out);
 		PG_RETURN_POINTER(g_out);
 	}
 
@@ -167,8 +167,7 @@
 	PG_FREE_IF_COPY(g, 0);
 
     lwgeom_out = lwpoint_as_lwgeom(lwpoint_out);
-    lwgeom_set_geodetic(lwgeom_out, true);
-    g_out = gserialized_from_lwgeom(lwgeom_out, 0);
+    g_out = geography_serialize(lwgeom_out);
 
 	PG_RETURN_POINTER(g_out);
 }

Modified: trunk/postgis/geography_measurement.c
===================================================================
--- trunk/postgis/geography_measurement.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/geography_measurement.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -687,7 +687,6 @@
 	GBOX gbox;
 	GSERIALIZED *g = NULL;
 	GSERIALIZED *g_out = NULL;
-	size_t g_out_size;
 	LWGEOM *lwpoint = NULL;
 	POINT2D pt;
 
@@ -707,13 +706,9 @@
 	gbox_pt_outside(&gbox, &pt);
 
 	lwpoint = (LWGEOM*) lwpoint_make2d(4326, pt.x, pt.y);
-	/* TODO: Investigate where this is used, this was probably not
-	* returning a geography object before. How did this miss checking
-	*/
-	lwgeom_set_geodetic(lwpoint, true);
-	g_out = gserialized_from_lwgeom(lwpoint, &g_out_size);
-	SET_VARSIZE(g_out, g_out_size);
 
+	g_out = geography_serialize(lwpoint);
+
 	PG_FREE_IF_COPY(g, 0);
 	PG_RETURN_POINTER(g_out);
 

Modified: trunk/postgis/gserialized_gist_nd.c
===================================================================
--- trunk/postgis/gserialized_gist_nd.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/gserialized_gist_nd.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -613,41 +613,6 @@
 	return sqrt(sum);
 }
 
-static double
-gidx_distance_m(const GIDX *a, const GIDX *b)
-{
-	int mdim_a, mdim_b;
-	double d, amin, amax, bmin, bmax;
-
-	/* Base computation on least available dimensions */
-	mdim_a = GIDX_NDIMS(a) - 1;
-	mdim_b = GIDX_NDIMS(b) - 1;
-
-	amin = GIDX_GET_MIN(a, mdim_a);
-	amax = GIDX_GET_MAX(a, mdim_a);
-	bmin = GIDX_GET_MIN(b, mdim_b);
-	bmax = GIDX_GET_MAX(b, mdim_b);
-
-	if ((amin <= bmax && amax >= bmin))
-	{
-		/* overlaps */
-		d = 0;
-	}
-	else if (bmax < amin)
-	{
-		/* is "left" */
-		d = amin - bmax;
-	}
-	else
-	{
-		/* is "right" */
-		assert(bmin > amax);
-		d = bmin - amax;
-	}
-
-	return d;
-}
-
 /**
  * Return a #GSERIALIZED with an expanded bounding box.
  */
@@ -654,18 +619,18 @@
 GSERIALIZED *
 gserialized_expand(GSERIALIZED *g, double distance)
 {
-	char boxmem[GIDX_MAX_SIZE];
-	GIDX *gidx = (GIDX *)boxmem;
+	GBOX gbox;
 	float fdistance = (float)distance;
+	gbox_init(&gbox);
 
 	/* Get our bounding box out of the geography, return right away if
 	   input is an EMPTY geometry. */
-	if (gserialized_get_gidx_p(g, gidx) == LW_FAILURE)
+	if (gserialized_get_gbox_p(g, &gbox) == LW_FAILURE)
 		return g;
 
-	gidx_expand(gidx, fdistance);
+	gbox_expand(&gbox, fdistance);
 
-	return gserialized_set_gidx(g, gidx);
+	return gserialized_set_gbox(g, &gbox);
 }
 
 /***********************************************************************
@@ -678,11 +643,6 @@
 PG_FUNCTION_INFO_V1(gserialized_distance_nd);
 Datum gserialized_distance_nd(PG_FUNCTION_ARGS)
 {
-	char b1mem[GIDX_MAX_SIZE];
-	GIDX *b1 = (GIDX *)b1mem;
-	char b2mem[GIDX_MAX_SIZE];
-	GIDX *b2 = (GIDX *)b2mem;
-
 	/* Feature-to-feature distance */
 	GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(0);
 	GSERIALIZED *geom2 = PG_GETARG_GSERIALIZED_P(1);
@@ -743,11 +703,21 @@
 
 		if (usebox)
 		{
-			double d;
-			gserialized_get_gidx_p(geom1, b1);
-			gserialized_get_gidx_p(geom2, b2);
-			d = gidx_distance_m(b1, b2);
-			distance += d * d;
+			GBOX b1, b2;
+			if (gserialized_get_gbox_p(geom1, &b1) && gserialized_get_gbox_p(geom2, &b2))
+			{
+				double d;
+				/* Disjoint left */
+				if (b1.mmin > b2.mmax)
+					d = b1.mmin - b2.mmax;
+				/* Disjoint right */
+				else if (b2.mmin > b1.mmax)
+					d = b2.mmin - b1.mmax;
+				/* Not Disjoint */
+				else
+					d = 0;
+				distance += d * d;
+			}
 		}
 		else
 			distance += (m2 - m1) * (m2 - m1);

Modified: trunk/postgis/gserialized_typmod.c
===================================================================
--- trunk/postgis/gserialized_typmod.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/gserialized_typmod.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -235,7 +235,7 @@
 	                  &elem_values, NULL, &n);
 
 	/* Set the SRID to the default value first */
-	if ( is_geography)
+	if (is_geography)
 	    TYPMOD_SET_SRID(typmod, SRID_DEFAULT);
 	else
 	    TYPMOD_SET_SRID(typmod, SRID_UNKNOWN);

Modified: trunk/postgis/lwgeom_box.c
===================================================================
--- trunk/postgis/lwgeom_box.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_box.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -554,7 +554,7 @@
 
 	error_if_srid_mismatch(minpoint->srid, maxpoint->srid);
 
-	result = gbox_new(gflags(0, 0, 0));
+	result = gbox_new(lwflags(0, 0, 0));
 
 	/* Process X min/max */
 	min = lwpoint_get_x(minpoint);

Modified: trunk/postgis/lwgeom_dumppoints.c
===================================================================
--- trunk/postgis/lwgeom_dumppoints.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_dumppoints.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -257,7 +257,7 @@
 				pathpt[0] = PointerGetDatum(construct_array(state->path, state->pathlen+1,
 						INT4OID, state->typlen, state->byval, state->align));
 
-				pathpt[1] = PointerGetDatum(gserialized_from_lwgeom((LWGEOM*)lwpoint,0));
+				pathpt[1] = PointerGetDatum(geometry_serialize((LWGEOM*)lwpoint));
 
 				tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
 				result = HeapTupleGetDatum(tuple);

Modified: trunk/postgis/lwgeom_functions_analytic.c
===================================================================
--- trunk/postgis/lwgeom_functions_analytic.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_functions_analytic.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -433,10 +433,8 @@
 	getPoint4d_p(in_lwpoint->point, 0, &offsetpoint);
 	grid.ipx = offsetpoint.x;
 	grid.ipy = offsetpoint.y;
-	if (lwgeom_has_z((LWGEOM*)in_lwpoint)) grid.ipz = offsetpoint.z;
-	else grid.ipz=0;
-	if (lwgeom_has_m((LWGEOM*)in_lwpoint)) grid.ipm = offsetpoint.m;
-	else grid.ipm=0;
+	grid.ipz = lwgeom_has_z((LWGEOM*)in_lwpoint) ? offsetpoint.z : 0;
+	grid.ipm = lwgeom_has_m((LWGEOM*)in_lwpoint) ? offsetpoint.m : 0;
 
 #if POSTGIS_DEBUG_LEVEL >= 4
 	grid_print(&grid);

Modified: trunk/postgis/lwgeom_geos.c
===================================================================
--- trunk/postgis/lwgeom_geos.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_geos.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -1209,7 +1209,7 @@
 		PG_RETURN_NULL();
 
 	/* Serialize and return */
-	gser_result = gserialized_from_lwgeom(lwgeom_result, 0);
+	gser_result = geometry_serialize(lwgeom_result);
 	lwgeom_free(lwgeom_result);
 	PG_RETURN_POINTER(gser_result);
 }
@@ -1338,7 +1338,7 @@
 	if (!lwgeom_result)
 		lwpgerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
 
-	gser_result = gserialized_from_lwgeom(lwgeom_result, 0);
+	gser_result = geometry_serialize(lwgeom_result);
 	lwgeom_free(lwgeom_input);
 	lwgeom_free(lwgeom_result);
 	PG_RETURN_POINTER(gser_result);
@@ -3088,7 +3088,7 @@
 	result_array_data = palloc(nclusters * sizeof(Datum));
 	for (i=0; i<nclusters; ++i)
 	{
-		result_array_data[i] = PointerGetDatum(gserialized_from_lwgeom(lw_results[i], NULL));
+		result_array_data[i] = PointerGetDatum(geometry_serialize(lw_results[i]));
 		lwgeom_free(lw_results[i]);
 	}
 	lwfree(lw_results);

Modified: trunk/postgis/lwgeom_in_geohash.c
===================================================================
--- trunk/postgis/lwgeom_in_geohash.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_in_geohash.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -62,7 +62,7 @@
 	POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash sw: %.20f, %.20f", lon[0], lat[0]);
 	POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash ne: %.20f, %.20f", lon[1], lat[1]);
 
-	box = gbox_new(gflags(0, 0, 1));
+	box = gbox_new(lwflags(0, 0, 1));
 
 	box->xmin = lon[0];
 	box->ymin = lat[0];

Modified: trunk/postgis/lwgeom_inout.c
===================================================================
--- trunk/postgis/lwgeom_inout.c	2019-06-12 15:27:01 UTC (rev 17516)
+++ trunk/postgis/lwgeom_inout.c	2019-06-12 22:04:58 UTC (rev 17517)
@@ -701,7 +701,7 @@
 	if ( ! gserialized_has_bbox(geom) )
 		PG_RETURN_POINTER(geom);
 
-	PG_RETURN_POINTER(gserialized_drop_gidx(geom));
+	PG_RETURN_POINTER(gserialized_drop_gbox(geom));
 }
 
 



More information about the postgis-tickets mailing list