]> granicus.if.org Git - postgis/commitdiff
Make the calculation of gboxes a little simpler in the db level code.
authorPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 7 Oct 2009 14:26:21 +0000 (14:26 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 7 Oct 2009 14:26:21 +0000 (14:26 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@4620 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/g_box.c
liblwgeom/libgeom.h
postgis/geography_distance.c

index b465200b90b170afc803ebbd5e782e775edad579..bf4b919758e48388f160ef2e8ec401ac92ff5d96 100644 (file)
@@ -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.
index e89f477899c70801cc1c9a15e07554825084f43f..030621ced7bc4971e822a3c62df3e48e7637b7b1 100644 (file)
@@ -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. 
 */
index af79d370ca274d19cdc3c90c2e7166ba4f511598..b6455741c498c88b0f29c54f4c08574e027da833 100644 (file)
@@ -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);