diff -urN postgis-cvs.vanilla/lwgeom/lwgeom_box2dfloat4.c postgis-cvs/lwgeom/lwgeom_box2dfloat4.c --- postgis-cvs.vanilla/lwgeom/lwgeom_box2dfloat4.c 2004-10-28 17:13:30.000000000 +0100 +++ postgis-cvs/lwgeom/lwgeom_box2dfloat4.c 2005-01-11 09:34:40.000000000 +0000 @@ -157,9 +157,6 @@ /* box_overleft - is the right edge of box1 to the left of * the right edge of box2? - * - * This is "less than or equal" for the end of a time range, - * when time ranges are stored as rectangles. */ PG_FUNCTION_INFO_V1(BOX2D_overleft); Datum BOX2D_overleft(PG_FUNCTION_ARGS) @@ -194,9 +191,6 @@ /* box_overright - is the left edge of box1 to the right of * the left edge of box2? - * - * This is "greater than or equal" for time ranges, when time ranges - * are stored as rectangles. */ PG_FUNCTION_INFO_V1(BOX2D_overright); Datum BOX2D_overright(PG_FUNCTION_ARGS) @@ -207,6 +201,52 @@ PG_RETURN_BOOL(FPge(box1->xmin, box2->xmin)); } +/* box_overbelow - is the bottom edge of box1 below + * the bottom edge of box2? + */ + PG_FUNCTION_INFO_V1(BOX2D_overbelow); +Datum BOX2D_overbelow(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPle(box1->ymin, box2->ymin)); +} + +/* box_below - is box1 strictly below box2? + */ + PG_FUNCTION_INFO_V1(BOX2D_below); +Datum BOX2D_below(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPlt(box1->ymax, box2->ymin)); +} + +/* box_above - is box1 strictly above box2? + */ + PG_FUNCTION_INFO_V1(BOX2D_above); +Datum BOX2D_above(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPgt(box1->ymin, box2->ymax)); +} + +/* box_overabove - is the top edge of box1 above + * the top edge of box2? + */ + PG_FUNCTION_INFO_V1(BOX2D_overabove); +Datum BOX2D_overabove(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPge(box1->ymax, box2->ymax)); +} + /* box_contained - is box1 contained by box2? */ PG_FUNCTION_INFO_V1(BOX2D_contained); diff -urN postgis-cvs.vanilla/lwgeom/lwgeom_gist.c postgis-cvs/lwgeom/lwgeom_gist.c --- postgis-cvs.vanilla/lwgeom/lwgeom_gist.c 2004-10-25 18:07:09.000000000 +0100 +++ postgis-cvs/lwgeom/lwgeom_gist.c 2005-01-11 11:22:44.000000000 +0000 @@ -7,7 +7,6 @@ #include "postgres.h" #include "access/gist.h" #include "access/itup.h" -#include "access/rtree.h" #include "fmgr.h" #include "utils/elog.h" @@ -32,6 +31,10 @@ Datum LWGEOM_left(PG_FUNCTION_ARGS); Datum LWGEOM_right(PG_FUNCTION_ARGS); Datum LWGEOM_overright(PG_FUNCTION_ARGS); +Datum LWGEOM_overbelow(PG_FUNCTION_ARGS); +Datum LWGEOM_below(PG_FUNCTION_ARGS); +Datum LWGEOM_above(PG_FUNCTION_ARGS); +Datum LWGEOM_overabove(PG_FUNCTION_ARGS); Datum LWGEOM_contained(PG_FUNCTION_ARGS); Datum LWGEOM_contain(PG_FUNCTION_ARGS); Datum LWGEOM_gist_compress(PG_FUNCTION_ARGS); @@ -56,8 +59,22 @@ int counter_intern = 0; +// GiST strategies (modified from src/include/access/rtree.h) +#define RTLeftStrategyNumber 1 +#define RTOverLeftStrategyNumber 2 +#define RTOverlapStrategyNumber 3 +#define RTOverRightStrategyNumber 4 +#define RTRightStrategyNumber 5 +#define RTSameStrategyNumber 6 +#define RTContainsStrategyNumber 7 +#define RTContainedByStrategyNumber 8 +#define RTOverBelowStrategyNumber 9 +#define RTBelowStrategyNumber 10 +#define RTAboveStrategyNumber 11 +#define RTOverAboveStrategyNumber 12 -// all the lwgeom_ + +// all the lwgeom_ // work the same. // 1. get lwgeom1 // 2. get lwgeom2 @@ -216,6 +233,118 @@ } +PG_FUNCTION_INFO_V1(LWGEOM_overbelow); +Datum LWGEOM_overbelow(PG_FUNCTION_ARGS) +{ + char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + bool result; + BOX2DFLOAT4 box1; + BOX2DFLOAT4 box2; + +#ifdef DEBUG_CALLS + elog(NOTICE,"GIST: LWGEOM_overbelow --entry"); +#endif + + if ( ! (getbox2d_p(lwgeom1+4, &box1) && getbox2d_p(lwgeom2+4, &box2)) ) + { + PG_RETURN_BOOL(FALSE); + } + + + result = DatumGetBool(DirectFunctionCall2(BOX2D_overbelow, + PointerGetDatum(&box1), PointerGetDatum(&box2))); + + PG_FREE_IF_COPY(lwgeom1, 0); + PG_FREE_IF_COPY(lwgeom2, 1); + + PG_RETURN_BOOL(result); +} + +PG_FUNCTION_INFO_V1(LWGEOM_below); +Datum LWGEOM_below(PG_FUNCTION_ARGS) +{ + char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + bool result; + BOX2DFLOAT4 box1; + BOX2DFLOAT4 box2; + +#ifdef DEBUG_CALLS + elog(NOTICE,"GIST: LWGEOM_below --entry"); +#endif + + if ( ! (getbox2d_p(lwgeom1+4, &box1) && getbox2d_p(lwgeom2+4, &box2)) ) + { + PG_RETURN_BOOL(FALSE); + } + + result = DatumGetBool(DirectFunctionCall2(BOX2D_below, + PointerGetDatum(&box1), PointerGetDatum(&box2))); + + PG_FREE_IF_COPY(lwgeom1, 0); + PG_FREE_IF_COPY(lwgeom2, 1); + + PG_RETURN_BOOL(result); +} + + +PG_FUNCTION_INFO_V1(LWGEOM_above); +Datum LWGEOM_above(PG_FUNCTION_ARGS) +{ + char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + bool result; + BOX2DFLOAT4 box1; + BOX2DFLOAT4 box2; + +#ifdef DEBUG_CALLS + elog(NOTICE,"GIST: LWGEOM_above --entry"); +#endif + + if ( ! (getbox2d_p(lwgeom1+4, &box1) && getbox2d_p(lwgeom2+4, &box2)) ) + { + PG_RETURN_BOOL(FALSE); + } + + result = DatumGetBool(DirectFunctionCall2(BOX2D_above, + PointerGetDatum(&box1), PointerGetDatum(&box2))); + + PG_FREE_IF_COPY(lwgeom1, 0); + PG_FREE_IF_COPY(lwgeom2, 1); + + PG_RETURN_BOOL(result); +} + + +PG_FUNCTION_INFO_V1(LWGEOM_overabove); +Datum LWGEOM_overabove(PG_FUNCTION_ARGS) +{ + char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + bool result; + BOX2DFLOAT4 box1; + BOX2DFLOAT4 box2; + +#ifdef DEBUG_CALLS + elog(NOTICE,"GIST: LWGEOM_overabove --entry"); +#endif + + if ( ! (getbox2d_p(lwgeom1+4, &box1) && getbox2d_p(lwgeom2+4, &box2)) ) + { + PG_RETURN_BOOL(FALSE); + } + + result = DatumGetBool(DirectFunctionCall2(BOX2D_overabove, + PointerGetDatum(&box1), PointerGetDatum(&box2))); + + PG_FREE_IF_COPY(lwgeom1, 0); + PG_FREE_IF_COPY(lwgeom2, 1); + + PG_RETURN_BOOL(result); +} + + PG_FUNCTION_INFO_V1(LWGEOM_contained); Datum LWGEOM_contained(PG_FUNCTION_ARGS) { @@ -482,6 +611,14 @@ case RTRightStrategyNumber: retval = DatumGetBool( DirectFunctionCall2( BOX2D_overright, PointerGetDatum(key), PointerGetDatum(query) ) ); break; + case RTOverBelowStrategyNumber: + case RTBelowStrategyNumber: + retval = DatumGetBool( DirectFunctionCall2( BOX2D_overbelow, PointerGetDatum(key), PointerGetDatum(query) ) ); + break; + case RTAboveStrategyNumber: + case RTOverAboveStrategyNumber: + retval = DatumGetBool( DirectFunctionCall2( BOX2D_overabove, PointerGetDatum(key), PointerGetDatum(query) ) ); + break; case RTSameStrategyNumber: case RTContainsStrategyNumber: retval = DatumGetBool( DirectFunctionCall2( BOX2D_contain, PointerGetDatum(key), PointerGetDatum(query) ) ); @@ -539,6 +676,18 @@ case RTRightStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(BOX2D_right, PointerGetDatum(key), PointerGetDatum(query))); break; + case RTOverBelowStrategyNumber: + retval = DatumGetBool(DirectFunctionCall2(BOX2D_overbelow, PointerGetDatum(key), PointerGetDatum(query))); + break; + case RTBelowStrategyNumber: + retval = DatumGetBool(DirectFunctionCall2(BOX2D_below, PointerGetDatum(key), PointerGetDatum(query))); + break; + case RTAboveStrategyNumber: + retval = DatumGetBool(DirectFunctionCall2(BOX2D_above, PointerGetDatum(key), PointerGetDatum(query))); + break; + case RTOverAboveStrategyNumber: + retval = DatumGetBool(DirectFunctionCall2(BOX2D_overabove, PointerGetDatum(key), PointerGetDatum(query))); + break; case RTSameStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(BOX2D_same, PointerGetDatum(key), PointerGetDatum(query))); break; diff -urN postgis-cvs.vanilla/lwgeom/lwgeom_pg.h postgis-cvs/lwgeom/lwgeom_pg.h --- postgis-cvs.vanilla/lwgeom/lwgeom_pg.h 2005-01-07 14:20:14.000000000 +0000 +++ postgis-cvs/lwgeom/lwgeom_pg.h 2005-01-11 09:33:05.000000000 +0000 @@ -36,6 +36,10 @@ Datum BOX2D_left(PG_FUNCTION_ARGS); Datum BOX2D_right(PG_FUNCTION_ARGS); Datum BOX2D_overright(PG_FUNCTION_ARGS); +Datum BOX2D_overbelow(PG_FUNCTION_ARGS); +Datum BOX2D_below(PG_FUNCTION_ARGS); +Datum BOX2D_above(PG_FUNCTION_ARGS); +Datum BOX2D_overabove(PG_FUNCTION_ARGS); Datum BOX2D_contained(PG_FUNCTION_ARGS); Datum BOX2D_contain(PG_FUNCTION_ARGS); Datum BOX2D_intersects(PG_FUNCTION_ARGS); diff -urN postgis-cvs.vanilla/lwgeom/lwgeom.sql.in postgis-cvs/lwgeom/lwgeom.sql.in --- postgis-cvs.vanilla/lwgeom/lwgeom.sql.in 2004-08-17 16:27:47.000000000 +0100 +++ postgis-cvs/lwgeom/lwgeom.sql.in 2005-01-11 10:00:03.000000000 +0000 @@ -76,6 +76,26 @@ AS '@MODULE_FILENAME@' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION box2d_overbelow(box2d, box2d) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION box2d_below(box2d, box2d) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION box2d_above(box2d, box2d) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION box2d_overabove(box2d, box2d) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + CREATEFUNCTION box2d_contain(box2d, box2d) RETURNS bool AS '@MODULE_FILENAME@' @@ -108,6 +128,18 @@ RESTRICT = positionsel, JOIN = positionjoinsel ); +CREATE OPERATOR <<| ( + LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_below, + COMMUTATOR = '|>>', + RESTRICT = positionsel, JOIN = positionjoinsel +); + +CREATE OPERATOR &<| ( + LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_overbelow, + COMMUTATOR = '|&>', + RESTRICT = positionsel, JOIN = positionjoinsel +); + CREATE OPERATOR && ( LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_overlap, COMMUTATOR = '&&', @@ -126,6 +158,18 @@ RESTRICT = positionsel, JOIN = positionjoinsel ); +CREATE OPERATOR |&> ( + LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_overabove, + COMMUTATOR = '&<|', + RESTRICT = positionsel, JOIN = positionjoinsel +); + +CREATE OPERATOR |>> ( + LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_above, + COMMUTATOR = '<<|', + RESTRICT = positionsel, JOIN = positionjoinsel +); + CREATE OPERATOR ~= ( LEFTARG = box2d, RIGHTARG = box2d, PROCEDURE = box2d_same, COMMUTATOR = '~=', @@ -158,6 +202,16 @@ AS '@MODULE_FILENAME@' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION lwgeom_overabove(lwgeom, lwgeom) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION lwgeom_overbelow(lwgeom, lwgeom) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + CREATEFUNCTION lwgeom_left(lwgeom, lwgeom) RETURNS bool AS '@MODULE_FILENAME@' @@ -168,6 +222,16 @@ AS '@MODULE_FILENAME@' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION lwgeom_above(lwgeom, lwgeom) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION lwgeom_below(lwgeom, lwgeom) + RETURNS bool + AS '@MODULE_FILENAME@' + LANGUAGE 'C' WITH (isstrict,iscachable); + CREATEFUNCTION lwgeom_contain(lwgeom, lwgeom) RETURNS bool AS '@MODULE_FILENAME@' diff -urN postgis-cvs.vanilla/lwgeom/lwpostgis.sql.in postgis-cvs/lwgeom/lwpostgis.sql.in --- postgis-cvs.vanilla/lwgeom/lwpostgis.sql.in 2005-01-07 18:32:57.000000000 +0000 +++ postgis-cvs/lwgeom/lwpostgis.sql.in 2005-01-11 11:28:25.000000000 +0000 @@ -444,6 +444,16 @@ AS '@MODULE_FILENAME@', 'LWGEOM_overright' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION geometry_overabove(geometry, geometry) + RETURNS bool + AS '@MODULE_FILENAME@', 'LWGEOM_overabove' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION geometry_overbelow(geometry, geometry) + RETURNS bool + AS '@MODULE_FILENAME@', 'LWGEOM_overbelow' + LANGUAGE 'C' WITH (isstrict,iscachable); + CREATEFUNCTION geometry_left(geometry, geometry) RETURNS bool AS '@MODULE_FILENAME@', 'LWGEOM_left' @@ -454,6 +464,16 @@ AS '@MODULE_FILENAME@', 'LWGEOM_right' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION geometry_above(geometry, geometry) + RETURNS bool + AS '@MODULE_FILENAME@', 'LWGEOM_above' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION geometry_below(geometry, geometry) + RETURNS bool + AS '@MODULE_FILENAME@', 'LWGEOM_below' + LANGUAGE 'C' WITH (isstrict,iscachable); + CREATEFUNCTION geometry_contain(geometry, geometry) RETURNS bool AS '@MODULE_FILENAME@', 'LWGEOM_contain' @@ -488,6 +508,18 @@ RESTRICT = positionsel, JOIN = positionjoinsel ); +CREATE OPERATOR <<| ( + LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_below, + COMMUTATOR = '|>>', + RESTRICT = positionsel, JOIN = positionjoinsel +); + +CREATE OPERATOR &<| ( + LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_overbelow, + COMMUTATOR = '|&>', + RESTRICT = positionsel, JOIN = positionjoinsel +); + CREATE OPERATOR && ( LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_overlap, COMMUTATOR = '&&', @@ -506,6 +538,18 @@ RESTRICT = positionsel, JOIN = positionjoinsel ); +CREATE OPERATOR |>& ( + LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_overabove, + COMMUTATOR = '&<|', + RESTRICT = positionsel, JOIN = positionjoinsel +); + +CREATE OPERATOR |>> ( + LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_above, + COMMUTATOR = '<<|', + RESTRICT = positionsel, JOIN = positionjoinsel +); + CREATE OPERATOR ~= ( LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_same, COMMUTATOR = '~=', @@ -638,6 +682,35 @@ WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' AND c.oprname = '@'; +-- box_overbelow +INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) + SELECT am.oid, opcl.oid, c.opoid, 9 + FROM pg_am am, pg_opclass opcl, rt_ops_tmp c + WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' + AND c.oprname = '&<|'; + +-- box_below +INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) + SELECT am.oid, opcl.oid, c.opoid, 10 + FROM pg_am am, pg_opclass opcl, rt_ops_tmp c + WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' + AND c.oprname = '<<|'; + +-- box_above +INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) + SELECT am.oid, opcl.oid, c.opoid, 11 + FROM pg_am am, pg_opclass opcl, rt_ops_tmp c + WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' + AND c.oprname = '|>>'; + +-- box_overabove +INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) + SELECT am.oid, opcl.oid, c.opoid, 12 + FROM pg_am am, pg_opclass opcl, rt_ops_tmp c + WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' + AND c.oprname = '|>&'; + + DROP TABLE rt_ops_tmp; -- @@ -782,8 +855,45 @@ and opcname = 'gist_geometry_ops' and c.oprname = '@'; +-- poly_overbelow +INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) + SELECT opcl.oid, 9, true, c.opoid + FROM pg_opclass opcl, rt_ops_tmp c + WHERE + opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') + and opcname = 'gist_geometry_ops' + and c.oprname = '&<|'; + +-- poly_below +INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) + SELECT opcl.oid, 10, true, c.opoid + FROM pg_opclass opcl, rt_ops_tmp c + WHERE + opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') + and opcname = 'gist_geometry_ops' + and c.oprname = '<<|'; + +-- poly_above +INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) + SELECT opcl.oid, 11, true, c.opoid + FROM pg_opclass opcl, rt_ops_tmp c + WHERE + opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') + and opcname = 'gist_geometry_ops' + and c.oprname = '|>>'; + +-- poly_overabove +INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) + SELECT opcl.oid, 12, true, c.opoid + FROM pg_opclass opcl, rt_ops_tmp c + WHERE + opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') + and opcname = 'gist_geometry_ops' + and c.oprname = '|>&'; + DROP TABLE rt_ops_tmp; + -- add the entries to amproc for the support methods -- note the amprocnum numbers associated with each are specific! INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) @@ -858,7 +968,11 @@ OPERATOR 6 ~= RECHECK, OPERATOR 7 ~ RECHECK, OPERATOR 8 @ RECHECK, - FUNCTION 1 LWGEOM_gist_consistent (internal, geometry, int4), + OPERATOR 9 &<| RECHECK, + OPERATOR 10 <<| RECHECK, + OPERATOR 11 |>> RECHECK, + OPERATOR 12 |>& RECHECK, + FUNCTION 1 LWGEOM_gist_consistent (internal, geometry, int4), FUNCTION 2 LWGEOM_gist_union (bytea, internal), FUNCTION 3 LWGEOM_gist_compress (internal), FUNCTION 4 LWGEOM_gist_decompress (internal),