Пример #1
0
OGRFeature *OGRNTFLayer::GetNextFeature()

{
    OGRFeature  *poFeature = NULL;

/* -------------------------------------------------------------------- */
/*      Have we processed all features already?                         */
/* -------------------------------------------------------------------- */
    if( iCurrentReader == poDS->GetFileCount() )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Do we need to open a file?                                      */
/* -------------------------------------------------------------------- */
    if( iCurrentReader == -1 )
    {
        iCurrentReader++;
        nCurrentPos = -1;
    }

    NTFFileReader       *poCurrentReader = poDS->GetFileReader(iCurrentReader);
    if( poCurrentReader->GetFP() == NULL )
    {
        poCurrentReader->Open();
    }

/* -------------------------------------------------------------------- */
/*      Ensure we are reading on from the same point we were reading    */
/*      from for the last feature, even if some other access            */
/*      mechanism has moved the file pointer.                           */
/* -------------------------------------------------------------------- */
    if( nCurrentPos != -1 )
        poCurrentReader->SetFPPos( nCurrentPos, nCurrentFID );
    else
        poCurrentReader->Reset();
        
/* -------------------------------------------------------------------- */
/*      Read features till we find one that satisfies our current       */
/*      spatial criteria.                                               */
/* -------------------------------------------------------------------- */
    while( TRUE )
    {
        poFeature = poCurrentReader->ReadOGRFeature( this );
        if( poFeature == NULL )
            break;

        m_nFeaturesRead++;

        if( (m_poFilterGeom == NULL
             || poFeature->GetGeometryRef() == NULL 
             || FilterGeometry( poFeature->GetGeometryRef() ) )
            && (m_poAttrQuery == NULL
                || m_poAttrQuery->Evaluate( poFeature )) )
            break;

        delete poFeature;
    }

/* -------------------------------------------------------------------- */
/*      If we get NULL the file must be all consumed, advance to the    */
/*      next file that contains features for this layer.                */
/* -------------------------------------------------------------------- */
    if( poFeature == NULL )
    {
        poCurrentReader->Close();

        if( poDS->GetOption("CACHING") != NULL
            && EQUAL(poDS->GetOption("CACHING"),"OFF") )
        {
            poCurrentReader->DestroyIndex();
        }

        do { 
            iCurrentReader++;
        } while( iCurrentReader < poDS->GetFileCount()
                 && !poDS->GetFileReader(iCurrentReader)->TestForLayer(this) );

        nCurrentPos = -1;
        nCurrentFID = 1;

        poFeature = GetNextFeature();
    }
    else
    {
        poCurrentReader->GetFPPos(&nCurrentPos, &nCurrentFID);
    }

    return poFeature;
}
Пример #2
0
int OGRNTFDataSource::Open( const char * pszFilename, int bTestOpen,
                            char ** papszLimitedFileList )

{
    VSIStatBuf      stat;
    char            **papszFileList = NULL;

    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Is the given path a directory or a regular file?                */
/* -------------------------------------------------------------------- */
    if( CPLStat( pszFilename, &stat ) != 0 
        || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) )
    {
        if( !bTestOpen )
            CPLError( CE_Failure, CPLE_AppDefined,
                   "%s is neither a file or directory, NTF access failed.\n",
                      pszFilename );

        return FALSE;
    }
    
/* -------------------------------------------------------------------- */
/*      Build a list of filenames we figure are NTF files.              */
/* -------------------------------------------------------------------- */
    if( VSI_ISREG(stat.st_mode) )
    {
        papszFileList = CSLAddString( NULL, pszFilename );
    }
    else
    {
        char      **candidateFileList = CPLReadDir( pszFilename );
        int         i;

        for( i = 0; 
             candidateFileList != NULL && candidateFileList[i] != NULL; 
             i++ ) 
        {
            if( papszLimitedFileList != NULL
                && CSLFindString(papszLimitedFileList,
                                 candidateFileList[i]) == -1 )
            {
                continue;
            }
            
            if( strlen(candidateFileList[i]) > 4
              && EQUALN(candidateFileList[i] + strlen(candidateFileList[i])-4,
                       ".ntf",4) )
            {
                char       fullFilename[2048];

                sprintf( fullFilename, "%s%c%s", 
                         pszFilename,
#ifdef WIN32
                         '\\',
#else
                         '/',
#endif
                         candidateFileList[i] );

                papszFileList = CSLAddString( papszFileList, fullFilename );
            }
        }

        CSLDestroy( candidateFileList );

        if( CSLCount(papszFileList) == 0 )
        {
            if( !bTestOpen )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "No candidate NTF files (.ntf) found in\n"
                          "directory: %s",
                          pszFilename );

            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Loop over all these files trying to open them.  In testopen     */
/*      mode we first read the first 80 characters, to verify that      */
/*      it looks like an NTF file.  Note that we don't keep the file    */
/*      open ... we don't want to occupy alot of file handles when      */
/*      handling a whole directory.                                     */
/* -------------------------------------------------------------------- */
    int         i;

    papoNTFFileReader = (NTFFileReader **)
        CPLCalloc(sizeof(void*), CSLCount(papszFileList));
    
    for( i = 0; papszFileList[i] != NULL; i++ )
    {
        if( bTestOpen )
        {
            char        szHeader[80];
            FILE        *fp;
            int         j;

            fp = VSIFOpen( papszFileList[i], "rb" );
            if( fp == NULL )
                continue;
            
            if( VSIFRead( szHeader, 80, 1, fp ) < 1 )
            {
                VSIFClose( fp );
                continue;
            }

            VSIFClose( fp );
            
            if( !EQUALN(szHeader,"01",2) )
                continue;

            for( j = 0; j < 80; j++ )
            {
                if( szHeader[j] == 10 || szHeader[j] == 13 )
                    break;
            }

            if( j == 80 || szHeader[j-1] != '%' )
                continue;

        }

        NTFFileReader   *poFR;

        poFR = new NTFFileReader( this );

        if( !poFR->Open( papszFileList[i] ) )
        {
            delete poFR;
            CSLDestroy( papszFileList );
            
            return FALSE;
        }

        poFR->SetBaseFID( nNTFFileCount * 1000000 + 1 );
        poFR->Close();

        EnsureTileNameUnique( poFR );

        papoNTFFileReader[nNTFFileCount++] = poFR;
    }

    CSLDestroy( papszFileList );

    if( nNTFFileCount == 0 )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Establish generic layers.                                       */
/* -------------------------------------------------------------------- */
    EstablishGenericLayers();
    
/* -------------------------------------------------------------------- */
/*      Loop over all the files, collecting a unique feature class      */
/*      listing.                                                        */
/* -------------------------------------------------------------------- */
    for( int iSrcFile = 0; iSrcFile < nNTFFileCount; iSrcFile++ )
    {
        NTFFileReader   *poSrcReader = papoNTFFileReader[iSrcFile];
        
        for( int iSrcFC = 0; iSrcFC < poSrcReader->GetFCCount(); iSrcFC++ )
        {
            int         iDstFC;
            char       *pszSrcFCName, *pszSrcFCNum;

            poSrcReader->GetFeatureClass( iSrcFC, &pszSrcFCNum, &pszSrcFCName);
            
            for( iDstFC = 0; iDstFC < nFCCount; iDstFC++ )
            {
                if( EQUAL(pszSrcFCNum,papszFCNum[iDstFC]) )
                    break;
            }

            if( iDstFC >= nFCCount )
            {
                nFCCount++;
                papszFCNum = CSLAddString(papszFCNum,pszSrcFCNum);
                papszFCName = CSLAddString(papszFCName,pszSrcFCName);
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Create a new layer specifically for feature classes.            */
/* -------------------------------------------------------------------- */
    if( nFCCount > 0 )
        poFCLayer = new OGRNTFFeatureClassLayer( this );
    else
        poFCLayer = NULL;
    
    return TRUE;
}