// Function to filter search results further against feature bboxes void msFilterTreeSearch(shapefileObj *shp, char *status, rectObj search_rect) { int i; rectObj shape_rect; for(i=0; i<shp->numshapes; i++) { /* for each shape */ if(msGetBit(status, i)) { if(!msSHPReadBounds(shp->hSHP, i, &shape_rect)) if(msRectOverlap(&shape_rect, &search_rect) != MS_TRUE) msSetBit(status, i, 0); } } }
/* Function to filter search results further against feature bboxes */ void msFilterTreeSearch(shapefileObj *shp, ms_bitarray status, rectObj search_rect) { int i; rectObj shape_rect; i = msGetNextBit(status, 0, shp->numshapes); while(i >= 0) { if(msSHPReadBounds(shp->hSHP, i, &shape_rect) == MS_SUCCESS) { if(msRectOverlap(&shape_rect, &search_rect) != MS_TRUE) { msSetBit(status, i, 0); } } i = msGetNextBit(status, i+1, shp->numshapes); } }
treeObj *msCreateTree(shapefileObj *shapefile, int maxdepth) { int i; treeObj *tree; rectObj bounds; if(!shapefile) return NULL; /* -------------------------------------------------------------------- */ /* Allocate the tree object */ /* -------------------------------------------------------------------- */ tree = (treeObj *) msSmallMalloc(sizeof(treeObj)); tree->numshapes = shapefile->numshapes; tree->maxdepth = maxdepth; /* -------------------------------------------------------------------- */ /* If no max depth was defined, try to select a reasonable one */ /* that implies approximately 8 shapes per node. */ /* -------------------------------------------------------------------- */ if( tree->maxdepth == 0 ) { int numnodes = 1; while(numnodes*4 < shapefile->numshapes) { tree->maxdepth += 1; numnodes = numnodes * 2; } } /* -------------------------------------------------------------------- */ /* Allocate the root node. */ /* -------------------------------------------------------------------- */ tree->root = treeNodeCreate(shapefile->bounds); for(i=0; i<shapefile->numshapes; i++) { if(msSHPReadBounds(shapefile->hSHP, i, &bounds) == MS_SUCCESS) treeAddShapeId(tree, i, bounds); } return tree; }
void Topology::initCache() { //Selecting caching scenarios based on available memory and topo size // Unfortunatelly I don't find a suitable algorithm to estimate the loaded // shapefile's memory footprint so we never choose mode2. KR long free_size = CheckFreeRam(); long bounds_size = sizeof(rectObj)*shpfile.numshapes; //Cache mode selection based on available memory cache_mode = 0; free_size -= 10000*1024; // Safe: if we don't have enough memory we use mode0 if (free_size>bounds_size) cache_mode = 1; // TESTING ONLY, mode override //cache_mode = 2; shpBounds = NULL; shps = NULL; for (int i=0; i<shpfile.numshapes; i++) shpCache[i] = NULL; switch (cache_mode) { default: case 0: // Original #ifdef DEBUG_TFC StartupStore(_T("Topology cache using mode 0%s"), NEWLINE); #endif break; case 1: // Using bounds array in memory #ifdef DEBUG_TFC StartupStore(_T(". Topology cache using mode 1%s"), NEWLINE); #endif shpBounds = (rectObj*)malloc(sizeof(rectObj)*shpfile.numshapes); if (shpBounds == NULL) { //Fallback to mode 0 StartupStore(_T("------ WARN Topology, malloc failed shpBounds, fallback to mode0%s"), NEWLINE); cache_mode = 0; break; } // Get bounds for each shape from shapefile rectObj *prect; int retval; for (int i=0; i<shpfile.numshapes; i++) { prect = &shpBounds[i]; retval = msSHPReadBounds(shpfile.hSHP, i, prect); if (retval) { StartupStore(_T("------ WARN Topology, shape bounds reading failed, fallback to mode0%s"), NEWLINE); // Cleanup free(shpBounds); shpBounds=NULL; cache_mode = 0; break; } }//for break; case 2: // Using shape array in memory #ifdef DEBUG_TFC StartupStore(_T(". Topology cache using mode 2%s"), NEWLINE); #endif shpBounds = NULL; shps = (XShape**)malloc(sizeof(XShape*)*shpfile.numshapes); if (shps == NULL) { //Fallback to mode 0 StartupStore(_T("------ WARN Topology, malloc failed shps, fallback to mode0%s"), NEWLINE); cache_mode = 0; break; } // Load all shapes to shps for (int i=0; i<shpfile.numshapes; i++) { if ( (shps[i] = addShape(i)) == NULL ) { StartupStore(_T("------ WARN Topology, addShape failed for shps[%d], fallback to mode0%s"), i, NEWLINE); // Cleanup for (int j=0; j<i; j++) delete(shps[i]); free(shps); shps=NULL; cache_mode = 0; break; } } } //sw }