From: Sandro Santilli Date: Wed, 5 Jan 2005 09:47:58 +0000 (+0000) Subject: collect(geom, geom) and collect_garray(geom[]) use WHEN_SIMPLE strategy X-Git-Tag: pgis_1_0_0RC1~87 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=349ab82f65899379471deba70844616126af8eba;p=postgis collect(geom, geom) and collect_garray(geom[]) use WHEN_SIMPLE strategy for bbox computation. pglwgeom_serialize() honour user's AUTOCACHE_BBOX define. BBOXCACHE_BEHAVIOURS updated. git-svn-id: http://svn.osgeo.org/postgis/trunk@1217 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/BBOXCACHE_BEHAVIOURS b/lwgeom/BBOXCACHE_BEHAVIOURS index eaf1ca499..ae5192991 100644 --- a/lwgeom/BBOXCACHE_BEHAVIOURS +++ b/lwgeom/BBOXCACHE_BEHAVIOURS @@ -36,6 +36,11 @@ points where some BBOX caching strategies could be enforced). *EXP* Uses deprecated LWEXPLODED, and LWEXPLODED_serialize() *LWG* Uses LWGEOM, pglwgeom_serialize() + + +AUTOCACHE_BBOX is currently used by all functions using *LWG* +(pglwgeom_serialize entry point). Other functions explicitly +listed in the AUTOCACHE_BBOX section also use it. [ explicit control ] @@ -90,6 +95,12 @@ points where some BBOX caching strategies could be enforced). multi(geometry) **SRL** envelope(geometry) *SRL* + ### computes union of + ### input bbox (if all available) + collect(geometry, geometry) *LWG* + collect_garray (geometry[]) *LWG* + + ## These use LWGEOM as a mean to access and modigy SERIALIZED form reverse(geometry) *LWG* **SRL** ForceRHR(geometry) *LWG* **SRL** @@ -104,11 +115,6 @@ points where some BBOX caching strategies could be enforced). StartPoint(geometry) *SRL* EndPoint(geometry) *SRL* - ### could use WHEN_SIMPLE computing union of - ### input bbox (if available or SIMPLE to compute: points) - collect(geometry, geometry) *LWG* - collect_garray (geometry[]) *LWG* - makePoint(float8, float8, [float8], [float8]) *LWG* makePointM(float8, float8, float8) *LWG* makeline_garray (geometry[]) *LWG* diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 9304a8f14..643a299d4 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -1572,6 +1572,7 @@ Datum LWGEOM_collect(PG_FUNCTION_ARGS) PG_LWGEOM *pglwgeom1, *pglwgeom2, *result; LWGEOM *lwgeoms[2], *outlwg; unsigned int type1, type2, outtype; + BOX2DFLOAT4 *box=NULL; // return null if both geoms are null if ( (geom1_ptr == NULL) && (geom2_ptr == NULL) ) @@ -1619,9 +1620,25 @@ Datum LWGEOM_collect(PG_FUNCTION_ARGS) elog(NOTICE, " outtype = %d", outtype); #endif + /* COMPUTE_BBOX WHEN_SIMPLE */ + if ( lwgeoms[0]->bbox && lwgeoms[1]->bbox ) + { + box = palloc(sizeof(BOX2DFLOAT4)); + box->xmin = LW_MIN(lwgeoms[0]->bbox->xmin, lwgeoms[1]->bbox->xmin); + box->ymin = LW_MIN(lwgeoms[0]->bbox->ymin, lwgeoms[1]->bbox->ymin); + box->xmax = LW_MAX(lwgeoms[0]->bbox->xmax, lwgeoms[1]->bbox->xmax); + box->ymax = LW_MAX(lwgeoms[0]->bbox->ymax, lwgeoms[1]->bbox->ymax); + } + + /* Drop input geometries bbox and SRID */ + lwgeom_dropBBOX(lwgeoms[0]); + lwgeom_dropSRID(lwgeoms[0]); + lwgeom_dropBBOX(lwgeoms[1]); + lwgeom_dropSRID(lwgeoms[1]); + outlwg = (LWGEOM *)lwcollection_construct( outtype, lwgeoms[0]->SRID, - NULL, 2, lwgeoms); + box, 2, lwgeoms); result = pglwgeom_serialize(outlwg); @@ -1773,6 +1790,7 @@ Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS) int i; int SRID=-1; size_t offset; + BOX2DFLOAT4 *box=NULL; #ifdef DEBUG elog(NOTICE, "LWGEOM_collect_garray called"); @@ -1829,19 +1847,46 @@ Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS) elog(NOTICE, "LWGEOM_collect_garray: geom %d deserialized", i); #endif - // Check SRID homogeneity - if ( ! i ) { + if ( ! i ) + { /* Get first geometry SRID */ SRID = lwgeoms[i]->SRID; - } else { + + /* COMPUTE_BBOX WHEN_SIMPLE */ + if ( lwgeoms[i]->bbox ) { + box = palloc(sizeof(BOX2DFLOAT4)); + memcpy(box, lwgeoms[i]->bbox, sizeof(BOX2DFLOAT4)); + } + } + else + { + // Check SRID homogeneity if ( lwgeoms[i]->SRID != SRID ) { elog(ERROR, "Operation on mixed SRID geometries"); PG_RETURN_NULL(); } + + /* COMPUTE_BBOX WHEN_SIMPLE */ + if ( box ) + { + if ( lwgeoms[i]->bbox ) + { + box->xmin = LW_MIN(box->xmin, lwgeoms[i]->bbox->xmin); + box->ymin = LW_MIN(box->ymin, lwgeoms[i]->bbox->ymin); + box->xmax = LW_MAX(box->xmax, lwgeoms[i]->bbox->xmax); + box->ymax = LW_MAX(box->ymax, lwgeoms[i]->bbox->ymax); + } + else + { + pfree(box); + box = NULL; + } + } } + lwgeom_dropSRID(lwgeoms[i]); lwgeom_dropBBOX(lwgeoms[i]); @@ -1868,7 +1913,7 @@ Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS) outlwg = (LWGEOM *)lwcollection_construct( outtype, SRID, - NULL, nelems, lwgeoms); + box, nelems, lwgeoms); result = pglwgeom_serialize(outlwg); diff --git a/lwgeom/lwgeom_pg.c b/lwgeom/lwgeom_pg.c index f5339f48b..411d06d51 100644 --- a/lwgeom/lwgeom_pg.c +++ b/lwgeom/lwgeom_pg.c @@ -106,6 +106,13 @@ pglwgeom_serialize(LWGEOM *in) size_t size; PG_LWGEOM *result; +#if AUTOCACHE_BBOX + if ( ! in->bbox && is_worth_caching_lwgeom_bbox(in) ) + { + lwgeom_addBBOX(in); + } +#endif + size = lwgeom_serialize_size(in) + VARHDRSZ; //lwnotice("lwgeom_serialize_size returned %d", size-VARHDRSZ); result = palloc(size);