コード例 #1
0
ファイル: ogrshapelayer.cpp プロジェクト: dlsyaim/osgEarthX
OGRSpatialReference *OGRShapeLayer::GetSpatialRef()

{
    if (bSRSSet)
        return poSRS;

    bSRSSet = TRUE;

/* -------------------------------------------------------------------- */
/*      Is there an associated .prj file we can read?                   */
/* -------------------------------------------------------------------- */
    const char  *pszPrjFile = CPLResetExtension( pszFullName, "prj" );
    char    **papszLines;

    char* apszOptions[] = { (char*)"EMIT_ERROR_IF_CANNOT_OPEN_FILE=FALSE", NULL };
    papszLines = CSLLoad2( pszPrjFile, -1, -1, apszOptions );
    if (papszLines == NULL)
    {
        pszPrjFile = CPLResetExtension( pszFullName, "PRJ" );
        papszLines = CSLLoad2( pszPrjFile, -1, -1, apszOptions );
    }

    if( papszLines != NULL )
    {
        poSRS = new OGRSpatialReference();
        if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
        CSLDestroy( papszLines );
    }

    return poSRS;
}
コード例 #2
0
ファイル: ogridrisilayer.cpp プロジェクト: rashadkm/lib_gdal
int OGRIdrisiLayer::Detect_AVL_ADC(const char* pszFilename)
{
// --------------------------------------------------------------------
//      Look for .adc file
// --------------------------------------------------------------------
    const char* pszADCFilename = CPLResetExtension(pszFilename, "adc");
    VSILFILE* fpADC = VSIFOpenL(pszADCFilename, "rb");
    if (fpADC == NULL)
    {
        pszADCFilename = CPLResetExtension(pszFilename, "ADC");
        fpADC = VSIFOpenL(pszADCFilename, "rb");
    }

    char** papszADC = NULL;
    if (fpADC != NULL)
    {
        VSIFCloseL(fpADC);
        fpADC = NULL;

        CPLPushErrorHandler(CPLQuietErrorHandler);
        papszADC = CSLLoad2(pszADCFilename, 1024, 256, NULL);
        CPLPopErrorHandler();
        CPLErrorReset();
    }

    if (papszADC == NULL)
        return FALSE;

    CSLSetNameValueSeparator( papszADC, ":" );

    const char *pszVersion = CSLFetchNameValue( papszADC, "file format " );
    if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Values A.1" ) )
    {
        CSLDestroy( papszADC );
        return FALSE;
    }

    const char *pszFileType = CSLFetchNameValue( papszADC, "file type   " );
    if( pszFileType == NULL || !EQUAL( pszFileType, "ascii" ) )
    {
        CPLDebug("IDRISI", ".adc file found, but file type != ascii");
        CSLDestroy( papszADC );
        return FALSE;
    }

    const char* pszRecords = CSLFetchNameValue( papszADC, "records     " );
    if( pszRecords == NULL || atoi(pszRecords) != (int)nTotalFeatures )
    {
        CPLDebug("IDRISI", ".adc file found, but 'records' not found or not "
                 "consistent with feature number declared in .vdc");
        CSLDestroy( papszADC );
        return FALSE;
    }

    const char* pszFields = CSLFetchNameValue( papszADC, "fields      " );
    if( pszFields == NULL || atoi(pszFields) <= 1 )
    {
        CPLDebug("IDRISI", ".adc file found, but 'fields' not found or invalid");
        CSLDestroy( papszADC );
        return FALSE;
    }

// --------------------------------------------------------------------
//      Look for .avl file
// --------------------------------------------------------------------
    const char* pszAVLFilename = CPLResetExtension(pszFilename, "avl");
    fpAVL = VSIFOpenL(pszAVLFilename, "rb");
    if (fpAVL == NULL)
    {
        pszAVLFilename = CPLResetExtension(pszFilename, "AVL");
        fpAVL = VSIFOpenL(pszAVLFilename, "rb");
    }
    if (fpAVL == NULL)
    {
        CSLDestroy( papszADC );
        return FALSE;
    }

// --------------------------------------------------------------------
//      Build layer definition
// --------------------------------------------------------------------

    int iCurField;
    char szKey[32];

    iCurField = 0;
    sprintf(szKey, "field %d ", iCurField);

    char** papszIter = papszADC;
    const char* pszLine;
    int bFieldFound = FALSE;
    CPLString osFieldName;
    while((pszLine = *papszIter) != NULL)
    {
        //CPLDebug("IDRISI", "%s", pszLine);
        if (strncmp(pszLine, szKey, strlen(szKey)) == 0)
        {
            const char* pszColon = strchr(pszLine, ':');
            if (pszColon)
            {
                osFieldName = pszColon + 1;
                bFieldFound = TRUE;
            }
        }
        else if (bFieldFound &&
                 strncmp(pszLine, "data type   :", strlen("data type   :")) == 0)
        {
            const char* pszFieldType = pszLine + strlen("data type   :");

            OGRFieldDefn oFieldDefn(osFieldName.c_str(),
                                    EQUAL(pszFieldType, "integer") ? OFTInteger :
                                    EQUAL(pszFieldType, "real") ? OFTReal : OFTString);

            if( iCurField == 0 && oFieldDefn.GetType() != OFTInteger )
            {
                CSLDestroy( papszADC );
                return FALSE;
            }

            if( iCurField != 0 )
                poFeatureDefn->AddFieldDefn( &oFieldDefn );

            iCurField ++;
            sprintf(szKey, "field %d ", iCurField);
        }

        papszIter++;
    }

    CSLDestroy(papszADC);

    return TRUE;
}
コード例 #3
0
int OGRIdrisiDataSource::Open( const char * pszFilename )

{
    pszName = CPLStrdup( pszFilename );

    VSILFILE* fpVCT = VSIFOpenL(pszFilename, "rb");
    if (fpVCT == NULL)
        return FALSE;

    char* pszWTKString = NULL;

// --------------------------------------------------------------------
//      Look for .vdc file
// --------------------------------------------------------------------
    const char* pszVDCFilename = CPLResetExtension(pszFilename, "vdc");
    VSILFILE* fpVDC = VSIFOpenL(pszVDCFilename, "rb");
    if (fpVDC == NULL)
    {
        pszVDCFilename = CPLResetExtension(pszFilename, "VDC");
        fpVDC = VSIFOpenL(pszVDCFilename, "rb");
    }

    char** papszVDC = NULL;
    if (fpVDC != NULL)
    {
        VSIFCloseL(fpVDC);
        fpVDC = NULL;

        CPLPushErrorHandler(CPLQuietErrorHandler);
        papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, NULL);
        CPLPopErrorHandler();
        CPLErrorReset();
    }

    OGRwkbGeometryType eType = wkbUnknown;

    if (papszVDC != NULL)
    {
        CSLSetNameValueSeparator( papszVDC, ":" );

        const char *pszVersion = CSLFetchNameValue( papszVDC, "file format " );

        if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Vector A.1" ) )
        {
            CSLDestroy( papszVDC );
            VSIFCloseL(fpVCT);
            return FALSE;
        }

        const char *pszRefSystem
            = CSLFetchNameValue( papszVDC, "ref. system " );
        const char *pszRefUnits = CSLFetchNameValue( papszVDC, "ref. units  " );

        if (pszRefSystem != NULL && pszRefUnits != NULL)
            IdrisiGeoReference2Wkt( pszFilename, pszRefSystem, pszRefUnits,
                                    &pszWTKString);
    }

    GByte chType;
    if (VSIFReadL(&chType, 1, 1, fpVCT) != 1)
    {
        VSIFCloseL(fpVCT);
        CSLDestroy( papszVDC );
        return FALSE;
    }

    if (chType == 1)
        eType = wkbPoint;
    else if (chType == 2)
        eType = wkbLineString;
    else if (chType == 3)
        eType = wkbPolygon;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Unsupport geometry type : %d",
                  static_cast<int>(chType) );
        VSIFCloseL(fpVCT);
        CSLDestroy( papszVDC );
        return FALSE;
    }

    const char *pszMinX = CSLFetchNameValue( papszVDC, "min. X      " );
    const char *pszMaxX = CSLFetchNameValue( papszVDC, "max. X      " );
    const char *pszMinY = CSLFetchNameValue( papszVDC, "min. Y      " );
    const char *pszMaxY = CSLFetchNameValue( papszVDC, "max. Y      " );

    OGRIdrisiLayer* poLayer = new OGRIdrisiLayer(pszFilename,
                                                 CPLGetBasename(pszFilename),
                                                 fpVCT, eType, pszWTKString);
    papoLayers = static_cast<OGRLayer**>( CPLMalloc(sizeof(OGRLayer*)) );
    papoLayers[nLayers ++] = poLayer;

    if( pszMinX != NULL && pszMaxX != NULL && pszMinY != NULL &&
        pszMaxY != NULL)
    {
        poLayer->SetExtent(
            CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX),
            CPLAtof(pszMaxY) );
    }

    CPLFree(pszWTKString);

    CSLDestroy( papszVDC );

    return TRUE;
}
コード例 #4
0
ファイル: ozidataset.cpp プロジェクト: Joe-xXx/gdal
GDALDataset *OZIDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if (!Identify(poOpenInfo))
        return NULL;

    GByte abyHeader[14];
    CPLString osImgFilename = poOpenInfo->pszFilename;
    int bIsMap = FALSE;
    if (EQUALN((const char*)poOpenInfo->pabyHeader,
        "OziExplorer Map Data File Version ", 34) )
    {
        char** papszLines = CSLLoad2( poOpenInfo->pszFilename, 1000, 200, NULL );
        if ( !papszLines || CSLCount(papszLines) < 5)
        {
            CSLDestroy(papszLines);
            return FALSE;
        }

        bIsMap = TRUE;

        osImgFilename = papszLines[2];
        VSIStatBufL sStat;
        if (VSIStatL(osImgFilename, &sStat) != 0)
        {
            if (CPLIsFilenameRelative(osImgFilename))
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
            else
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLGetFilename(osImgFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
        }

        CSLDestroy(papszLines);

        GDALOpenInfo oOpenInfo(osImgFilename, GA_ReadOnly);
        if (!Identify(&oOpenInfo))
            return NULL;
        memcpy(abyHeader, oOpenInfo.pabyHeader, 14);
    }
    else
        memcpy(abyHeader, poOpenInfo->pabyHeader, 14);

    int bOzi3 = (abyHeader[0] == 0x80 &&
                 abyHeader[1] == 0x77);

    VSILFILE* fp = VSIFOpenL(osImgFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    OZIDataset* poDS = new OZIDataset();
    poDS->fp = fp;

    if (bIsMap)
    {
        poDS->bReadMapFileSuccess =
            GDALLoadOziMapFile( poOpenInfo->pszFilename,
                                poDS->adfGeoTransform,
                                &poDS->pszWKT,
                                &poDS->nGCPCount,
                                &poDS->pasGCPs );
    }

    GByte nRandomNumber = 0;
    GByte nKeyInit = 0;
    if (bOzi3)
    {
        VSIFSeekL(fp, 14, SEEK_SET);
        VSIFReadL(&nRandomNumber, 1, 1, fp);
        //printf("nRandomNumber = %d\n", nRandomNumber);
        if (nRandomNumber < 0x94)
        {
            delete poDS;
            return NULL;
        }
        VSIFSeekL(fp, 0x93, SEEK_CUR);
        VSIFReadL(&nKeyInit, 1, 1, fp);

        VSIFSeekL(fp, 0, SEEK_SET);
        VSIFReadL(abyHeader, 1, 14, fp);
        OZIDecrypt(abyHeader, 14, nKeyInit);
        if (!(abyHeader[6] == 0x40 &&
           abyHeader[7] == 0x00 &&
           abyHeader[8] == 0x01 &&
           abyHeader[9] == 0x00 &&
           abyHeader[10] == 0x36 &&
           abyHeader[11] == 0x04 &&
           abyHeader[12] == 0x00 &&
           abyHeader[13] == 0x00))
        {
            delete poDS;
            return NULL;
        }

        VSIFSeekL(fp, 14 + 1 + nRandomNumber, SEEK_SET);
        int nMagic = ReadInt(fp, bOzi3, nKeyInit);
        CPLDebug("OZI", "OZI version code : 0x%08X", nMagic);

        poDS->bOzi3 = bOzi3;
    }
    else
    {
        VSIFSeekL(fp, 14, SEEK_SET);
    }

    GByte abyHeader2[40], abyHeader2_Backup[40];
    VSIFReadL(abyHeader2, 40, 1, fp);
    memcpy(abyHeader2_Backup, abyHeader2, 40);

    /* There's apparently a relationship between the nMagic number */
    /* and the nKeyInit, but I'm too lazy to add switch/cases that might */
    /* be not exhaustive, so let's try the 'brute force' attack !!! */
    /* It is much so funny to be able to run one in a few microseconds :-) */
    for(nKeyInit = 0; nKeyInit < 256; nKeyInit ++)
    {
        GByte* pabyHeader2 = abyHeader2;
        if (bOzi3)
            OZIDecrypt(abyHeader2, 40, nKeyInit);

        int nHeaderSize = ReadInt(&pabyHeader2); /* should be 40 */
        poDS->nRasterXSize = ReadInt(&pabyHeader2);
        poDS->nRasterYSize = ReadInt(&pabyHeader2);
        int nDepth = ReadShort(&pabyHeader2); /* should be 1 */
        int nBPP = ReadShort(&pabyHeader2); /* should be 8 */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* pixel number (height * width) : unused */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* ?? 0x100 */
        ReadInt(&pabyHeader2); /* ?? 0x100 */

        if (nHeaderSize != 40 || nDepth != 1 || nBPP != 8)
        {
            if (bOzi3)
            {
                if (nKeyInit != 255)
                {
                    memcpy(abyHeader2, abyHeader2_Backup,40);
                    continue;
                }
                else
                {
                    CPLDebug("OZI", "Cannot decypher 2nd header. Sorry...");
                    delete poDS;
                    return NULL;
                }
            }
            else
            {
                CPLDebug("OZI", "nHeaderSize = %d, nDepth = %d, nBPP = %d",
                        nHeaderSize, nDepth, nBPP);
                delete poDS;
                return NULL;
            }
        }
        else
            break;
    }
    poDS->nKeyInit = nKeyInit;

    int nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        CPLDebug("OZI", "didn't get end of header2 marker");
        delete poDS;
        return NULL;
    }

    poDS->nZoomLevelCount = ReadShort(fp);
    //CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
    if (poDS->nZoomLevelCount < 0 || poDS->nZoomLevelCount >= 256)
    {
        CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
        delete poDS;
        return NULL;
    }

    /* Skip array of zoom level percentage. We don't need it for GDAL */
    VSIFSeekL(fp, sizeof(float) * poDS->nZoomLevelCount, SEEK_CUR);

    nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        /* Some files have 8 extra bytes before the marker. I'm not sure */
        /* what they are used for. So just skeep them and hope that */
        /* we'll find the marker */
        nSeparator = ReadInt(fp);
        nSeparator = ReadInt(fp);
        if (nSeparator != 0x77777777)
        {
            CPLDebug("OZI", "didn't get end of zoom levels marker");
            delete poDS;
            return NULL;
        }
    }

    VSIFSeekL(fp, 0, SEEK_END);
    vsi_l_offset nFileSize = VSIFTellL(fp);
    poDS->nFileSize = nFileSize;
    VSIFSeekL(fp, nFileSize - 4, SEEK_SET);
    int nZoomLevelTableOffset = ReadInt(fp, bOzi3, nKeyInit);
    if (nZoomLevelTableOffset < 0 ||
        (vsi_l_offset)nZoomLevelTableOffset >= nFileSize)
    {
        CPLDebug("OZI", "nZoomLevelTableOffset = %d",
                 nZoomLevelTableOffset);
        delete poDS;
        return NULL;
    }

    VSIFSeekL(fp, nZoomLevelTableOffset, SEEK_SET);

    poDS->panZoomLevelOffsets =
        (int*)CPLMalloc(sizeof(int) * poDS->nZoomLevelCount);
    int i;
    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        poDS->panZoomLevelOffsets[i] = ReadInt(fp, bOzi3, nKeyInit);
        if (poDS->panZoomLevelOffsets[i] < 0 ||
            (vsi_l_offset)poDS->panZoomLevelOffsets[i] >= nFileSize)
        {
            CPLDebug("OZI", "panZoomLevelOffsets[%d] = %d",
                     i, poDS->panZoomLevelOffsets[i]);
            delete poDS;
            return NULL;
        }
    }

    poDS->papoBands =
        (OZIRasterBand**)CPLCalloc(sizeof(OZIRasterBand*), poDS->nZoomLevelCount);

    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        VSIFSeekL(fp, poDS->panZoomLevelOffsets[i], SEEK_SET);
        int nW = ReadInt(fp, bOzi3, nKeyInit);
        int nH = ReadInt(fp, bOzi3, nKeyInit);
        short nTileX = ReadShort(fp, bOzi3, nKeyInit);
        short nTileY = ReadShort(fp, bOzi3, nKeyInit);
        if (i == 0 && (nW != poDS->nRasterXSize || nH != poDS->nRasterYSize))
        {
            CPLDebug("OZI", "zoom[%d] inconsistant dimensions for zoom level 0 : nW=%d, nH=%d, nTileX=%d, nTileY=%d, nRasterXSize=%d, nRasterYSize=%d",
                     i, nW, nH, nTileX, nTileY, poDS->nRasterXSize, poDS->nRasterYSize);
            delete poDS;
            return NULL;
        }
        /* Note (#3895): some files such as world.ozf2 provided with OziExplorer */
        /* expose nTileY=33, but have nH=2048, so only require 32 tiles in vertical dimension. */
        /* So there's apparently one extra and useless tile that will be ignored */
        /* without causing apparent issues */
        /* Some other files have more tile in horizontal direction than needed, so let's */
        /* accept that. But in that case we really need to keep the nTileX value for IReadBlock() */
        /* to work properly */
        if ((nW + 63) / 64 > nTileX || (nH + 63) / 64 > nTileY)
        {
            CPLDebug("OZI", "zoom[%d] unexpected number of tiles : nW=%d, nH=%d, nTileX=%d, nTileY=%d",
                     i, nW, nH, nTileX, nTileY);
            delete poDS;
            return NULL;
        }

        GDALColorTable* poColorTable = new GDALColorTable();
        GByte abyColorTable[256*4];
        VSIFReadL(abyColorTable, 1, 1024, fp);
        if (bOzi3)
            OZIDecrypt(abyColorTable, 1024, nKeyInit);
        int j;
        for(j=0;j<256;j++)
        {
            GDALColorEntry sEntry;
            sEntry.c1 = abyColorTable[4*j + 2];
            sEntry.c2 = abyColorTable[4*j + 1];
            sEntry.c3 = abyColorTable[4*j + 0];
            sEntry.c4 = 255;
            poColorTable->SetColorEntry(j, &sEntry);
        }

        poDS->papoBands[i] = new OZIRasterBand(poDS, i, nW, nH, nTileX, poColorTable);

        if (i > 0)
        {
            GByte* pabyTranslationTable =
                poDS->papoBands[i]->GetIndexColorTranslationTo(poDS->papoBands[0], NULL, NULL);

            delete poDS->papoBands[i]->poColorTable;
            poDS->papoBands[i]->poColorTable = poDS->papoBands[0]->poColorTable->Clone();
            poDS->papoBands[i]->pabyTranslationTable = pabyTranslationTable;
        }

    }

    poDS->SetBand(1, poDS->papoBands[0]);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
コード例 #5
0
char **CPL_STDCALL GDALLoadRPCFile( const char *pszFilename,
                                    char **papszSiblingFiles )

{
/* -------------------------------------------------------------------- */
/*      Try to identify the RPC file in upper or lower case.            */
/* -------------------------------------------------------------------- */
    CPLString osTarget; 

    /* Is this already a _RPC.TXT file ? */
    if (strlen(pszFilename) > 8 && EQUAL(pszFilename + strlen(pszFilename) - 8, "_RPC.TXT"))
        osTarget = pszFilename;
    else
    {
        CPLString osSrcPath = pszFilename;
        CPLString soPt(".");
        size_t found = osSrcPath.rfind(soPt);
        if (found == CPLString::npos)
            return NULL;
        osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt");
        CPLString osTarget = osSrcPath; 

        if( papszSiblingFiles == NULL )
        {
            VSIStatBufL sStatBuf;

            if( VSIStatL( osTarget, &sStatBuf ) != 0 )
            {
                osSrcPath = pszFilename;
                osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT");
                osTarget = osSrcPath; 

                if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                {
                    osSrcPath = pszFilename;
                    osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT");
                    osTarget = osSrcPath; 

                    if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                    {
                        return NULL;
                    }
                }
            }
        }
        else
        {
            int iSibling = CSLFindString( papszSiblingFiles, 
                                        CPLGetFilename(osTarget) );
            if( iSibling < 0 )
                return NULL;

            osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
            osTarget += papszSiblingFiles[iSibling];
        }
    }

/* -------------------------------------------------------------------- */
/*      Read file and parse.                                            */
/* -------------------------------------------------------------------- */
    char **papszLines = CSLLoad2( osTarget, 100, 100, NULL );
    if(!papszLines)
        return NULL;

    char **papszMD = NULL;

    /* From LINE_OFF to HEIGHT_SCALE */
    for(size_t i = 0; i < 19; i += 2 )
    {
        const char *pszRPBVal = CSLFetchNameValue(papszLines, apszRPBMap[i] );
        if( pszRPBVal == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                "%s file found, but missing %s field (and possibly others).",
                osTarget.c_str(), apszRPBMap[i]);
            CSLDestroy( papszMD );
            CSLDestroy( papszLines );
            return NULL;
        }
        else
        {
            papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], pszRPBVal );
        }
    }
       
    /* For LINE_NUM_COEFF, LINE_DEN_COEFF, SAMP_NUM_COEFF, SAMP_DEN_COEFF */
    /* parameters that have 20 values each */
    for(size_t i = 20; apszRPBMap[i] != NULL; i += 2 )
    {
        CPLString soVal;
        for(int j = 1; j <= 20; j++)
        {
            CPLString soRPBMapItem;
            soRPBMapItem.Printf("%s_%d", apszRPBMap[i], j);
            const char *pszRPBVal = CSLFetchNameValue(papszLines, soRPBMapItem.c_str() );
            if( pszRPBVal == NULL )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                    "%s file found, but missing %s field (and possibly others).",
                    osTarget.c_str(), soRPBMapItem.c_str() );
                CSLDestroy( papszMD );
                CSLDestroy( papszLines );
                return NULL;
            }
            else
            {
                soVal += pszRPBVal;
                soVal += " ";
            }
        }
        papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], soVal.c_str() );
    }

    CSLDestroy( papszLines );
    return papszMD;
}