From dcf3e6c7d6c069225fad098b5207fd2fb7d2a26d Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Thu, 30 Dec 2004 13:47:56 +0000 Subject: [PATCH] Introduced bbox caching worth evaluation functions, honoured in LWGEOM_in, LWGEOMFromWKB, and GEOS2POSTGIS. git-svn-id: http://svn.osgeo.org/postgis/trunk@1194 b70326c6-7e19-0410-871a-916f4a2858ee --- lwgeom/liblwgeom.h | 7 ++++++ lwgeom/lwgeom_geos.c | 5 ++++ lwgeom/lwgeom_inout.c | 58 ++++++++++++++++++++++++++----------------- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index 5ba027c4a..00e880d76 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -401,6 +401,13 @@ typedef struct { */ extern PG_LWGEOM *PG_LWGEOM_construct(char *serialized, int SRID, int wantbbox); +/* + * Evaluate with an heuristic if the provided PG_LWGEOM is worth + * caching a bbox + */ +char is_worth_caching_pglwgeom_bbox(PG_LWGEOM *); +char is_worth_caching_lwgeom_bbox(LWGEOM *); + /* * Use this macro to extract the char * required * by most functions from an PG_LWGEOM struct. diff --git a/lwgeom/lwgeom_geos.c b/lwgeom/lwgeom_geos.c index 35c0c8c49..8642d5f3a 100644 --- a/lwgeom/lwgeom_geos.c +++ b/lwgeom/lwgeom_geos.c @@ -2198,6 +2198,11 @@ GEOS2POSTGIS(Geometry *geom, char want3d) lwnotice("GEOS2POSTGIS: lwgeom_from_geometry returned a %s", lwgeom_summary(lwgeom, 0)); #endif + if ( is_worth_caching_lwgeom_bbox(lwgeom) ) + { + lwgeom_addBBOX(lwgeom); + } + size = lwgeom_serialize_size(lwgeom); #ifdef DEBUG_GEOS2POSTGIS diff --git a/lwgeom/lwgeom_inout.c b/lwgeom/lwgeom_inout.c index bf2cc7f82..b50e1355f 100644 --- a/lwgeom/lwgeom_inout.c +++ b/lwgeom/lwgeom_inout.c @@ -65,6 +65,7 @@ Datum LWGEOM_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); char *semicolonLoc,start; + PG_LWGEOM *ret; //determine if its WKB or WKT @@ -78,29 +79,16 @@ Datum LWGEOM_in(PG_FUNCTION_ARGS) start=semicolonLoc[1]; // one in } - // this is included just for redundancy (new parser can handle wkt and wkb) + // will handle both EWKB and EWKT + ret = (PG_LWGEOM *)parse_lwgeom_wkt(str); - if ( ( (start >= '0') && (start <= '9') ) || - ( (start >= 'A') && (start <= 'F') )) + if ( is_worth_caching_pglwgeom_bbox(ret) ) { - //its WKB - //PG_RETURN_POINTER(parse_lwgeom_serialized_form(str)); - // this function handles wkt and wkb (in hex-form) - PG_RETURN_POINTER( parse_lwgeom_wkt(str) ); - } - else if ( (start == 'P') || (start == 'L') || (start == 'M') || - (start == 'G') || (start == 'p') || (start == 'l') || - (start == 'm') || (start == 'g')) - { - // its WKT - // this function handles wkt and wkb (in hex-form) - PG_RETURN_POINTER( parse_lwgeom_wkt(str) ); - } - else - { - elog(ERROR,"couldnt determine if input lwgeom is WKB or WKT"); - PG_RETURN_NULL(); + ret = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1( + LWGEOM_addBBOX, PointerGetDatum(ret))); } + + PG_RETURN_POINTER(ret); } @@ -205,6 +193,12 @@ Datum LWGEOMFromWKB(PG_FUNCTION_ARGS) pfree(wkb_srid_hexized); + if ( is_worth_caching_pglwgeom_bbox(lwgeom) ) + { + lwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1( + LWGEOM_addBBOX, PointerGetDatum(lwgeom))); + } + #ifdef DEBUG elog(NOTICE, "LWGEOMFromWKB returning %s", unparse_WKB(SERIALIZED_FORM(lwgeom), pg_alloc, pg_free, -1)); #endif @@ -284,8 +278,6 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } - - // puts a bbox inside the geometry PG_FUNCTION_INFO_V1(LWGEOM_addBBOX); Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS) @@ -310,7 +302,13 @@ Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS) //elog(NOTICE,"LWGEOM_addBBOX -- giving it a bbox"); //construct new one - getbox2d_p(SERIALIZED_FORM(lwgeom), &box); + if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), &box) ) + { + // Empty geom, no bbox to add + result = palloc (lwgeom->size); + memcpy(result, lwgeom, lwgeom->size); + PG_RETURN_POINTER(result); + } old_type = lwgeom->type; size = lwgeom->size+sizeof(BOX2DFLOAT4); @@ -334,6 +332,20 @@ Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } +char +is_worth_caching_pglwgeom_bbox(PG_LWGEOM *in) +{ + if ( TYPE_GETTYPE(in->type) == POINTTYPE ) return false; + return true; +} + +char +is_worth_caching_lwgeom_bbox(LWGEOM *in) +{ + if ( TYPE_GETTYPE(in->type) == POINTTYPE ) return false; + return true; +} + // removes a bbox from a geometry PG_FUNCTION_INFO_V1(LWGEOM_dropBBOX); Datum LWGEOM_dropBBOX(PG_FUNCTION_ARGS) -- 2.40.0