2004-04-26 23:05:20 +00:00
# include "postgres.h"
# include <math.h>
# include <float.h>
# include <string.h>
# include <stdio.h>
# include <errno.h>
# include "access/gist.h"
# include "access/itup.h"
# include "access/rtree.h"
# include "fmgr.h"
# include "utils/elog.h"
# include "lwgeom.h"
# include "stringBuffer.h"
2004-04-29 18:44:36 +00:00
// implementation GiST support and basic LWGEOM operations (like &&)
2004-04-26 23:05:20 +00:00
//#define DEBUG
2004-08-23 08:32:14 +00:00
//#define DEBUG_GIST
2004-04-26 23:05:20 +00:00
//#define DEBUG_GIST2
//#define DEBUG_GIST3
//#define DEBUG_GIST4
//#define DEBUG_GIST5
//#define DEBUG_GIST6
Datum lwgeom_same ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_overlap ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_overleft ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_left ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_right ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_overright ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_contained ( PG_FUNCTION_ARGS ) ;
Datum lwgeom_contain ( PG_FUNCTION_ARGS ) ;
static float size_box2d ( Datum box ) ;
static bool lwgeom_rtree_internal_consistent ( BOX2DFLOAT4 * key , BOX2DFLOAT4 * query , StrategyNumber strategy ) ;
static bool lwgeom_rtree_leaf_consistent ( BOX2DFLOAT4 * key , BOX2DFLOAT4 * query , StrategyNumber strategy ) ;
2004-04-26 23:15:19 +00:00
2004-04-29 18:44:36 +00:00
// for debugging
2004-04-26 23:05:20 +00:00
int counter_leaf = 0 ;
int counter_intern = 0 ;
// all the lwgeom_<same,overlpa,overleft,left,right,overright,contained,contain>
// work the same.
// 1. get lwgeom1
// 2. get lwgeom2
// 3. get box3d for lwgeom1
// 4. get box3d for lwgeom2
// 5. convert box3d (for lwgeom1) to BOX2DFLOAT4
// 6. convert box3d (for lwgeom2) to BOX2DFLOAT4
// 7. call the appropriate BOX2DFLOAT4 function
// 8. return result;
// lwgeom_same(lwgeom1, lwgeom2)
PG_FUNCTION_INFO_V1 ( lwgeom_same ) ;
Datum lwgeom_same ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_same --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_same ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_overlap ) ;
Datum lwgeom_overlap ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_overlap ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
2004-08-18 13:46:49 +00:00
# ifdef DEBUG
# ifdef DEBUG_GIST2
elog ( NOTICE , " GIST: lwgeom_overlap: \n (%f %f, %f %f) (%f %f %f %f) = %i " ,
box1 . xmin , box1 . ymax , box1 . xmax , box1 . ymax ,
box2 . xmin , box2 . ymax , box2 . xmax , box2 . ymax ,
result
) ;
# else
elog ( NOTICE , " GIST: lwgeom_overlap: call " ) ;
# endif
# endif
2004-04-26 23:05:20 +00:00
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_overleft ) ;
Datum lwgeom_overleft ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_overleft --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_overleft ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_left ) ;
Datum lwgeom_left ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_left --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_left ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_right ) ;
Datum lwgeom_right ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_right --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_right ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_overright ) ;
Datum lwgeom_overright ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_overright --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_overright ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_contained ) ;
Datum lwgeom_contained ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_contained --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_contained ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
PG_FUNCTION_INFO_V1 ( lwgeom_contain ) ;
Datum lwgeom_contain ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
char * lwgeom1 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 0 ) ) ;
char * lwgeom2 = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
bool result ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 box1 = getbox2d ( lwgeom1 + 4 ) ;
BOX2DFLOAT4 box2 = getbox2d ( lwgeom2 + 4 ) ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
elog ( NOTICE , " GIST: lwgeom_contain --entry " ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
result = DatumGetBool ( DirectFunctionCall2 ( box2d_contain ,
PointerGetDatum ( & box1 ) , PointerGetDatum ( & box2 ) ) ) ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
PG_FREE_IF_COPY ( lwgeom1 , 0 ) ;
2004-04-26 23:05:20 +00:00
PG_FREE_IF_COPY ( lwgeom2 , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
// These functions are taken from the postgis_gist_72.c file
PG_FUNCTION_INFO_V1 ( gist_lwgeom_compress ) ;
Datum gist_lwgeom_compress ( PG_FUNCTION_ARGS )
{
GISTENTRY * entry = ( GISTENTRY * ) PG_GETARG_POINTER ( 0 ) ;
GISTENTRY * retval ;
# ifdef DEBUG_GIST4
elog ( NOTICE , " GIST: gist_lwgeom_compress called on lwgeom " ) ;
# endif
if ( entry - > leafkey )
{
retval = palloc ( sizeof ( GISTENTRY ) ) ;
if ( DatumGetPointer ( entry - > key ) ! = NULL )
{
2004-08-18 13:46:49 +00:00
char * in ; // lwgeom serialized
2004-08-19 14:05:24 +00:00
BOX2DFLOAT4 * rr ;
2004-04-26 23:05:20 +00:00
2004-08-18 13:46:49 +00:00
// lwgeom serialized form
2004-08-19 14:05:24 +00:00
in = ( char * ) PG_DETOAST_DATUM ( entry - > key ) ;
2004-04-26 23:05:20 +00:00
if ( in = = NULL )
PG_RETURN_POINTER ( entry ) ;
2004-08-18 13:46:49 +00:00
// this is the EMPTY geometry
if ( lwgeom_getnumgeometries ( in + 4 ) = = 0 )
2004-04-26 23:05:20 +00:00
{
2004-04-29 18:44:36 +00:00
//elog(NOTICE,"found an empty geometry");
2004-04-26 23:05:20 +00:00
// dont bother adding this to the index
PG_RETURN_POINTER ( entry ) ;
}
2004-08-19 14:05:24 +00:00
rr = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
getbox2d_p ( in + 4 , rr ) ;
//memcpy(rr,&r,sizeof(BOX2DFLOAT4));
if ( ! finite ( rr - > xmin ) | |
! finite ( rr - > ymin ) | |
! finite ( rr - > xmax ) | |
! finite ( rr - > ymax ) )
2004-04-26 23:05:20 +00:00
{
2004-08-19 14:05:24 +00:00
elog ( NOTICE , " found infinite geometry " ) ;
pfree ( rr ) ;
PG_RETURN_POINTER ( entry ) ;
}
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST2
2004-08-19 14:05:24 +00:00
elog ( NOTICE , " GIST: gist_lwgeom_compress -- got box2d BOX(%.15g %.15g,%.15g %.15g) " , rr - > xmin , rr - > ymin , rr - > xmax , rr - > ymax ) ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-19 14:05:24 +00:00
//r = convert_box3d_to_box(&in->bvol);
2004-04-26 23:05:20 +00:00
2004-08-19 14:05:24 +00:00
if ( in ! = ( char * ) DatumGetPointer ( entry - > key ) )
{
pfree ( in ) ; // PG_FREE_IF_COPY
2004-04-26 23:05:20 +00:00
}
2004-08-19 14:05:24 +00:00
gistentryinit ( * retval , PointerGetDatum ( rr ) ,
entry - > rel , entry - > page ,
entry - > offset , sizeof ( BOX2DFLOAT4 ) ,
FALSE ) ;
2004-04-26 23:05:20 +00:00
}
else
{
2004-08-18 13:46:49 +00:00
gistentryinit ( * retval , ( Datum ) 0 , entry - > rel ,
entry - > page , entry - > offset , 0 , FALSE ) ;
2004-04-26 23:05:20 +00:00
}
}
else
{
retval = entry ;
}
PG_RETURN_POINTER ( retval ) ;
}
PG_FUNCTION_INFO_V1 ( gist_lwgeom_consistent ) ;
Datum gist_lwgeom_consistent ( PG_FUNCTION_ARGS )
{
2004-08-18 13:46:49 +00:00
GISTENTRY * entry = ( GISTENTRY * ) PG_GETARG_POINTER ( 0 ) ;
char * query ; // lwgeom serialized form
StrategyNumber strategy = ( StrategyNumber ) PG_GETARG_UINT16 ( 2 ) ;
// BOX thebox;
2004-04-26 23:05:20 +00:00
bool result ;
BOX2DFLOAT4 box ;
/*
2004-08-18 13:46:49 +00:00
* if entry is not leaf , use rtree_internal_consistent ,
* else use rtree_leaf_consistent
*/
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: gist_lwgeom_consistent called " ) ;
# endif
2004-08-18 13:46:49 +00:00
if ( ( ( Pointer * ) PG_GETARG_DATUM ( 1 ) ) = = NULL )
{
2004-04-26 23:05:20 +00:00
//elog(NOTICE,"gist_lwgeom_consistent:: got null query!");
PG_RETURN_BOOL ( false ) ; // null query - this is screwy!
}
query = ( char * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM ( 1 ) ) ;
2004-08-18 13:46:49 +00:00
if ( ! ( DatumGetPointer ( entry - > key ) ! = NULL & & query ) )
2004-04-26 23:05:20 +00:00
PG_RETURN_BOOL ( FALSE ) ;
//box3d = lw_geom_getBB(query+4);
//thebox = box3d_to_box2df(box3d);
//pfree(box3d);
2004-08-18 13:46:49 +00:00
//convert_box3d_to_box_p( &(query->bvol) , &thebox);
2004-04-26 23:05:20 +00:00
//thebox = getBOX2D_cache(query);
2004-08-18 13:46:49 +00:00
getbox2d_p ( query + 4 , & box ) ;
2004-04-26 23:05:20 +00:00
if ( GIST_LEAF ( entry ) )
2004-08-18 13:46:49 +00:00
result = lwgeom_rtree_leaf_consistent ( ( BOX2DFLOAT4 * )
DatumGetPointer ( entry - > key ) , & box , strategy ) ;
2004-04-26 23:05:20 +00:00
else
2004-08-18 13:46:49 +00:00
result = lwgeom_rtree_internal_consistent (
( BOX2DFLOAT4 * ) DatumGetPointer ( entry - > key ) ,
& box , strategy ) ;
2004-04-26 23:05:20 +00:00
//pfree(thebox);
PG_FREE_IF_COPY ( query , 1 ) ;
PG_RETURN_BOOL ( result ) ;
}
static bool lwgeom_rtree_internal_consistent ( BOX2DFLOAT4 * key ,
BOX2DFLOAT4 * query ,
StrategyNumber strategy )
{
2004-08-18 13:46:49 +00:00
bool retval ;
2004-04-26 23:05:20 +00:00
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: lwgeom_rtree_internal_consistent called with strategy=%i " , strategy ) ;
# endif
2004-08-18 13:46:49 +00:00
switch ( strategy ) {
2004-04-26 23:05:20 +00:00
case RTLeftStrategyNumber :
case RTOverLeftStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_overleft , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTOverlapStrategyNumber : //optimized for speed
retval = ( ( ( key - > xmax > = query - > xmax ) & &
( key - > xmin < = query - > xmax ) ) | |
( ( query - > xmax > = key - > xmax ) & &
( query - > xmin < = key - > xmax ) ) )
& &
( ( ( key - > ymax > = query - > ymax ) & &
( key - > ymin < = query - > ymax ) ) | |
( ( query - > ymax > = key - > ymax ) & &
( query - > ymin < = key - > ymax ) ) ) ;
# ifdef DEBUG_GIST5
2004-04-29 18:44:36 +00:00
//keep track and report info about how many times this is called
2004-04-26 23:05:20 +00:00
if ( counter_intern = = 0 )
{
elog ( NOTICE , " search bounding box is: <%.16g %.16g,%.16g %.16g> - size box2d= %i " ,
query - > xmin , query - > ymin , query - > xmax , query - > ymax , sizeof ( BOX2DFLOAT4 ) ) ;
}
elog ( NOTICE , " %i:(int)<%.8g %.8g,%.8g %.8g>&&<%.8g %.8g,%.8g %.8g> %i " , counter_intern , key - > xmin , key - > ymin , key - > xmax , key - > ymax ,
query - > xmin , query - > ymin , query - > xmax , query - > ymax , ( int ) retval ) ;
# endif
counter_intern + + ;
return ( retval ) ;
break ;
case RTOverRightStrategyNumber :
case RTRightStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_overright , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTSameStrategyNumber :
case RTContainsStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_contain , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTContainedByStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_overlap , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
default :
retval = FALSE ;
}
return ( retval ) ;
}
static bool lwgeom_rtree_leaf_consistent ( BOX2DFLOAT4 * key ,
BOX2DFLOAT4 * query ,
StrategyNumber strategy )
{
bool retval ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: rtree_leaf_consist called with strategy=%i " , strategy ) ;
# endif
switch ( strategy )
{
case RTLeftStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_left , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTOverLeftStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_overleft , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTOverlapStrategyNumber : //optimized for speed
retval = ( ( ( key - > xmax > = query - > xmax ) & &
( key - > xmin < = query - > xmax ) ) | |
( ( query - > xmax > = key - > xmax ) & &
( query - > xmin < = key - > xmax ) ) )
& &
( ( ( key - > ymax > = query - > ymax ) & &
( key - > ymin < = query - > ymax ) ) | |
( ( query - > ymax > = key - > ymax ) & &
( query - > ymin < = key - > ymax ) ) ) ;
# ifdef DEBUG_GIST5
2004-04-29 18:44:36 +00:00
//keep track and report info about how many times this is called
2004-04-26 23:05:20 +00:00
elog ( NOTICE , " %i:gist test (leaf) <%.6g %.6g,%.6g %.6g> && <%.6g %.6g,%.6g %.6g> --> %i " , counter_leaf , key - > xmin , key - > ymin , key - > xmax , key - > ymax ,
query - > xmin , query - > ymin , query - > xmax , query - > ymax , ( int ) retval ) ;
# endif
counter_leaf + + ;
return ( retval ) ;
break ;
case RTOverRightStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_overright , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTRightStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_right , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTSameStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_same , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTContainsStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_contain , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
case RTContainedByStrategyNumber :
retval = DatumGetBool ( DirectFunctionCall2 ( box2d_contained , PointerGetDatum ( key ) , PointerGetDatum ( query ) ) ) ;
break ;
default :
retval = FALSE ;
}
return ( retval ) ;
}
PG_FUNCTION_INFO_V1 ( gist_rtree_decompress ) ;
Datum gist_rtree_decompress ( PG_FUNCTION_ARGS )
{
# ifdef DEBUG_GIST
2004-08-18 13:46:49 +00:00
static unsigned int counter2 = 0 ;
elog ( NOTICE , " GIST: gist_rtree_decompress called %i " , counter2 ) ;
counter2 + + ;
2004-04-26 23:05:20 +00:00
# endif
2004-08-18 13:46:49 +00:00
PG_RETURN_POINTER ( PG_GETARG_POINTER ( 0 ) ) ;
2004-04-26 23:05:20 +00:00
}
/*
2004-08-18 13:46:49 +00:00
* The GiST Union method for boxes
* returns the minimal bounding box that encloses all the entries in entryvec
*/
2004-04-26 23:05:20 +00:00
PG_FUNCTION_INFO_V1 ( lwgeom_box_union ) ;
Datum lwgeom_box_union ( PG_FUNCTION_ARGS )
{
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-08-18 13:46:49 +00:00
bytea * entryvec = ( bytea * ) PG_GETARG_POINTER ( 0 ) ;
# else
GistEntryVector * entryvec = ( GistEntryVector * ) PG_GETARG_POINTER ( 0 ) ;
# endif
2004-04-26 23:05:20 +00:00
int * sizep = ( int * ) PG_GETARG_POINTER ( 1 ) ;
int numranges ,
i ;
2004-08-18 13:46:49 +00:00
BOX2DFLOAT4 * cur ,
2004-04-26 23:05:20 +00:00
* pageunion ;
2004-08-18 13:46:49 +00:00
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: lwgeom_box_union called \n " ) ;
# endif
2004-04-26 23:05:20 +00:00
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
numranges = ( VARSIZE ( entryvec ) - VARHDRSZ ) / sizeof ( GISTENTRY ) ;
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ 0 ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
numranges = entryvec - > n ;
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ 0 ] . key ) ;
# endif
pageunion = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
2004-04-26 23:05:20 +00:00
memcpy ( ( void * ) pageunion , ( void * ) cur , sizeof ( BOX2DFLOAT4 ) ) ;
for ( i = 1 ; i < numranges ; i + + )
{
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ i ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ i ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
if ( pageunion - > xmax < cur - > xmax )
pageunion - > xmax = cur - > xmax ;
if ( pageunion - > xmin > cur - > xmin )
pageunion - > xmin = cur - > xmin ;
if ( pageunion - > ymax < cur - > ymax )
pageunion - > ymax = cur - > ymax ;
if ( pageunion - > ymin > cur - > ymin )
pageunion - > ymin = cur - > ymin ;
}
* sizep = sizeof ( BOX2DFLOAT4 ) ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: gbox_union called with numranges=%i pageunion is: <%.16g %.16g,%.16g %.16g> " , numranges , pageunion - > xmin , pageunion - > ymin , pageunion - > xmax , pageunion - > ymax ) ;
# endif
PG_RETURN_POINTER ( pageunion ) ;
}
2004-04-29 18:44:36 +00:00
// size of a box is width*height
// we do this in double precision because width and height can be very very small
// and it gives screwy results
2004-04-26 23:05:20 +00:00
static float size_box2d ( Datum box2d )
{
float result ;
if ( DatumGetPointer ( box2d ) ! = NULL )
{
BOX2DFLOAT4 * a = ( BOX2DFLOAT4 * ) DatumGetPointer ( box2d ) ;
if ( a = = ( BOX2DFLOAT4 * ) NULL | | a - > xmax < = a - > xmin | | a - > ymax < = a - > ymin )
result = ( float ) 0.0 ;
else
{
result = ( ( ( double ) a - > xmax ) - ( ( double ) a - > xmin ) ) * ( ( ( double ) a - > ymax ) - ( ( double ) a - > ymin ) ) ;
}
// result= (float) ((a->xmax - a->xmin) * (a->ymax - a->ymin));
}
else
result = ( float ) 0.0 ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: size_box2d called - returning %.15g " , result ) ;
# endif
return result ;
}
2004-04-29 18:44:36 +00:00
// size of a box is width*height
// we do this in double precision because width and height can be very very small
// and it gives screwy results
// this version returns a double
2004-04-26 23:05:20 +00:00
static double size_box2d_double ( Datum box2d ) ;
static double size_box2d_double ( Datum box2d )
{
double result ;
if ( DatumGetPointer ( box2d ) ! = NULL )
{
BOX2DFLOAT4 * a = ( BOX2DFLOAT4 * ) DatumGetPointer ( box2d ) ;
if ( a = = ( BOX2DFLOAT4 * ) NULL | | a - > xmax < = a - > xmin | | a - > ymax < = a - > ymin )
result = ( double ) 0.0 ;
else
{
result = ( ( ( double ) a - > xmax ) - ( ( double ) a - > xmin ) ) * ( ( ( double ) a - > ymax ) - ( ( double ) a - > ymin ) ) ;
}
// result= (float) ((a->xmax - a->xmin) * (a->ymax - a->ymin));
}
else
result = ( double ) 0.0 ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: size_box2d_double called - returning %.15g " , result ) ;
# endif
return result ;
}
/*
* * The GiST Penalty method for boxes
* * As in the R - tree paper , we use change in area as our penalty metric
*/
PG_FUNCTION_INFO_V1 ( lwgeom_box_penalty ) ;
Datum lwgeom_box_penalty ( PG_FUNCTION_ARGS )
{
GISTENTRY * origentry = ( GISTENTRY * ) PG_GETARG_POINTER ( 0 ) ;
GISTENTRY * newentry = ( GISTENTRY * ) PG_GETARG_POINTER ( 1 ) ;
float * result = ( float * ) PG_GETARG_POINTER ( 2 ) ;
Datum ud ;
double tmp1 ;
2004-08-18 13:46:49 +00:00
# ifdef DEBUG_GIST6
elog ( NOTICE , " GIST: lwgeom_box_penalty called " ) ;
# endif
2004-04-26 23:05:20 +00:00
ud = DirectFunctionCall2 ( box2d_union , origentry - > key , newentry - > key ) ;
tmp1 = size_box2d_double ( ud ) ;
if ( DatumGetPointer ( ud ) ! = NULL )
pfree ( DatumGetPointer ( ud ) ) ;
* result = tmp1 - size_box2d_double ( origentry - > key ) ;
/*
if ( ( * result < 0 ) & & ( * result > - 0.00001 ) )
* result = 0 ;
if ( ( * result > 0 ) & & ( * result < 0.00001 ) )
* result = 0 ;
*/
# ifdef DEBUG_GIST6
elog ( NOTICE , " GIST: lwgeom_box_penalty called and returning %.15g " , * result ) ;
if ( * result < 0 )
{
BOX2DFLOAT4 * a , * b , * c ;
a = ( BOX2DFLOAT4 * ) DatumGetPointer ( origentry - > key ) ;
b = ( BOX2DFLOAT4 * ) DatumGetPointer ( newentry - > key ) ;
c = ( BOX2DFLOAT4 * ) DatumGetPointer ( DirectFunctionCall2 ( box2d_union , origentry - > key , newentry - > key ) ) ;
//elog(NOTICE,"lwgeom_box_penalty -- a = <%.16g %.16g,%.16g %.16g>", a->xmin, a->ymin, a->xmax, a->ymax);
//elog(NOTICE,"lwgeom_box_penalty -- b = <%.16g %.16g,%.16g %.16g>", b->xmin, b->ymin, b->xmax, b->ymax);
//elog(NOTICE,"lwgeom_box_penalty -- c = <%.16g %.16g,%.16g %.16g>", c->xmin, c->ymin, c->xmax, c->ymax);
}
# endif
PG_RETURN_POINTER ( result ) ;
}
typedef struct {
BOX2DFLOAT4 * key ;
int pos ;
} KBsort ;
static int
compare_KB ( const void * a , const void * b ) {
BOX2DFLOAT4 * abox = ( ( KBsort * ) a ) - > key ;
BOX2DFLOAT4 * bbox = ( ( KBsort * ) b ) - > key ;
float sa = ( abox - > xmax - abox - > xmin ) * ( abox - > ymax - abox - > ymin ) ;
float sb = ( bbox - > xmax - bbox - > xmin ) * ( bbox - > ymax - bbox - > ymin ) ;
if ( sa = = sb ) return 0 ;
return ( sa > sb ) ? 1 : - 1 ;
}
/*
* * Equality method
*/
PG_FUNCTION_INFO_V1 ( lwgeom_gbox_same ) ;
Datum lwgeom_gbox_same ( PG_FUNCTION_ARGS )
{
BOX2DFLOAT4 * b1 = ( BOX2DFLOAT4 * ) PG_GETARG_POINTER ( 0 ) ;
BOX2DFLOAT4 * b2 = ( BOX2DFLOAT4 * ) PG_GETARG_POINTER ( 1 ) ;
bool * result = ( bool * ) PG_GETARG_POINTER ( 2 ) ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: lwgeom_gbox_same called " ) ;
# endif
if ( b1 & & b2 )
* result = DatumGetBool ( DirectFunctionCall2 ( box2d_same , PointerGetDatum ( b1 ) , PointerGetDatum ( b2 ) ) ) ;
else
* result = ( b1 = = NULL & & b2 = = NULL ) ? TRUE : FALSE ;
PG_RETURN_POINTER ( result ) ;
}
/*
* * The GiST PickSplit method
* * New linear algorithm , see ' New Linear Node Splitting Algorithm for R - tree ' ,
* * C . H . Ang and T . C . Tan
*/
PG_FUNCTION_INFO_V1 ( lwgeom_gbox_picksplit ) ;
Datum lwgeom_gbox_picksplit ( PG_FUNCTION_ARGS )
{
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
bytea * entryvec = ( bytea * ) PG_GETARG_POINTER ( 0 ) ;
2004-08-18 13:46:49 +00:00
# else
GistEntryVector * entryvec = ( GistEntryVector * ) PG_GETARG_POINTER ( 0 ) ;
# endif
2004-04-26 23:05:20 +00:00
GIST_SPLITVEC * v = ( GIST_SPLITVEC * ) PG_GETARG_POINTER ( 1 ) ;
OffsetNumber i ;
OffsetNumber * listL ,
* listR ,
* listB ,
* listT ;
BOX2DFLOAT4 * unionL ,
* unionR ,
* unionB ,
* unionT ;
int posL ,
posR ,
posB ,
posT ;
BOX2DFLOAT4 pageunion ;
BOX2DFLOAT4 * cur ;
char direction = ' ' ;
bool allisequal = true ;
OffsetNumber maxoff ;
int nbytes ;
# ifdef DEBUG_GIST
elog ( NOTICE , " GIST: lwgeom_gbox_picksplit called " ) ;
# endif
# ifdef DEBUG_GIST6
elog ( NOTICE , " GIST: lwgeom_gbox_picksplit called -- analysing " ) ;
# endif
posL = posR = posB = posT = 0 ;
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
maxoff = ( ( VARSIZE ( entryvec ) - VARHDRSZ ) / sizeof ( GISTENTRY ) ) - 1 ;
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ FirstOffsetNumber ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
maxoff = entryvec - > n - 1 ;
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ FirstOffsetNumber ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
memcpy ( ( void * ) & pageunion , ( void * ) cur , sizeof ( BOX2DFLOAT4 ) ) ;
# ifdef DEBUG_GIST6
elog ( NOTICE , " cur is: <%.16g %.16g,%.16g %.16g> " , cur - > xmin , cur - > ymin , cur - > xmax , cur - > ymax ) ;
# endif
/* find MBR */
for ( i = OffsetNumberNext ( FirstOffsetNumber ) ; i < = maxoff ; i = OffsetNumberNext ( i ) )
{
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-08-18 13:46:49 +00:00
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ i ] . key ) ;
# else
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ i ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
if ( allisequal = = true & & (
pageunion . xmax ! = cur - > xmax | |
pageunion . ymax ! = cur - > ymax | |
pageunion . xmin ! = cur - > xmin | |
pageunion . ymin ! = cur - > ymin
) )
allisequal = false ;
if ( pageunion . xmax < cur - > xmax )
pageunion . xmax = cur - > xmax ;
if ( pageunion . xmin > cur - > xmin )
pageunion . xmin = cur - > xmin ;
if ( pageunion . ymax < cur - > ymax )
pageunion . ymax = cur - > ymax ;
if ( pageunion . ymin > cur - > ymin )
pageunion . ymin = cur - > ymin ;
}
# ifdef DEBUG_GIST6
elog ( NOTICE , " pageunion is: <%.16g %.16g,%.16g %.16g> " , pageunion . xmin , pageunion . ymin , pageunion . xmax , pageunion . ymax ) ;
# endif
nbytes = ( maxoff + 2 ) * sizeof ( OffsetNumber ) ;
listL = ( OffsetNumber * ) palloc ( nbytes ) ;
listR = ( OffsetNumber * ) palloc ( nbytes ) ;
unionL = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
unionR = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
if ( allisequal )
{
# ifdef DEBUG_GIST6
elog ( NOTICE , " AllIsEqual! " ) ;
# endif
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ OffsetNumberNext ( FirstOffsetNumber ) ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ OffsetNumberNext ( FirstOffsetNumber ) ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
if ( memcmp ( ( void * ) cur , ( void * ) & pageunion , sizeof ( BOX2DFLOAT4 ) ) = = 0 )
{
v - > spl_left = listL ;
v - > spl_right = listR ;
v - > spl_nleft = v - > spl_nright = 0 ;
memcpy ( ( void * ) unionL , ( void * ) & pageunion , sizeof ( BOX2DFLOAT4 ) ) ;
memcpy ( ( void * ) unionR , ( void * ) & pageunion , sizeof ( BOX2DFLOAT4 ) ) ;
for ( i = FirstOffsetNumber ; i < = maxoff ; i = OffsetNumberNext ( i ) )
{
if ( i < = ( maxoff - FirstOffsetNumber + 1 ) / 2 )
{
v - > spl_left [ v - > spl_nleft ] = i ;
v - > spl_nleft + + ;
}
else
{
v - > spl_right [ v - > spl_nright ] = i ;
v - > spl_nright + + ;
}
}
v - > spl_ldatum = PointerGetDatum ( unionL ) ;
v - > spl_rdatum = PointerGetDatum ( unionR ) ;
PG_RETURN_POINTER ( v ) ;
}
}
listB = ( OffsetNumber * ) palloc ( nbytes ) ;
listT = ( OffsetNumber * ) palloc ( nbytes ) ;
unionB = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
unionT = ( BOX2DFLOAT4 * ) palloc ( sizeof ( BOX2DFLOAT4 ) ) ;
# define ADDLIST( list, unionD, pos, num ) do { \
if ( pos ) { \
if ( unionD - > xmax < cur - > xmax ) unionD - > xmax = cur - > xmax ; \
if ( unionD - > xmin > cur - > xmin ) unionD - > xmin = cur - > xmin ; \
if ( unionD - > ymax < cur - > ymax ) unionD - > ymax = cur - > ymax ; \
if ( unionD - > ymin > cur - > ymin ) unionD - > ymin = cur - > ymin ; \
} else { \
memcpy ( ( void * ) unionD , ( void * ) cur , sizeof ( BOX2DFLOAT4 ) ) ; \
} \
list [ pos ] = num ; \
( pos ) + + ; \
} while ( 0 )
for ( i = FirstOffsetNumber ; i < = maxoff ; i = OffsetNumberNext ( i ) )
{
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ i ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
cur = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ i ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
if ( cur - > xmin - pageunion . xmin < pageunion . xmax - cur - > xmax )
ADDLIST ( listL , unionL , posL , i ) ;
else
ADDLIST ( listR , unionR , posR , i ) ;
if ( cur - > ymin - pageunion . ymin < pageunion . ymax - cur - > ymax )
ADDLIST ( listB , unionB , posB , i ) ;
else
ADDLIST ( listT , unionT , posT , i ) ;
}
# ifdef DEBUG_GIST6
elog ( NOTICE , " unionL is: <%.16g %.16g,%.16g %.16g> " , unionL - > xmin , unionL - > ymin , unionL - > xmax , unionL - > ymax ) ;
elog ( NOTICE , " unionR is: <%.16g %.16g,%.16g %.16g> " , unionR - > xmin , unionR - > ymin , unionR - > xmax , unionR - > ymax ) ;
elog ( NOTICE , " unionT is: <%.16g %.16g,%.16g %.16g> " , unionT - > xmin , unionT - > ymin , unionT - > xmax , unionT - > ymax ) ;
elog ( NOTICE , " unionB is: <%.16g %.16g,%.16g %.16g> " , unionB - > xmin , unionB - > ymin , unionB - > xmax , unionB - > ymax ) ;
# endif
/* bad disposition, sort by ascending and resplit */
if ( ( posR = = 0 | | posL = = 0 ) & & ( posT = = 0 | | posB = = 0 ) ) {
KBsort * arr = ( KBsort * ) palloc ( sizeof ( KBsort ) * maxoff ) ;
posL = posR = posB = posT = 0 ;
for ( i = FirstOffsetNumber ; i < = maxoff ; i = OffsetNumberNext ( i ) ) {
2004-08-19 06:15:58 +00:00
# if USE_VERSION < 80
2004-04-26 23:05:20 +00:00
arr [ i - 1 ] . key = ( BOX2DFLOAT4 * ) DatumGetPointer ( ( ( GISTENTRY * ) VARDATA ( entryvec ) ) [ i ] . key ) ;
2004-08-18 13:46:49 +00:00
# else
arr [ i - 1 ] . key = ( BOX2DFLOAT4 * ) DatumGetPointer ( entryvec - > vector [ i ] . key ) ;
# endif
2004-04-26 23:05:20 +00:00
arr [ i - 1 ] . pos = i ;
}
qsort ( arr , maxoff , sizeof ( KBsort ) , compare_KB ) ;
for ( i = FirstOffsetNumber ; i < = maxoff ; i = OffsetNumberNext ( i ) ) {
cur = arr [ i - 1 ] . key ;
if ( cur - > xmin - pageunion . xmin < pageunion . xmax - cur - > xmax )
ADDLIST ( listL , unionL , posL , arr [ i - 1 ] . pos ) ;
else if ( cur - > xmin - pageunion . xmin = = pageunion . xmax - cur - > xmax ) {
if ( posL > posR )
ADDLIST ( listR , unionR , posR , arr [ i - 1 ] . pos ) ;
else
ADDLIST ( listL , unionL , posL , arr [ i - 1 ] . pos ) ;
} else
ADDLIST ( listR , unionR , posR , arr [ i - 1 ] . pos ) ;
if ( cur - > ymin - pageunion . ymin < pageunion . ymax - cur - > ymax )
ADDLIST ( listB , unionB , posB , arr [ i - 1 ] . pos ) ;
else if ( cur - > ymin - pageunion . ymin = = pageunion . ymax - cur - > ymax ) {
if ( posB > posT )
ADDLIST ( listT , unionT , posT , arr [ i - 1 ] . pos ) ;
else
ADDLIST ( listB , unionB , posB , arr [ i - 1 ] . pos ) ;
} else
ADDLIST ( listT , unionT , posT , arr [ i - 1 ] . pos ) ;
}
pfree ( arr ) ;
}
/* which split more optimal? */
if ( Max ( posL , posR ) < Max ( posB , posT ) )
direction = ' x ' ;
else if ( Max ( posL , posR ) > Max ( posB , posT ) )
direction = ' y ' ;
else
{
Datum interLR = DirectFunctionCall2 ( box2d_inter ,
PointerGetDatum ( unionL ) ,
PointerGetDatum ( unionR ) ) ;
Datum interBT = DirectFunctionCall2 ( box2d_inter ,
PointerGetDatum ( unionB ) ,
PointerGetDatum ( unionT ) ) ;
float sizeLR ,
sizeBT ;
//elog(NOTICE,"direction is abigeous");
sizeLR = size_box2d ( interLR ) ;
sizeBT = size_box2d ( interBT ) ;
if ( sizeLR < sizeBT )
direction = ' x ' ;
else
direction = ' y ' ;
}
if ( direction = = ' x ' )
{
pfree ( unionB ) ;
pfree ( listB ) ;
pfree ( unionT ) ;
pfree ( listT ) ;
v - > spl_left = listL ;
v - > spl_right = listR ;
v - > spl_nleft = posL ;
v - > spl_nright = posR ;
v - > spl_ldatum = PointerGetDatum ( unionL ) ;
v - > spl_rdatum = PointerGetDatum ( unionR ) ;
# ifdef DEBUG_GIST6
elog ( NOTICE , " split direction was '%c' " , direction ) ;
elog ( NOTICE , " posL = %i, posR=%i " , posL , posR ) ;
elog ( NOTICE , " posL's (nleft) offset numbers: " ) ;
{
char aaa [ 5000 ] , bbb [ 100 ] ;
aaa [ 0 ] = 0 ;
for ( i = 0 ; i < posL ; i + + )
{
sprintf ( bbb , " %i " , listL [ i ] ) ;
strcat ( aaa , bbb ) ;
}
elog ( NOTICE , aaa ) ;
aaa [ 0 ] = 0 ;
elog ( NOTICE , " posR's (nright) offset numbers: " ) ;
for ( i = 0 ; i < posR ; i + + )
{
sprintf ( bbb , " %i " , listR [ i ] ) ;
strcat ( aaa , bbb ) ;
}
elog ( NOTICE , aaa ) ;
}
# endif
}
else
{
pfree ( unionR ) ;
pfree ( listR ) ;
pfree ( unionL ) ;
pfree ( listL ) ;
v - > spl_left = listB ;
v - > spl_right = listT ;
v - > spl_nleft = posB ;
v - > spl_nright = posT ;
v - > spl_ldatum = PointerGetDatum ( unionB ) ;
v - > spl_rdatum = PointerGetDatum ( unionT ) ;
# ifdef DEBUG_GIST6
elog ( NOTICE , " split direction was '%c' " , direction ) ;
elog ( NOTICE , " posB = %i, posT=%i " , posB , posT ) ;
elog ( NOTICE , " posB's (nleft) offset numbers: " ) ;
{
char aaa [ 5000 ] , bbb [ 100 ] ;
aaa [ 0 ] = 0 ;
for ( i = 0 ; i < posB ; i + + )
{
sprintf ( bbb , " %i " , listB [ i ] ) ;
strcat ( aaa , bbb ) ;
}
elog ( NOTICE , aaa ) ;
aaa [ 0 ] = 0 ;
elog ( NOTICE , " posT's (nright) offset numbers: " ) ;
for ( i = 0 ; i < posT ; i + + )
{
sprintf ( bbb , " %i " , listT [ i ] ) ;
strcat ( aaa , bbb ) ;
}
elog ( NOTICE , aaa ) ;
}
# endif
}
PG_RETURN_POINTER ( v ) ;
}
2004-04-29 18:44:36 +00:00
// debug function
Datum report_lwgeom_gist_activity ( PG_FUNCTION_ARGS ) ;
2004-04-26 23:05:20 +00:00
PG_FUNCTION_INFO_V1 ( report_lwgeom_gist_activity ) ;
Datum report_lwgeom_gist_activity ( PG_FUNCTION_ARGS )
{
elog ( NOTICE , " lwgeom gist activity - internal consistency= %i, leaf consistency = %i " , counter_intern , counter_leaf ) ;
2004-04-29 18:44:36 +00:00
counter_intern = 0 ; //reset
counter_leaf = 0 ;
2004-04-26 23:05:20 +00:00
PG_RETURN_NULL ( ) ;
}