From: Paul Ramsey Date: Wed, 7 Oct 2009 14:26:21 +0000 (+0000) Subject: Make the calculation of gboxes a little simpler in the db level code. X-Git-Tag: 1.5.0b1~395 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e2da8b5140f3532915357ac47d632936aea41fdb;p=postgis Make the calculation of gboxes a little simpler in the db level code. git-svn-id: http://svn.osgeo.org/postgis/trunk@4620 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/g_box.c b/liblwgeom/g_box.c index b465200b9..bf4b91975 100644 --- a/liblwgeom/g_box.c +++ b/liblwgeom/g_box.c @@ -195,6 +195,51 @@ size_t gbox_serialized_size(uchar flags) return 2 * FLAGS_NDIMS(flags) * sizeof(float); } +int gbox_from_gserialized(GSERIALIZED *g, GBOX *gbox) +{ + + /* Null input! */ + if( ! g ) return G_FAILURE; + + /* Initialize the flags on the box */ + gbox->flags = g->flags; + + if ( FLAGS_GET_BBOX(g->flags) ) + { + int i = 0; + float *fbox = (float*)(g->data); + gbox->xmin = fbox[i]; i++; + gbox->xmax = fbox[i]; i++; + gbox->ymin = fbox[i]; i++; + gbox->ymax = fbox[i]; i++; + if ( FLAGS_GET_GEODETIC(g->flags) ) + { + gbox->zmin = fbox[i]; i++; + gbox->zmax = fbox[i]; i++; + return G_SUCCESS; + } + if ( FLAGS_GET_Z(g->flags) ) + { + gbox->zmin = fbox[i]; i++; + gbox->zmax = fbox[i]; i++; + } + if ( FLAGS_GET_M(g->flags) ) + { + gbox->mmin = fbox[i]; i++; + gbox->mmax = fbox[i]; i++; + } + return G_SUCCESS; + } + + LWDEBUG(4, "calculating new box from scratch"); + if( gserialized_calculate_gbox_geocentric_p(g, gbox) == G_FAILURE ) + { + LWDEBUG(4, "calculated null bbox, returning failure"); + return G_FAILURE; + } + return G_SUCCESS; +} + /* ******************************************************************************** ** Compute cartesian bounding GBOX boxes from LWGEOM. diff --git a/liblwgeom/libgeom.h b/liblwgeom/libgeom.h index e89f47789..030621ced 100644 --- a/liblwgeom/libgeom.h +++ b/liblwgeom/libgeom.h @@ -425,6 +425,11 @@ extern GBOX* gbox_copy(GBOX *gbox); */ extern GBOX* gbox_from_string(char *str); +/** +* Given a serialized form, extract the box if it exists, calculate it if it does not. +*/ +extern int gbox_from_gserialized(GSERIALIZED *g, GBOX *gbox); + /** * Return #LW_TRUE if the #GBOX overlaps, #LW_FALSE otherwise. */ diff --git a/postgis/geography_distance.c b/postgis/geography_distance.c index af79d370c..b6455741c 100644 --- a/postgis/geography_distance.c +++ b/postgis/geography_distance.c @@ -45,20 +45,19 @@ Datum geography_distance_sphere(PG_FUNCTION_ARGS) double tolerance; double distance; - /* We need the bounding boxes in case of polygon calculations, - which requires them to generate a stab-line to test point-in-polygon. */ - geography_datum_gidx(PG_GETARG_DATUM(0), gidx1); - geography_datum_gidx(PG_GETARG_DATUM(0), gidx2); - gbox_from_gidx(gidx1, &gbox1); - gbox_from_gidx(gidx2, &gbox2); - gbox1.flags = FLAGS_SET_GEODETIC(gbox1.flags,1); - gbox2.flags = FLAGS_SET_GEODETIC(gbox2.flags,1); - pfree(gidx1); - pfree(gidx2); - /* Get our geometry objects loaded into memory. */ g1 = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); g2 = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + /* We need the bounding boxes in case of polygon calculations, + which requires them to generate a stab-line to test point-in-polygon. */ + if( ! gbox_from_gserialized(g1, &gbox1) || + ! gbox_from_gserialized(g2, &gbox2) ) + { + elog(ERROR, "Error in gbox_from_gserialized calculation."); + PG_RETURN_NULL(); + } + lwgeom1 = lwgeom_from_gserialized(g1); lwgeom2 = lwgeom_from_gserialized(g2);