]> granicus.if.org Git - postgis/commitdiff
- integrated a bugfix for the rtree_picksplit algorithm from Teodor Sigaev. This...
authorChris Hodgson <chodgson@refractions.net>
Tue, 14 May 2002 18:28:07 +0000 (18:28 +0000)
committerChris Hodgson <chodgson@refractions.net>
Tue, 14 May 2002 18:28:07 +0000 (18:28 +0000)
- cleaned up some warnings (mostly "possibly unitialized variables")

git-svn-id: http://svn.osgeo.org/postgis/trunk@159 b70326c6-7e19-0410-871a-916f4a2858ee

loader/shp2pgsql.c
postgis.h
postgis.sql.in
postgis_fn.c
postgis_gist_72.c
postgis_inout.c

index dfa1327e39be9b1cd8b5bb4e68f3758d71e9e094..8ddeb9d510d7d10b300b56a4236ebad27622f540 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include "getopt.h"
 
 typedef struct {double x, y, z;} Point;
 
index b75218082b27aa3fa3743a6f357264e7a1894320..615b63c59603c60c65924cba0f42204fc08c51bf 100644 (file)
--- a/postgis.h
+++ b/postgis.h
@@ -487,6 +487,7 @@ Datum box3d_zmin(PG_FUNCTION_ARGS);
 Datum box3d_xmax(PG_FUNCTION_ARGS);
 Datum box3d_ymax(PG_FUNCTION_ARGS);
 Datum box3d_zmax(PG_FUNCTION_ARGS);
+Datum box3dtobox(PG_FUNCTION_ARGS);
 
 
 
index 811ec153e08dcee8e01e26d0065003db73f960c4..52ca7213601655de87a155f76f34d14aa38dbea8 100644 (file)
@@ -674,6 +674,11 @@ CREATE FUNCTION zmax(BOX3D)
    AS '@MODULE_FILENAME@','box3d_zmax'
    LANGUAGE 'c' with (isstrict,iscachable);
 
+CREATE FUNCTION box3dtobox(BOX3D)
+   RETURNS BOX
+   AS '@MODULE_FILENAME@','box3dtobox'
+   LANGUAGE 'c' with (isstrict,iscachable);
+
 ------- Aggregate
 
 CREATE FUNCTION combine_bbox(BOX3D,GEOMETRY)
index 513e7c9183a048635f607a3efddd6e2ed2f16f59..566ead08759760fcaada1ed528982356147452c4 100644 (file)
@@ -1935,7 +1935,7 @@ Datum distance(PG_FUNCTION_ARGS)
        GEOMETRY                      *geom1 = (GEOMETRY *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
        GEOMETRY                      *geom2 = (GEOMETRY *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
        int     g1_i, g2_i;
-       double          dist,this_dist;
+       double          dist,this_dist = 0;
        bool                    dist_set = FALSE; //true once dist makes sense.
        int32                   *offsets1,*offsets2;    
        int                     type1,type2;
@@ -2392,7 +2392,7 @@ PG_FUNCTION_INFO_V1(segmentize);
 Datum segmentize(PG_FUNCTION_ARGS)
 {
                GEOMETRY                *geom1 = (GEOMETRY *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-               GEOMETRY                *result,*result2;
+               GEOMETRY                *result = NULL, *result2;
                double                  maxdist = PG_GETARG_FLOAT8(1);
                int32                   *offsets1,*p_npoints_ring;
                int                             g1_i,r;
@@ -2608,3 +2608,12 @@ Datum box3d_zmax(PG_FUNCTION_ARGS)
        PG_RETURN_FLOAT8(box1->URT.z);
 }
 
+PG_FUNCTION_INFO_V1(box3dtobox);
+Datum box3dtobox(PG_FUNCTION_ARGS)
+{
+       BOX3D *box1 = (BOX3D *) PG_GETARG_POINTER(0);
+       BOX *out;
+       out = convert_box3d_to_box(box1);
+       PG_RETURN_POINTER(out);
+}
+
index 8dc1ed74681ac66e38a13bf4b52a1de2b389c258..6c31b829ac8650721330e88303d9ed48c731b304 100644 (file)
@@ -40,7 +40,7 @@
 #define SHOW_DIGS_DOUBLE 15
 #define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1)
 
-// #define DEBUG_GIST
+//#define DEBUG_GIST
 
 //for GIST index
 typedef char* (*BINARY_UNION)(char*, char*, int*);
@@ -52,13 +52,14 @@ BOX *convert_box3d_to_box(BOX3D *in);
 Datum ggeometry_compress(PG_FUNCTION_ARGS);
 Datum ggeometry_consistent(PG_FUNCTION_ARGS);
 bool rtree_internal_consistent(BOX *key, BOX *query,StrategyNumber strategy);
+Datum rtree_decompress(PG_FUNCTION_ARGS);
 Datum gbox_union(PG_FUNCTION_ARGS);
 Datum gbox_picksplit(PG_FUNCTION_ARGS);
 Datum gbox_penalty(PG_FUNCTION_ARGS);
 Datum gbox_same(PG_FUNCTION_ARGS);
-static bool gbox_leaf_consistent(BOX *key, BOX *query, StrategyNumber strategy);
 static float size_box(Datum box);
 
+int debug = 0;
 
 //restriction in the GiST && operator
 PG_FUNCTION_INFO_V1(postgis_gist_sel);
@@ -94,7 +95,7 @@ Datum ggeometry_compress(PG_FUNCTION_ARGS)
                        GEOMETRY *in;
                        BOX     *r;
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: ggeometry_compress called on geometry\n");
        fflush( stdout );
 #endif
@@ -132,7 +133,7 @@ Datum ggeometry_consistent(PG_FUNCTION_ARGS)
     ** else use gbox_leaf_consistent
     */
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: ggeometry_consistent called\n");
        fflush( stdout );
 #endif
@@ -154,7 +155,7 @@ bool rtree_internal_consistent(BOX *key,
 {
     bool retval;
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: rtree_internal_consist called\n");
        fflush( stdout );
 #endif
@@ -204,7 +205,7 @@ Datum gbox_union(PG_FUNCTION_ARGS)
        BOX                *cur,
                           *pageunion;
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: gbox_union called\n");
        fflush( stdout );
 #endif
@@ -244,7 +245,7 @@ Datum gbox_penalty(PG_FUNCTION_ARGS)
        Datum           ud;
        float           tmp1;
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: gbox_penalty called\n");
        fflush( stdout );
 #endif
@@ -258,13 +259,30 @@ Datum gbox_penalty(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+typedef struct {
+       BOX     *key;
+       int     pos;
+} KBsort;
+
+static int
+compare_KB(const void* a, const void* b) {
+       BOX *abox = ((KBsort*)a)->key; 
+       BOX *bbox = ((KBsort*)b)->key;
+       float sa = (abox->high.x - abox->low.x) * (abox->high.y - abox->low.y);
+       float sb = (bbox->high.x - bbox->low.x) * (bbox->high.y - bbox->low.y);
+
+       if ( sa==sb ) return 0;
+       return ( sa>sb ) ? 1 : -1;
+}
+
 /*
 ** 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(gbox_picksplit);
-Datum gbox_picksplit(PG_FUNCTION_ARGS)
+Datum
+gbox_picksplit(PG_FUNCTION_ARGS)
 {
        bytea      *entryvec = (bytea *) PG_GETARG_POINTER(0);
        GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
@@ -288,7 +306,7 @@ Datum gbox_picksplit(PG_FUNCTION_ARGS)
        OffsetNumber maxoff;
        int                     nbytes;
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: gbox_picksplit called\n");
        fflush( stdout );
 #endif
@@ -303,26 +321,22 @@ Datum gbox_picksplit(PG_FUNCTION_ARGS)
        for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i))
        {
                cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
-               if (pageunion.high.x < cur->high.x)
-               {
+               if ( allisequal == true &&  (
+                               pageunion.high.x != cur->high.x || 
+                               pageunion.high.y != cur->high.y || 
+                               pageunion.low.x != cur->low.x || 
+                               pageunion.low.y != cur->low.y 
+                       ) ) 
                        allisequal = false;
+               if (pageunion.high.x < cur->high.x)
                        pageunion.high.x = cur->high.x;
-               }
                if (pageunion.low.x > cur->low.x)
-               {
-                       allisequal = false;
                        pageunion.low.x = cur->low.x;
-               }
                if (pageunion.high.y < cur->high.y)
-               {
-                       allisequal = false;
                        pageunion.high.y = cur->high.y;
-               }
                if (pageunion.low.y > cur->low.y)
-               {
-                       allisequal = false;
                        pageunion.low.y = cur->low.y;
-               }
        }
 
        nbytes = (maxoff + 2) * sizeof(OffsetNumber);
@@ -366,7 +380,7 @@ Datum gbox_picksplit(PG_FUNCTION_ARGS)
        unionB = (BOX *) palloc(sizeof(BOX));
        unionT = (BOX *) palloc(sizeof(BOX));
 
-#define ADDLIST( list, unionD, pos ) do { \
+#define ADDLIST( list, unionD, pos, num ) do { \
        if ( pos ) { \
                if ( unionD->high.x < cur->high.x ) unionD->high.x      = cur->high.x; \
                if ( unionD->low.x      > cur->low.x  ) unionD->low.x   = cur->low.x; \
@@ -375,7 +389,7 @@ Datum gbox_picksplit(PG_FUNCTION_ARGS)
        } else { \
                        memcpy( (void*)unionD, (void*) cur, sizeof( BOX ) );  \
        } \
-       list[pos] = i; \
+       list[pos] = num; \
        (pos)++; \
 } while(0)
 
@@ -383,17 +397,50 @@ Datum gbox_picksplit(PG_FUNCTION_ARGS)
        {
                cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
                if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x)
-                       ADDLIST(listL, unionL, posL);
+                       ADDLIST(listL, unionL, posL,i);
                else
-                       ADDLIST(listR, unionR, posR);
+                       ADDLIST(listR, unionR, posR,i);
                if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y)
-                       ADDLIST(listB, unionB, posB);
+                       ADDLIST(listB, unionB, posB,i);
                else
-                       ADDLIST(listT, unionT, posT);
+                       ADDLIST(listT, unionT, posT,i);
        }
 
-       /* which split more optimal? */
+       /* 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)) {
+                       arr[i-1].key = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
+                       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->low.x - pageunion.low.x < pageunion.high.x - cur->high.x)
+                               ADDLIST(listL, unionL, posL,arr[i-1].pos);
+                       else if ( cur->low.x - pageunion.low.x == pageunion.high.x - cur->high.x ) {
+                               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->low.y - pageunion.low.y < pageunion.high.y - cur->high.y)
+                               ADDLIST(listB, unionB, posB,arr[i-1].pos);
+                       else if ( cur->low.y - pageunion.low.y == pageunion.high.y - cur->high.y ) {
+                               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))
@@ -460,7 +507,7 @@ Datum gbox_same(PG_FUNCTION_ARGS)
        BOX                *b2 = (BOX *) PG_GETARG_POINTER(1);
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: gbox_same called\n");
        fflush( stdout );
 #endif
@@ -472,58 +519,11 @@ Datum gbox_same(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
-/*
-** SUPPORT ROUTINES for boxes
-*/
-static bool
-gbox_leaf_consistent(BOX *key,
-                                        BOX *query,
-                                        StrategyNumber strategy)
-{
-       bool            retval;
-
-#ifdef DEBUG_GIST2
-       printf("GIST: gbox_leaf_consistent called\n");
-       fflush( stdout );
-#endif
-
-       switch (strategy)
-       {
-               case RTLeftStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_left, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTOverLeftStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTOverlapStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTOverRightStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_overright, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTRightStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_right, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTSameStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTContainsStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               case RTContainedByStrategyNumber:
-                       retval = DatumGetBool(DirectFunctionCall2(box_contained, PointerGetDatum(key), PointerGetDatum(query)));
-                       break;
-               default:
-                       retval = FALSE;
-       }
-       return (retval);
-}
-
 static float
 size_box(Datum box)
 {
 
-#ifdef DEBUG_GIST2
+#ifdef DEBUG_GIST
        printf("GIST: size_box called\n");
        fflush( stdout );
 #endif
index fd5d84eb316bd83a04303edee0346e492f214a7b..823ec5cfebd77e51d78afcb926c1625b1aa78ae6 100644 (file)
@@ -2685,7 +2685,7 @@ char      *to_wkb_sub(GEOMETRY *geom, bool flip_endian, int32 *wkb_size)
 {
 
        char    byte_order;
-       char    *result;
+       char    *result = NULL;
        int             t;
        
 
@@ -3233,8 +3233,8 @@ unsigned char     parse_hex(char *str)
 {
        //do this a little brute force to make it faster
 
-       unsigned char           result_high;
-       unsigned char           result_low;
+       unsigned char           result_high = 0;
+       unsigned char           result_low = 0;
 
        switch (str[0])
        {