Beispiel #1
0
int OGRShapeLayer::ScanIndices()

{
    iMatchingFID = 0;

/* -------------------------------------------------------------------- */
/*      Utilize attribute index if appropriate.                         */
/* -------------------------------------------------------------------- */
    if( m_poAttrQuery != NULL )
    {
        CPLAssert( panMatchingFIDs == NULL );
        panMatchingFIDs = m_poAttrQuery->EvaluateAgainstIndices( this,
                                                                 NULL );
    }

/* -------------------------------------------------------------------- */
/*      Check for spatial index if we have a spatial query.             */
/* -------------------------------------------------------------------- */
    if( m_poFilterGeom != NULL && !bCheckedForQIX )
        CheckForQIX();

/* -------------------------------------------------------------------- */
/*      Utilize spatial index if appropriate.                           */
/* -------------------------------------------------------------------- */
    if( m_poFilterGeom && fpQIX )
    {
        int nSpatialFIDCount, *panSpatialFIDs;
        double adfBoundsMin[4], adfBoundsMax[4];
        OGREnvelope oEnvelope;

        m_poFilterGeom->getEnvelope( &oEnvelope );

        adfBoundsMin[0] = oEnvelope.MinX;
        adfBoundsMin[1] = oEnvelope.MinY;
        adfBoundsMin[2] = 0.0;
        adfBoundsMin[3] = 0.0;
        adfBoundsMax[0] = oEnvelope.MaxX;
        adfBoundsMax[1] = oEnvelope.MaxY;
        adfBoundsMax[2] = 0.0;
        adfBoundsMax[3] = 0.0;

        panSpatialFIDs = SHPSearchDiskTree( fpQIX, 
                                            adfBoundsMin, adfBoundsMax, 
                                            &nSpatialFIDCount );
        CPLDebug( "SHAPE", "Used spatial index, got %d matches.", 
                  nSpatialFIDCount );

        // Use resulting list as matching FID list (but reallocate and
        // terminate with OGRNullFID).

        if( panMatchingFIDs == NULL )
        {
            int i;

            panMatchingFIDs = (long *) 
                CPLMalloc(sizeof(long) * (nSpatialFIDCount+1) );
            for( i = 0; i < nSpatialFIDCount; i++ )
                panMatchingFIDs[i] = (long) panSpatialFIDs[i];
            panMatchingFIDs[nSpatialFIDCount] = OGRNullFID;
        }

        // Cull attribute index matches based on those in the spatial index
        // result set.  We assume that the attribute results are in sorted
        // order.
        else
        {
            int iRead, iWrite=0, iSpatial=0;

            for( iRead = 0; panMatchingFIDs[iRead] != OGRNullFID; iRead++ )
            {
                while( iSpatial < nSpatialFIDCount
                       && panSpatialFIDs[iSpatial] < panMatchingFIDs[iRead] )
                    iSpatial++;

                if( iSpatial == nSpatialFIDCount )
                    continue;

                if( panSpatialFIDs[iSpatial] == panMatchingFIDs[iRead] )
                    panMatchingFIDs[iWrite++] = panMatchingFIDs[iRead];
            }
            panMatchingFIDs[iWrite] = OGRNullFID;
        }

        if ( panSpatialFIDs )
            free( panSpatialFIDs );
    }

    return TRUE;
}
Beispiel #2
0
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 );
}