mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-25 01:22:47 +00:00
Alter the in-built casts between the internal PostgreSQL BOX type and the PostGIS geometry/BOX3D types so that they do not go through an intermediate BOX2DFLOAT4 first. This prevents the float4 rounding errors appearing in the numbers when invoking the casts.
git-svn-id: http://svn.osgeo.org/postgis/trunk@3805 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
919bac6d62
commit
15e1705f88
|
@ -1,3 +1,16 @@
|
|||
/**********************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* PostGIS - Spatial Types for PostgreSQL
|
||||
* http://postgis.refractions.net
|
||||
* Copyright 2001-2009 Refractions Research Inc.
|
||||
* Copyright 2009 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
|
||||
*
|
||||
* This is free software; you can redistribute and/or modify it under
|
||||
* the terms of the GNU General Public Licence. See the COPYING file.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "postgres.h"
|
||||
#include "utils/geo_decls.h"
|
||||
|
||||
|
@ -5,38 +18,38 @@
|
|||
#include "liblwgeom.h"
|
||||
|
||||
|
||||
void box_to_box2df(BOX *box, BOX2DFLOAT4 *out);
|
||||
void box_to_box3d(BOX *box, BOX3D *out);
|
||||
void box3d_to_box_p(BOX3D *box, BOX *out);
|
||||
|
||||
|
||||
|
||||
/* convert postgresql BOX to BOX2D */
|
||||
/* convert postgresql BOX to BOX3D */
|
||||
void
|
||||
box_to_box2df(BOX *box, BOX2DFLOAT4 *out)
|
||||
box_to_box3d(BOX *box, BOX3D *out)
|
||||
{
|
||||
#if PARANOIA_LEVEL > 0
|
||||
if (box == NULL) return;
|
||||
#endif
|
||||
|
||||
out->xmin = nextDown_f(box->low.x);
|
||||
out->ymin = nextDown_f(box->low.y);
|
||||
out->xmin = box->low.x;
|
||||
out->ymin = box->low.y;
|
||||
|
||||
out->xmax = nextUp_f(box->high.x);
|
||||
out->ymax = nextUp_f(box->high.x);
|
||||
out->xmax = box->high.x;
|
||||
out->ymax = box->high.y;
|
||||
|
||||
}
|
||||
|
||||
/* convert BOX2D to postgresql BOX */
|
||||
/* convert BOX3D to postgresql BOX */
|
||||
void
|
||||
box2df_to_box_p(BOX2DFLOAT4 *box, BOX *out)
|
||||
box3d_to_box_p(BOX3D *box, BOX *out)
|
||||
{
|
||||
#if PARANOIA_LEVEL > 0
|
||||
if (box == NULL) return;
|
||||
#endif
|
||||
|
||||
out->low.x = nextDown_d(box->xmin);
|
||||
out->low.y = nextDown_d(box->ymin);
|
||||
out->low.x = box->xmin;
|
||||
out->low.y = box->ymin;
|
||||
|
||||
out->high.x = nextUp_d(box->xmax);
|
||||
out->high.y = nextUp_d(box->ymax);
|
||||
out->high.x = box->xmax;
|
||||
out->high.y = box->ymax;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,10 +150,9 @@ PG_FUNCTION_INFO_V1(BOX3D_to_BOX);
|
|||
Datum BOX3D_to_BOX(PG_FUNCTION_ARGS)
|
||||
{
|
||||
BOX3D *in = (BOX3D *)PG_GETARG_POINTER(0);
|
||||
BOX2DFLOAT4 *box2d = box3d_to_box2df(in);
|
||||
BOX *box = palloc(sizeof(BOX));
|
||||
|
||||
box2df_to_box_p(box2d, box);
|
||||
box3d_to_box_p(in, box);
|
||||
PG_RETURN_POINTER(box);
|
||||
}
|
||||
|
||||
|
|
|
@ -2400,17 +2400,18 @@ Datum LWGEOM_expand(PG_FUNCTION_ARGS)
|
|||
PG_FUNCTION_INFO_V1(LWGEOM_to_BOX);
|
||||
Datum LWGEOM_to_BOX(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_LWGEOM *lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
BOX2DFLOAT4 box2d;
|
||||
PG_LWGEOM *pg_lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
BOX3D *box3d;
|
||||
BOX *result = (BOX *)lwalloc(sizeof(BOX));
|
||||
LWGEOM *lwgeom = lwgeom_deserialize(SERIALIZED_FORM(pg_lwgeom));
|
||||
|
||||
if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), &box2d) )
|
||||
{
|
||||
PG_RETURN_NULL(); /* must be the empty geometry */
|
||||
}
|
||||
box2df_to_box_p(&box2d, result);
|
||||
/* Calculate the BOX3D of the geometry */
|
||||
box3d = lwgeom_compute_box3d(lwgeom);
|
||||
box3d_to_box_p(box3d, result);
|
||||
lwfree(box3d);
|
||||
lwfree(lwgeom);
|
||||
|
||||
PG_FREE_IF_COPY(lwgeom, 0);
|
||||
PG_FREE_IF_COPY(pg_lwgeom, 0);
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
|
|
@ -82,8 +82,8 @@ extern Oid getGeometryOID(void);
|
|||
|
||||
/* PG-dependant */
|
||||
/* BOX is postgresql standard type */
|
||||
extern void box_to_box2df_p(BOX *box, BOX2DFLOAT4 *out);
|
||||
extern void box2df_to_box_p(BOX2DFLOAT4 *box, BOX *out);
|
||||
extern void box_to_box3d_p(BOX *box, BOX3D *out);
|
||||
extern void box3d_to_box_p(BOX3D *box, BOX *out);
|
||||
|
||||
/* PG-exposed */
|
||||
Datum BOX2D_same(PG_FUNCTION_ARGS);
|
||||
|
|
Loading…
Reference in a new issue