}
}
+/**
+* Read the bounding box off a serialization and fail if
+* it is not already there.
+*/
+int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *box)
+{
+ /* Try to just read the serialized box. */
+ if ( gserialized_read_gbox_p(g, box) == LW_SUCCESS )
+ {
+ return LW_SUCCESS;
+ }
+ /* No box? Try to peek into simpler geometries and */
+ /* derive a box without creating an lwgeom */
+ else if ( gserialized_peek_gbox_p(g, box) == LW_SUCCESS )
+ {
+ return LW_SUCCESS;
+ }
+ else
+ {
+ return LW_FAILURE;
+ }
+}
+
+
+
/***********************************************************************
* Calculate the GSERIALIZED size for an LWGEOM.
extern int lwgeom_is_clockwise(LWGEOM *lwgeom);
+/**
+* Simplification
+*/
extern LWGEOM* lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed);
extern LWGEOM* lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance);
+/**
+* Snap-to-grid
+*/
+typedef struct gridspec_t
+{
+ double ipx;
+ double ipy;
+ double ipz;
+ double ipm;
+ double xsize;
+ double ysize;
+ double zsize;
+ double msize;
+}
+gridspec;
+
+extern LWGEOM* lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid);
+extern void lwgeom_grid_in_place(LWGEOM *lwgeom, const gridspec *grid);
+
+
/****************************************************************
* READ/WRITE FUNCTIONS
*
* 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 *gbox);
+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);
/**
/**
* Snap to grid
*/
-
-/**
-* Snap-to-grid Support
-*/
-typedef struct gridspec_t
-{
- double ipx;
- double ipy;
- double ipz;
- double ipm;
- double xsize;
- double ysize;
- double zsize;
- double msize;
-}
-gridspec;
-
-LWGEOM* lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid);
-void lwgeom_grid_in_place(LWGEOM *lwgeom, const gridspec *grid);
void ptarray_grid_in_place(POINTARRAY *pa, const gridspec *grid);
/*
** enough to take serious advantage of PG_DETOAST_DATUM_SLICE will have
** already been compressed, which means the entire object will be
** fetched and decompressed before a slice is taken, thus removing
- ** any efficiencies gained from slicing. We need to move to
- ** "storage = external" and implement our own geometry compressor
- ** before we can take advantage of sliced retrieval.
+ ** any efficiencies gained from slicing.
+ ** As of Pg12 we can partially decompress a toasted object
+ ** (though we still need to fully retrieve it from TOAST)
+ ** which makes slicing worthwhile.
*/
gpart = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum);
flags = gpart->flags;
{
GBOX gserialized_box;
/* We only apply the optimization if the bounding box is available */
- if ((gserialized_read_gbox_p(geom_in, &gserialized_box) == LW_SUCCESS) ||
- (gserialized_peek_gbox_p(geom_in, &gserialized_box) == LW_SUCCESS))
+ if (gserialized_fast_gbox_p(geom_in, &gserialized_box) == LW_SUCCESS)
{
/* Shortcut to drop geometries smaller than the resolution */
double geom_width = gserialized_box.xmax - gserialized_box.xmin;
**********************************************************************/
#include <string.h>
+#include <float.h>
#include "mvt.h"
#include "lwgeom_geos.h"
PointerGetDatum(v.val.numeric)));
d = strtod(str, NULL);
l = strtol(str, NULL, 10);
- if (FP_NEQUALS(d, (double)l))
+
+ if (fabs(d - (double)l) > FLT_EPSILON)
{
MVT_PARSE_VALUE(d, mvt_kv_double_value, double_values_hash,
double_value, sizeof(double));
#include "access/htup.h"
#include "../postgis_config.h"
#include "liblwgeom.h"
-#include "liblwgeom_internal.h"
#include "lwgeom_pg.h"
#include "lwgeom_log.h"