OGRErr OGRShapeLayer::CreateSpatialIndex( int nMaxDepth ) { /* -------------------------------------------------------------------- */ /* If we have an existing spatial index, blow it away first. */ /* -------------------------------------------------------------------- */ if( CheckForQIX() ) DropSpatialIndex(); bCheckedForQIX = FALSE; /* -------------------------------------------------------------------- */ /* Build a quadtree structure for this file. */ /* -------------------------------------------------------------------- */ SHPTree *psTree; SyncToDisk(); psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL ); if( NULL == psTree ) { // TODO - mloskot: Is it better to return OGRERR_NOT_ENOUGH_MEMORY? CPLDebug( "SHAPE", "Index creation failure. Likely, memory allocation error." ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Trim unused nodes from the tree. */ /* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree ); /* -------------------------------------------------------------------- */ /* Dump tree to .qix file. */ /* -------------------------------------------------------------------- */ char *pszQIXFilename; pszQIXFilename = CPLStrdup(CPLResetExtension( pszFullName, "qix" )); CPLDebug( "SHAPE", "Creating index file %s", pszQIXFilename ); SHPWriteTree( psTree, pszQIXFilename ); CPLFree( pszQIXFilename ); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); CheckForQIX(); return OGRERR_NONE; }
int main( int argc, char ** argv ) { SHPHandle hSHP; SHPTree *psTree; int nExpandShapes = 0; int nMaxDepth = 0; int bDoSearch = 0; double adfSearchMin[4], adfSearchMax[4]; const char *pszOutputIndexFilename = NULL; const char *pszInputIndexFilename = NULL; const char *pszTargetFile = NULL; /* -------------------------------------------------------------------- */ /* Consume flags. */ /* -------------------------------------------------------------------- */ while( argc > 1 ) { if( strcmp(argv[1],"-v") == 0 ) { nExpandShapes = 1; argv++; argc--; } else if( strcmp(argv[1],"-maxdepth") == 0 && argc > 2 ) { nMaxDepth = atoi(argv[2]); argv += 2; argc -= 2; } else if( strcmp(argv[1],"-o") == 0 && argc > 2 ) { pszOutputIndexFilename = argv[2]; argv += 2; argc -= 2; } else if( strcmp(argv[1],"-i") == 0 && argc > 2 ) { pszInputIndexFilename = argv[2]; argv += 2; argc -= 2; } else if( strcmp(argv[1],"-search") == 0 && argc > 5 ) { bDoSearch = 1; adfSearchMin[0] = atof(argv[2]); adfSearchMin[1] = atof(argv[3]); adfSearchMax[0] = atof(argv[4]); adfSearchMax[1] = atof(argv[5]); adfSearchMin[2] = adfSearchMax[2] = 0.0; adfSearchMin[3] = adfSearchMax[3] = 0.0; if( adfSearchMin[0] > adfSearchMax[0] || adfSearchMin[1] > adfSearchMax[1] ) { printf( "Min greater than max in search criteria.\n" ); Usage(); } argv += 5; argc -= 5; } else if( pszTargetFile == NULL ) { pszTargetFile = argv[1]; argv++; argc--; } else { printf( "Unrecognised argument: %s\n", argv[1] ); Usage(); } } /* -------------------------------------------------------------------- */ /* Do a search with an existing index file? */ /* -------------------------------------------------------------------- */ if( bDoSearch && pszInputIndexFilename != NULL ) { FILE *fp = fopen( pszInputIndexFilename, "rb" ); int *panResult, nResultCount = 0, iResult; if( fp == NULL ) { perror( pszInputIndexFilename ); exit( 1 ); } panResult = SHPSearchDiskTree( fp, adfSearchMin, adfSearchMax, &nResultCount ); printf( "Result: " ); for( iResult = 0; iResult < nResultCount; iResult++ ) printf( "%d ", panResult[iResult] ); printf( "\n" ); free( panResult ); fclose( fp ); exit( 0 ); } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( pszTargetFile == NULL ) { Usage(); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( pszTargetFile, "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", pszTargetFile ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Build a quadtree structure for this file. */ /* -------------------------------------------------------------------- */ psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Trim unused nodes from the tree. */ /* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree ); /* -------------------------------------------------------------------- */ /* Dump tree to .qix file. */ /* -------------------------------------------------------------------- */ if( pszOutputIndexFilename != NULL ) { SHPWriteTree( psTree, pszOutputIndexFilename ); } /* -------------------------------------------------------------------- */ /* Dump tree by recursive descent. */ /* -------------------------------------------------------------------- */ else if( !bDoSearch ) SHPTreeNodeDump( psTree, psTree->psRoot, "", nExpandShapes ); /* -------------------------------------------------------------------- */ /* or do a search instead. */ /* -------------------------------------------------------------------- */ else SHPTreeNodeSearchAndDump( psTree, adfSearchMin, adfSearchMax ); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); SHPClose( hSHP ); #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); }
int main( int argc, char ** argv ) { SHPHandle hSHP; SHPTree *psTree; int nExpandShapes = 0; int nMaxDepth = 0; int nDoSearch = 0; double adfSearchMin[4], adfSearchMax[4]; /* -------------------------------------------------------------------- */ /* Consume flags. */ /* -------------------------------------------------------------------- */ while( argc > 1 ) { if( strcmp(argv[1],"-v") == 0 ) { nExpandShapes = 1; argv++; argc--; } else if( strcmp(argv[1],"-maxdepth") == 0 && argc > 2 ) { nMaxDepth = atoi(argv[2]); argv += 2; argc -= 2; } else if( strcmp(argv[1],"-search") == 0 && argc > 5 ) { nDoSearch = 1; adfSearchMin[0] = atof(argv[2]); adfSearchMin[1] = atof(argv[3]); adfSearchMax[0] = atof(argv[4]); adfSearchMax[1] = atof(argv[5]); adfSearchMin[2] = adfSearchMax[2] = 0.0; adfSearchMin[3] = adfSearchMax[3] = 0.0; if( adfSearchMin[0] > adfSearchMax[0] || adfSearchMin[1] > adfSearchMax[1] ) { printf( "Min greater than max in search criteria.\n" ); Usage(); } argv += 5; argc -= 5; } else break; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 2 ) { Usage(); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Build a quadtree structure for this file. */ /* -------------------------------------------------------------------- */ psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Trim unused nodes from the tree. */ /* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree ); /* -------------------------------------------------------------------- */ /* Dump tree by recursive descent. */ /* -------------------------------------------------------------------- */ if( !nDoSearch ) SHPTreeNodeDump( psTree, psTree->psRoot, "", nExpandShapes ); /* -------------------------------------------------------------------- */ /* or do a search instead. */ /* -------------------------------------------------------------------- */ else SHPTreeNodeSearchAndDump( psTree, adfSearchMin, adfSearchMax ); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); SHPClose( hSHP ); #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); }
int main( int argc, char *argv[] ) { char out_filename[256]; if( argc != 4 ) { fprintf( stderr, "closeshp poly_shape arc_shape output_shape\n" ); return 1; } char *poly_file = argv[1]; char *arc_file = argv[2]; char *out_file = argv[3]; struct source poly, arc, simplified; memset( &poly, 0, sizeof(poly) ); memset( &arc, 0, sizeof(arc) ); memset( &simplified, 0, sizeof(simplified) ); poly.in_memory = arc.in_memory = 0; simplified.in_memory = 1; /* open shapefiles and dbf files */ if( SourceOpen( &poly, poly_file, SHPT_POLYGON ) ) return 1; if( SourceOpen( &arc, arc_file, SHPT_ARC ) ) return 1; sprintf( out_filename, "%s_p", out_file ); shp_out = SHPCreate( out_filename, SHPT_POLYGON ); if( !shp_out ) { fprintf( stderr, "Couldn't create shapefile '%s': %s\n", out_file, strerror(errno)); return 1; } dbf_out = DBFCreate( out_filename ); if( !dbf_out ) { fprintf( stderr, "Couldn't create DBF '%s': %s\n", out_file, strerror(errno)); return 1; } // DBFAddField( dbf_out, "way_id", FTInteger, 11, 0 ); // DBFAddField( dbf_out, "orientation", FTInteger, 1, 0 ); DBFAddField( dbf_out, "error", FTInteger, 1, 0 ); DBFAddField( dbf_out, "tile_x", FTInteger, 4, 0 ); DBFAddField( dbf_out, "tile_y", FTInteger, 4, 0 ); /* Initialise node arrays */ v_x = malloc( MAX_NODES * sizeof(double) ); v_y = malloc( MAX_NODES * sizeof(double) ); if( !v_x || !v_y ) { fprintf( stderr, "Couldn't allocate memory for nodes\n" ); return 1; } /* Setup state */ struct state state; memset( &state, 0, sizeof(state) ); ResizeSubareas(&state, INIT_MAX_SUBAREAS); // Temporary file for simplified shapes { // Make the file and open it char filename[32]; sprintf( filename, "tmp_coastline_%d", getpid() ); simplified.shp = SHPCreate( filename, SHPT_ARC ); if( !simplified.shp ) { fprintf( stderr, "Couldn't open temporary shapefile: %s\n", strerror(errno) ); return 1; } // And now unlink them so they're cleaned up when we die int len = strlen( filename ); strcpy( filename+len, ".shp" ); unlink(filename); strcpy( filename+len, ".shx" ); unlink(filename); // Setup the bitmap while creating the simplified polygons InitBitmap( &arc, &simplified ); InitBitmap( &poly, &simplified ); // And index the simplified polygons simplified.shx = SHPCreateTree( simplified.shp, 2, 10, NULL, NULL ); if( !simplified.shx ) { fprintf( stderr, "Couldn't build temporary shapetree\n" ); return 1; } SHPGetInfo( simplified.shp, &simplified.shape_count, NULL, NULL, NULL ); simplified.shapes = calloc( simplified.shape_count, sizeof(SHPObject*) ); } /* Split coastlines into arcs no longer than MAX_NODES_PER_ARC long */ sprintf( out_filename, "%s_i", out_file ); SplitCoastlines( &poly, &arc, out_filename ); #if !TEST for( int i=0; i<DIVISIONS; i++ ) for( int j=0; j<DIVISIONS; j++ ) //Divide the world into mercator blocks approx 100km x 100km #else for( int i=204; i<=204; i++ ) for( int j=248; j<=248; j++ ) //Divide the world into mercator blocks approx 100km x 100km #endif { state.x = i; state.y = j; double left = -MERC_MAX + (i*MERC_BLOCK) - TILE_OVERLAP; double right = -MERC_MAX + ((i+1)*MERC_BLOCK) + TILE_OVERLAP; double bottom = -MERC_MAX + (j*MERC_BLOCK) - TILE_OVERLAP; double top = -MERC_MAX + ((j+1)*MERC_BLOCK) + TILE_OVERLAP; if( left < -MERC_MAX ) left = -MERC_MAX; if( right > +MERC_MAX ) right = +MERC_MAX; state.lb[0] = left; state.lb[1] = bottom; state.rt[0] = right; state.rt[1] = top; if(isatty(STDERR_FILENO)) // fprintf( stderr, "\rProcessing (%d,%d) (%.2f,%.2f)-(%.2f,%.2f) ", i, j, left, bottom, right, top ); fprintf( stderr, "\rProcessing (%d,%d) (%.2f,%.2f)-(%.2f,%.2f) ", i, j, state.lb[0], state.lb[1], state.rt[0], state.rt[1] ); state.seg_count = 0; state.subarea_count = 0; state.subarea_nodecount = 0; state.enclosed = 0; // Optimisation: if we have determined nothing enters the tile, we can used the simplified tiles // Basically, we only need to test for enclosure if( check_tile( state.x, state.y ) ) { Process( &state, &poly, 1 ); Process( &state, &arc, 0 ); } else Process( &state, &simplified, 0 ); OutputSegs( &state ); } free( state.sub_areas ); free( simplified.shapes ); SHPDestroyTree( poly.shx ); SHPDestroyTree( arc.shx ); SHPDestroyTree( simplified.shx ); DBFClose( poly.dbf ); DBFClose( arc.dbf ); DBFClose( dbf_out ); SHPClose( poly.shp ); SHPClose( arc.shp ); SHPClose( simplified.shp ); SHPClose( shp_out ); printf("\n"); return 0; }