Beispiel #1
0
static const char* BuildFullName(const char* pszTOCFilename,
                                 const char* pszFramePath,
                                 const char* pszFrameName)
{
    char* pszPath;
    if (pszFramePath[0] == '.' &&
        (pszFramePath[1] == '/' ||pszFramePath[1] == '\\'))
        pszPath = CPLStrdup(pszFramePath + 2);
    else
        pszPath = CPLStrdup(pszFramePath);
    for(int i=0;pszPath[i] != '\0';i++)
    {
        if (pszPath[i] == '\\')
            pszPath[i] = '/';
    }
    const char* pszName = CPLFormFilename(pszPath, pszFrameName, NULL);
    CPLFree(pszPath);
    pszPath = NULL;
    const char* pszTOCPath = CPLGetDirname(pszTOCFilename);
    const char* pszFirstSlashInName = strchr(pszName, '/');
    if (pszFirstSlashInName != NULL)
    {
        int nFirstDirLen = pszFirstSlashInName - pszName;
        if ((int)strlen(pszTOCPath) >= nFirstDirLen + 1 &&
            (pszTOCPath[strlen(pszTOCPath) - (nFirstDirLen + 1)] == '/' ||
                pszTOCPath[strlen(pszTOCPath) - (nFirstDirLen + 1)] == '\\') &&
            strncmp(pszTOCPath + strlen(pszTOCPath) - nFirstDirLen, pszName, nFirstDirLen) == 0)
        {
            pszTOCPath = CPLGetDirname(pszTOCPath);
        }
    }
    return CPLProjectRelativeFilename(pszTOCPath, pszName);
}
/**
 * GDALMDReaderOrbView()
 */
GDALMDReaderOrbView::GDALMDReaderOrbView(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    m_osIMDSourceFilename = GDALFindAssociatedFile( pszPath, "PVL",
                                                    papszSiblingFiles, 0 );

    const char* pszBaseName = CPLGetBasename(pszPath);
    const char* pszDirName = CPLGetDirname(pszPath);

    const char* pszRPBSourceFilename = CPLFormFilename( pszDirName,
                                                        CPLSPrintf("%s_rpc",
                                                        pszBaseName),
                                                        "txt" );
    if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
    {
        m_osRPBSourceFilename = pszRPBSourceFilename;
    }
    else
    {
        pszRPBSourceFilename = CPLFormFilename( pszDirName, CPLSPrintf("%s_RPC",
                                                pszBaseName), "TXT" );
        if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPBSourceFilename;
        }
    }

    if( m_osIMDSourceFilename.size() )
        CPLDebug( "MDReaderOrbView", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
    if( m_osRPBSourceFilename.size() )
        CPLDebug( "MDReaderOrbView", "RPB Filename: %s",
                  m_osRPBSourceFilename.c_str() );
}
/**
 * GDALMDReaderRapidEye()
 */
GDALMDReaderRapidEye::GDALMDReaderRapidEye(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    const char* pszDirName = CPLGetDirname(pszPath);
    const char* pszBaseName = CPLGetBasename(pszPath);

    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                        CPLSPrintf("%s_metadata",
                                                        pszBaseName), "xml" );
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osXMLSourceFilename = pszIMDSourceFilename;
    }
    else
    {
        pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                CPLSPrintf("%s_METADATA",
                                                pszBaseName), "XML" );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osXMLSourceFilename = pszIMDSourceFilename;
        }
    }

    if(m_osXMLSourceFilename.size())
        CPLDebug( "MDReaderRapidEye", "XML Filename: %s",
              m_osXMLSourceFilename.c_str() );
}
Beispiel #4
0
string CRFile::GetDirName(const string& strFileName)
{
	const char* pchDirName = CPLGetDirname(strFileName.c_str());
	if(strlen(pchDirName) > 0)
		return pchDirName;

	return "";
}
Beispiel #5
0
/**
 * GDALMDReaderSpot()
 */
GDALMDReaderSpot::GDALMDReaderSpot(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderPleiades(pszPath, papszSiblingFiles)
{
    const char* pszIMDSourceFilename;
    const char* pszDirName = CPLGetDirname(pszPath);

    if(m_osIMDSourceFilename.empty())
    {
        pszIMDSourceFilename = CPLFormFilename( pszDirName, "METADATA.DIM", NULL );

        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
        else
        {
            pszIMDSourceFilename = CPLFormFilename( pszDirName, "metadata.dim", NULL );
            if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
            {
                m_osIMDSourceFilename = pszIMDSourceFilename;
            }
        }
    }

    // if the file name ended on METADATA.DIM
    // Linux specific
    // example: R2_CAT_091028105025131_1\METADATA.DIM
    if(m_osIMDSourceFilename.empty())
    {
        if(EQUAL(CPLGetFilename(pszPath), "IMAGERY.TIF"))
        {
            pszIMDSourceFilename = CPLSPrintf( "%s\\METADATA.DIM",
                                                           CPLGetPath(pszPath));

            if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
            {
                m_osIMDSourceFilename = pszIMDSourceFilename;
            }
            else
            {
                pszIMDSourceFilename = CPLSPrintf( "%s\\metadata.dim",
                                                           CPLGetPath(pszPath));
                if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
                {
                    m_osIMDSourceFilename = pszIMDSourceFilename;
                }
            }
        }
    }

    if(m_osIMDSourceFilename.size())
        CPLDebug( "MDReaderSpot", "IMD Filename: %s",
              m_osIMDSourceFilename.c_str() );
}
Beispiel #6
0
/**
 * GDALMDReaderLandsat()
 */
GDALMDReaderLandsat::GDALMDReaderLandsat(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    const char* pszBaseName = CPLGetBasename(pszPath);
    const char* pszDirName = CPLGetDirname(pszPath);
    size_t nBaseNameLen = strlen(pszBaseName);
    if( nBaseNameLen > 511 )
        return;

    // split file name by _B or _b
    char szMetadataName[512] = {0};
    size_t i;
    for(i = 0; i < nBaseNameLen; i++)
    {
        szMetadataName[i] = pszBaseName[i];
        if(STARTS_WITH_CI(pszBaseName + i, "_B") || STARTS_WITH_CI(pszBaseName + i, "_b"))
        {
            break;
        }
    }

    // form metadata file name
    CPLStrlcpy(szMetadataName + i, "_MTL.txt", 9);

    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                        szMetadataName, NULL );
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }
    else
    {
        CPLStrlcpy(szMetadataName + i, "_MTL.TXT", 9);
        pszIMDSourceFilename = CPLFormFilename( pszDirName, szMetadataName, NULL );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    if( !m_osIMDSourceFilename.empty() )
        CPLDebug( "MDReaderLandsat", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
}
Beispiel #7
0
void VRTRawRasterBand::GetFileList( char*** ppapszFileList, int *pnSize,
                                    int *pnMaxSize, CPLHashSet* hSetFiles )
{
    if (m_pszSourceFilename == NULL)
        return;

/* -------------------------------------------------------------------- */
/*      Is it already in the list ?                                     */
/* -------------------------------------------------------------------- */
    CPLString osSourceFilename;
    if( m_bRelativeToVRT && strlen(poDS->GetDescription()) > 0 )
        osSourceFilename = CPLFormFilename(
              CPLGetDirname(poDS->GetDescription()), m_pszSourceFilename, NULL );
    else
        osSourceFilename = m_pszSourceFilename;

    if( CPLHashSetLookup(hSetFiles, osSourceFilename) != NULL )
        return;

/* -------------------------------------------------------------------- */
/*      Grow array if necessary                                         */
/* -------------------------------------------------------------------- */
    if (*pnSize + 1 >= *pnMaxSize)
    {
        *pnMaxSize = 2 + 2 * (*pnMaxSize);
        *ppapszFileList = reinterpret_cast<char **>(
            CPLRealloc( *ppapszFileList, sizeof(char*) * (*pnMaxSize) ) );
    }

/* -------------------------------------------------------------------- */
/*      Add the string to the list                                      */
/* -------------------------------------------------------------------- */
    (*ppapszFileList)[*pnSize] = CPLStrdup(osSourceFilename);
    (*ppapszFileList)[(*pnSize + 1)] = NULL;
    CPLHashSetInsert(hSetFiles, (*ppapszFileList)[*pnSize]);

    (*pnSize)++;

    VRTRasterBand::GetFileList( ppapszFileList, pnSize,
                                pnMaxSize, hSetFiles);
}
Beispiel #8
0
static CPLString GetJsonFilename(CPLString pszFilename)
{
    return CPLSPrintf( "%s/%s.json", CPLGetDirname(pszFilename),
                       CPLGetBasename(pszFilename) );
}
Beispiel #9
0
OGRErr OGRCSVLayer::CreateFeature( OGRFeature *poNewFeature )

{
    int iField;

    if( !bInWriteMode )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
            "The CreateFeature() operation is not permitted on a read-only CSV." );
        return OGRERR_FAILURE;
    }

    /* If we need rewind, it means that we have just written a feature before */
    /* so there's no point seeking to the end of the file, as we're already */
    /* at the end */
    int bNeedSeekEnd = !bNeedRewindBeforeRead;

    bNeedRewindBeforeRead = TRUE;

/* -------------------------------------------------------------------- */
/*      Write field names if we haven't written them yet.               */
/*      Write .csvt file if needed                                      */
/* -------------------------------------------------------------------- */
    if( !bHasFieldNames )
    {
      bHasFieldNames = TRUE;
      bNeedSeekEnd = FALSE;

      for(int iFile=0;iFile<((bCreateCSVT) ? 2 : 1);iFile++)
      {
        VSILFILE* fpCSVT = NULL;
        if (bCreateCSVT && iFile == 0)
        {
            char* pszDirName = CPLStrdup(CPLGetDirname(pszFilename));
            char* pszBaseName = CPLStrdup(CPLGetBasename(pszFilename));
            fpCSVT = VSIFOpenL(CPLFormFilename(pszDirName, pszBaseName, ".csvt"), "wb");
            CPLFree(pszDirName);
            CPLFree(pszBaseName);
        }
        else
        {
            if( strncmp(pszFilename, "/vsistdout/", 11) == 0 ||
                strncmp(pszFilename, "/vsizip/", 8) == 0 )
                fpCSV = VSIFOpenL( pszFilename, "wb" );
            else
                fpCSV = VSIFOpenL( pszFilename, "w+b" );

            if( fpCSV == NULL )
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                        "Failed to create %s:\n%s",
                        pszFilename, VSIStrerror( errno ) );

                return NULL;
            }
        }

        if (eGeometryFormat == OGR_CSV_GEOM_AS_WKT)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "%s", "WKT");
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "String");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "X%cY%cZ", chDelimiter, chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_XY)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "X%cY", chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_YX)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "Y%cX", chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }

        for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
        {
            char *pszEscaped;

            if( iField > 0 )
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }

            pszEscaped = 
                CPLEscapeString( poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), 
                                 -1, CPLES_CSV );

            if (fpCSV) VSIFPrintfL( fpCSV, "%s", pszEscaped );
            CPLFree( pszEscaped );

            if (fpCSVT)
            {
                switch( poFeatureDefn->GetFieldDefn(iField)->GetType() )
                {
                    case OFTInteger:  VSIFPrintfL( fpCSVT, "%s", "Integer"); break;
                    case OFTReal:     VSIFPrintfL( fpCSVT, "%s", "Real"); break;
                    case OFTDate:     VSIFPrintfL( fpCSVT, "%s", "Date"); break;
                    case OFTTime:     VSIFPrintfL( fpCSVT, "%s", "Time"); break;
                    case OFTDateTime: VSIFPrintfL( fpCSVT, "%s", "DateTime"); break;
                    default:          VSIFPrintfL( fpCSVT, "%s", "String"); break;
                }

                int nWidth = poFeatureDefn->GetFieldDefn(iField)->GetWidth();
                int nPrecision = poFeatureDefn->GetFieldDefn(iField)->GetPrecision();
                if (nWidth != 0)
                {
                    if (nPrecision != 0)
                        VSIFPrintfL( fpCSVT, "(%d.%d)", nWidth, nPrecision);
                    else
                        VSIFPrintfL( fpCSVT, "(%d)", nWidth);
                }
            }
        }
        if( bUseCRLF )
        {
            if (fpCSV) VSIFPutcL( 13, fpCSV );
            if (fpCSVT) VSIFPutcL( 13, fpCSVT );
        }
        if (fpCSV) VSIFPutcL( '\n', fpCSV );
        if (fpCSVT) VSIFPutcL( '\n', fpCSVT );
        if (fpCSVT) VSIFCloseL(fpCSVT);
      }
    }

    if (fpCSV == NULL)
        return OGRERR_FAILURE;

/* -------------------------------------------------------------------- */
/*      Make sure we are at the end of the file.                        */
/* -------------------------------------------------------------------- */
    if (bNeedSeekEnd)
    {
        if (bFirstFeatureAppendedDuringSession)
        {
            /* Add a newline character to the end of the file if necessary */
            bFirstFeatureAppendedDuringSession = FALSE;
            VSIFSeekL( fpCSV, 0, SEEK_END );
            VSIFSeekL( fpCSV, VSIFTellL(fpCSV) - 1, SEEK_SET);
            char chLast;
            VSIFReadL( &chLast, 1, 1, fpCSV );
            VSIFSeekL( fpCSV, 0, SEEK_END );
            if (chLast != '\n')
            {
                if( bUseCRLF )
                    VSIFPutcL( 13, fpCSV );
                VSIFPutcL( '\n', fpCSV );
            }
        }
        else
        {
            VSIFSeekL( fpCSV, 0, SEEK_END );
        }
    }

/* -------------------------------------------------------------------- */
/*      Write out the geometry                                          */
/* -------------------------------------------------------------------- */
    if (eGeometryFormat == OGR_CSV_GEOM_AS_WKT)
    {
        OGRGeometry     *poGeom = poNewFeature->GetGeometryRef();
        char* pszWKT = NULL;
        if (poGeom && poGeom->exportToWkt(&pszWKT) == OGRERR_NONE)
        {
            VSIFPrintfL( fpCSV, "\"%s\"", pszWKT);
        }
        else
        {
            VSIFPrintfL( fpCSV, "\"\"");
        }
        CPLFree(pszWKT);
        if (poFeatureDefn->GetFieldCount() > 0)
            VSIFPrintfL( fpCSV, "%c", chDelimiter);
    }
    else if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ ||
             eGeometryFormat == OGR_CSV_GEOM_AS_XY ||
             eGeometryFormat == OGR_CSV_GEOM_AS_YX)
    {
        OGRGeometry     *poGeom = poNewFeature->GetGeometryRef();
        if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
        {
            OGRPoint* poPoint = (OGRPoint*) poGeom;
            char szBuffer[75];
            if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ )
                OGRMakeWktCoordinate(szBuffer, poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3);
            else if (eGeometryFormat == OGR_CSV_GEOM_AS_XY )
                OGRMakeWktCoordinate(szBuffer, poPoint->getX(), poPoint->getY(), 0, 2);
            else
                OGRMakeWktCoordinate(szBuffer, poPoint->getY(), poPoint->getX(), 0, 2);
            char* pc = szBuffer;
            while(*pc != '\0')
            {
                if (*pc == ' ')
                    *pc = chDelimiter;
                pc ++;
            }
            VSIFPrintfL( fpCSV, "%s", szBuffer );
        }
        else
        {
            VSIFPrintfL( fpCSV, "%c", chDelimiter );
            if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ)
                VSIFPrintfL( fpCSV, "%c", chDelimiter );
        }
        if (poFeatureDefn->GetFieldCount() > 0)
            VSIFPrintfL( fpCSV, "%c", chDelimiter );
    }

/* -------------------------------------------------------------------- */
/*      Write out all the field values.                                 */
/* -------------------------------------------------------------------- */
    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {
        char *pszEscaped;
        
        if( iField > 0 )
            VSIFPrintfL( fpCSV, "%c", chDelimiter );
        
        pszEscaped = 
            CPLEscapeString( poNewFeature->GetFieldAsString(iField),
                            -1, CPLES_CSV );

        if (poFeatureDefn->GetFieldDefn(iField)->GetType() == OFTReal)
        {
            /* Use point as decimal separator */
            char* pszComma = strchr(pszEscaped, ',');
            if (pszComma)
                *pszComma = '.';
        }

        VSIFWriteL( pszEscaped, 1, strlen(pszEscaped), fpCSV );
        CPLFree( pszEscaped );
    }
    
    if( bUseCRLF )
        VSIFPutcL( 13, fpCSV );
    VSIFPutcL( '\n', fpCSV );

    return OGRERR_NONE;
}
Beispiel #10
0
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, 
                          VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode,
                          char chDelimiter, const char* pszNfdcGeomField,
                          const char* pszGeonamesGeomFieldPrefix)

{
    fpCSV = fp;

    iWktGeomReadField = -1;
    iNfdcLatitudeS = iNfdcLongitudeS = -1;
    iLatitudeField = iLongitudeField = -1;
    this->bInWriteMode = bInWriteMode;
    this->bNew = bNew;
    this->pszFilename = CPLStrdup(pszFilename);
    this->chDelimiter = chDelimiter;

    bFirstFeatureAppendedDuringSession = TRUE;
    bUseCRLF = FALSE;
    bNeedRewindBeforeRead = FALSE;
    eGeometryFormat = OGR_CSV_GEOM_NONE;

    nNextFID = 1;

    poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbNone );

    bCreateCSVT = FALSE;
    bDontHonourStrings = FALSE;

    nTotalFeatures = -1;

/* -------------------------------------------------------------------- */
/*      If this is not a new file, read ahead to establish if it is     */
/*      already in CRLF (DOS) mode, or just a normal unix CR mode.      */
/* -------------------------------------------------------------------- */
    if( !bNew && bInWriteMode )
    {
        int nBytesRead = 0;
        char chNewByte;

        while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 )
        {
            if( chNewByte == 13 )
            {
                bUseCRLF = TRUE;
                break;
            }
        }
        VSIRewindL( fpCSV );
    }

/* -------------------------------------------------------------------- */
/*      Check if the first record seems to be field definitions or      */
/*      not.  We assume it is field definitions if none of the          */
/*      values are strictly numeric.                                    */
/* -------------------------------------------------------------------- */
    char **papszTokens = NULL;
    int nFieldCount=0, iField;
    CPLValueType eType;

    if( !bNew )
    {
        papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE );
        nFieldCount = CSLCount( papszTokens );
        bHasFieldNames = TRUE;
    }
    else
        bHasFieldNames = FALSE;

    for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ )
    {
        eType = CPLGetValueType(papszTokens[iField]);
        if ( eType == CPL_VALUE_INTEGER ||
             eType == CPL_VALUE_REAL ) {
            /* we have a numeric field, therefore do not consider the first line as field names */
            bHasFieldNames = FALSE;
        }
    }

    if( !bNew && !bHasFieldNames )
        VSIRewindL( fpCSV );

/* -------------------------------------------------------------------- */
/*      Check for geonames.org tables                                   */
/* -------------------------------------------------------------------- */
    if( !bHasFieldNames && nFieldCount == 19 )
    {
        if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER &&
            CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL &&
            CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL &&
            CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 &&
            CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180)
        {
            bHasFieldNames = TRUE;
            CSLDestroy(papszTokens);
            papszTokens = NULL;

            static const struct {
                const char* pszName;
                OGRFieldType eType;
            }
            asGeonamesFieldDesc[] =
            {
                { "GEONAMEID", OFTString },
                { "NAME", OFTString },
                { "ASCIINAME", OFTString },
                { "ALTNAMES", OFTString },
                { "LATITUDE", OFTReal },
                { "LONGITUDE", OFTReal },
                { "FEATCLASS", OFTString },
                { "FEATCODE", OFTString },
                { "COUNTRY", OFTString },
                { "CC2", OFTString },
                { "ADMIN1", OFTString },
                { "ADMIN2", OFTString },
                { "ADMIN3", OFTString },
                { "ADMIN4", OFTString },
                { "POPULATION", OFTReal },
                { "ELEVATION", OFTInteger },
                { "GTOPO30", OFTInteger },
                { "TIMEZONE", OFTString },
                { "MODDATE", OFTString }
            };
            for(iField = 0; iField < nFieldCount; iField++)
            {
                OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName,
                                        asGeonamesFieldDesc[iField].eType);
                poFeatureDefn->AddFieldDefn(&oFieldDefn);
            }

            iLatitudeField = 4;
            iLongitudeField = 5;

            nFieldCount = 0;
        }
    }


/* -------------------------------------------------------------------- */
/*      Search a csvt file for types                                */
/* -------------------------------------------------------------------- */
    char** papszFieldTypes = NULL;
    if (!bNew) {
        char* dname = strdup(CPLGetDirname(pszFilename));
        char* fname = strdup(CPLGetBasename(pszFilename));
        VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r");
        free(dname);
        free(fname);
        if (fpCSVT!=NULL) {
            VSIRewindL(fpCSVT);
            papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE);
            VSIFCloseL(fpCSVT);
        }
    }
    

/* -------------------------------------------------------------------- */
/*      Build field definitions.                                        */
/* -------------------------------------------------------------------- */
    for( iField = 0; iField < nFieldCount; iField++ )
    {
        char *pszFieldName = NULL;
        char szFieldNameBuffer[100];

        if( bHasFieldNames )
        {
            pszFieldName = papszTokens[iField];

            // trim white space. 
            while( *pszFieldName == ' ' )
                pszFieldName++;

            while( pszFieldName[0] != '\0' 
                && pszFieldName[strlen(pszFieldName)-1] == ' ' )
                pszFieldName[strlen(pszFieldName)-1] = '\0';

            if (*pszFieldName == '\0')
                pszFieldName = NULL;
        }

        if (pszFieldName == NULL)
        {
            pszFieldName = szFieldNameBuffer;
            sprintf( szFieldNameBuffer, "field_%d", iField+1 );
        }

        OGRFieldDefn oField(pszFieldName, OFTString);
        if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) {

            char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '(');
            if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] &&
                pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9')
            {
                int nWidth = 0;
                int nPrecision = 0;

                char* pszDot = strchr(pszLeftParenthesis, '.');
                if (pszDot) *pszDot = 0;
                *pszLeftParenthesis = 0;

                if (pszLeftParenthesis[-1] == ' ')
                    pszLeftParenthesis[-1] = 0;

                nWidth = atoi(pszLeftParenthesis+1);
                if (pszDot)
                    nPrecision = atoi(pszDot+1);

                oField.SetWidth(nWidth);
                oField.SetPrecision(nPrecision);
            }

            if (EQUAL(papszFieldTypes[iField], "Integer"))
                oField.SetType(OFTInteger);
            else if (EQUAL(papszFieldTypes[iField], "Real"))
                oField.SetType(OFTReal);
            else if (EQUAL(papszFieldTypes[iField], "String"))
                oField.SetType(OFTString);
            else if (EQUAL(papszFieldTypes[iField], "Date"))
                oField.SetType(OFTDate); 
            else if (EQUAL(papszFieldTypes[iField], "Time"))
                oField.SetType(OFTTime);
            else if (EQUAL(papszFieldTypes[iField], "DateTime"))
                oField.SetType(OFTDateTime);
            else
                CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]);
        }

        if( EQUAL(oField.GetNameRef(),"WKT")
            && oField.GetType() == OFTString 
            && iWktGeomReadField == -1 )
        {
            iWktGeomReadField = iField;
            poFeatureDefn->SetGeomType( wkbUnknown );
        }

        /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */
        if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") )
            iNfdcLatitudeS = iField;
        else if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") )
            iNfdcLongitudeS = iField;

        /* GNIS specific */
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) )
        {
            oField.SetType(OFTReal);
            iLatitudeField = iField;
        }
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) )
        {
            oField.SetType(OFTReal);
            iLongitudeField = iField;
        }

        poFeatureDefn->AddFieldDefn( &oField );

    }

    if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 )
    {
        bDontHonourStrings = TRUE;
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    else if ( iLatitudeField != -1 && iLongitudeField != -1 )
    {
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    
    CSLDestroy( papszTokens );
    CSLDestroy( papszFieldTypes );
}
Beispiel #11
0
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, 
                          VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode,
                          char chDelimiter, const char* pszNfdcGeomField,
                          const char* pszGeonamesGeomFieldPrefix)

{
    fpCSV = fp;

    iWktGeomReadField = -1;
    iNfdcLatitudeS = iNfdcLongitudeS = -1;
    iLatitudeField = iLongitudeField = -1;
    this->bInWriteMode = bInWriteMode;
    this->bNew = bNew;
    this->pszFilename = CPLStrdup(pszFilename);
    this->chDelimiter = chDelimiter;

    bFirstFeatureAppendedDuringSession = TRUE;
    bUseCRLF = FALSE;
    bNeedRewindBeforeRead = FALSE;
    eGeometryFormat = OGR_CSV_GEOM_NONE;

    nNextFID = 1;

    poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbNone );

    bCreateCSVT = FALSE;
    bDontHonourStrings = FALSE;
    bWriteBOM = FALSE;

    bIsEurostatTSV = FALSE;
    nEurostatDims = 0;

    nTotalFeatures = -1;

/* -------------------------------------------------------------------- */
/*      If this is not a new file, read ahead to establish if it is     */
/*      already in CRLF (DOS) mode, or just a normal unix CR mode.      */
/* -------------------------------------------------------------------- */
    if( !bNew && bInWriteMode )
    {
        int nBytesRead = 0;
        char chNewByte;

        while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 )
        {
            if( chNewByte == 13 )
            {
                bUseCRLF = TRUE;
                break;
            }
            nBytesRead ++;
        }
        VSIRewindL( fpCSV );
    }

/* -------------------------------------------------------------------- */
/*      Check if the first record seems to be field definitions or      */
/*      not.  We assume it is field definitions if none of the          */
/*      values are strictly numeric.                                    */
/* -------------------------------------------------------------------- */
    char **papszTokens = NULL;
    int nFieldCount=0, iField;
    CPLValueType eType;

    if( !bNew )
    {
        const char *pszLine = NULL;
        char szDelimiter[2];
        szDelimiter[0] = chDelimiter; szDelimiter[1] = '\0';

        pszLine = CPLReadLineL( fpCSV );
        if ( pszLine != NULL )
        {
            /* Detect and remove UTF-8 BOM marker if found (#4623) */
            if (pszLine[0] == (char)0xEF &&
                pszLine[1] == (char)0xBB &&
                pszLine[2] == (char)0xBF)
            {
                pszLine += 3;
            }

            /* tokenize the strings and preserve quotes, so we can separate string from numeric */
            /* this is only used in the test for bHasFeldNames (bug #4361) */
            papszTokens = CSLTokenizeString2( pszLine, szDelimiter, 
                                              (CSLT_HONOURSTRINGS |
                                               CSLT_ALLOWEMPTYTOKENS |
                                               CSLT_PRESERVEQUOTES) );
            nFieldCount = CSLCount( papszTokens );
            bHasFieldNames = TRUE;

            for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ )
            {
                eType = CPLGetValueType(papszTokens[iField]);
                if ( (eType == CPL_VALUE_INTEGER ||
                      eType == CPL_VALUE_REAL) ) {
                    /* we have a numeric field, therefore do not consider the first line as field names */
                    bHasFieldNames = FALSE;
                }
            }

            CPLString osExt = OGRCSVDataSource::GetRealExtension(pszFilename);

            /* Eurostat .tsv files */
            if( EQUAL(osExt, "tsv") && nFieldCount > 1 &&
                strchr(papszTokens[0], ',') != NULL && strchr(papszTokens[0], '\\') != NULL )
            {
                bHasFieldNames = TRUE;
                bIsEurostatTSV = TRUE;
            }

            /* tokenize without quotes to get the actual values */
            CSLDestroy( papszTokens );
            // papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE );   
            papszTokens = CSLTokenizeString2( pszLine, szDelimiter, 
                                              (CSLT_HONOURSTRINGS |
                                               CSLT_ALLOWEMPTYTOKENS));
            nFieldCount = CSLCount( papszTokens );
        }
    }
    else
        bHasFieldNames = FALSE;

    if( !bNew && !bHasFieldNames )
        VSIRewindL( fpCSV );

/* -------------------------------------------------------------------- */
/*      Check for geonames.org tables                                   */
/* -------------------------------------------------------------------- */
    if( !bHasFieldNames && nFieldCount == 19 )
    {
        if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER &&
            CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL &&
            CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL &&
            CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 &&
            CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180)
        {
            bHasFieldNames = TRUE;
            CSLDestroy(papszTokens);
            papszTokens = NULL;

            static const struct {
                const char* pszName;
                OGRFieldType eType;
            }
            asGeonamesFieldDesc[] =
            {
                { "GEONAMEID", OFTString },
                { "NAME", OFTString },
                { "ASCIINAME", OFTString },
                { "ALTNAMES", OFTString },
                { "LATITUDE", OFTReal },
                { "LONGITUDE", OFTReal },
                { "FEATCLASS", OFTString },
                { "FEATCODE", OFTString },
                { "COUNTRY", OFTString },
                { "CC2", OFTString },
                { "ADMIN1", OFTString },
                { "ADMIN2", OFTString },
                { "ADMIN3", OFTString },
                { "ADMIN4", OFTString },
                { "POPULATION", OFTReal },
                { "ELEVATION", OFTInteger },
                { "GTOPO30", OFTInteger },
                { "TIMEZONE", OFTString },
                { "MODDATE", OFTString }
            };
            for(iField = 0; iField < nFieldCount; iField++)
            {
                OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName,
                                        asGeonamesFieldDesc[iField].eType);
                poFeatureDefn->AddFieldDefn(&oFieldDefn);
            }

            iLatitudeField = 4;
            iLongitudeField = 5;

            nFieldCount = 0;
        }
    }


/* -------------------------------------------------------------------- */
/*      Search a csvt file for types                                */
/* -------------------------------------------------------------------- */
    char** papszFieldTypes = NULL;
    if (!bNew) {
        char* dname = strdup(CPLGetDirname(pszFilename));
        char* fname = strdup(CPLGetBasename(pszFilename));
        VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r");
        free(dname);
        free(fname);
        if (fpCSVT!=NULL) {
            VSIRewindL(fpCSVT);
            papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE);
            VSIFCloseL(fpCSVT);
        }
    }
    

/* -------------------------------------------------------------------- */
/*      Build field definitions.                                        */
/* -------------------------------------------------------------------- */
    for( iField = 0; !bIsEurostatTSV && iField < nFieldCount; iField++ )
    {
        char *pszFieldName = NULL;
        char szFieldNameBuffer[100];

        if( bHasFieldNames )
        {
            pszFieldName = papszTokens[iField];

            // trim white space. 
            while( *pszFieldName == ' ' )
                pszFieldName++;

            while( pszFieldName[0] != '\0' 
                && pszFieldName[strlen(pszFieldName)-1] == ' ' )
                pszFieldName[strlen(pszFieldName)-1] = '\0';

            if (*pszFieldName == '\0')
                pszFieldName = NULL;
        }

        if (pszFieldName == NULL)
        {
            /* Re-read single column CSV files that have a trailing comma */
            /* in the header line */
            if( iField == 1 && nFieldCount == 2 && papszTokens[1][0] == '\0' )
            {
                nFieldCount = 1;
                break;
            }
            pszFieldName = szFieldNameBuffer;
            sprintf( szFieldNameBuffer, "field_%d", iField+1 );
        }

        OGRFieldDefn oField(pszFieldName, OFTString);
        if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) {

            char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '(');
            if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] &&
                pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9')
            {
                int nWidth = 0;
                int nPrecision = 0;

                char* pszDot = strchr(pszLeftParenthesis, '.');
                if (pszDot) *pszDot = 0;
                *pszLeftParenthesis = 0;

                if (pszLeftParenthesis[-1] == ' ')
                    pszLeftParenthesis[-1] = 0;

                nWidth = atoi(pszLeftParenthesis+1);
                if (pszDot)
                    nPrecision = atoi(pszDot+1);

                oField.SetWidth(nWidth);
                oField.SetPrecision(nPrecision);
            }

            if (EQUAL(papszFieldTypes[iField], "Integer"))
                oField.SetType(OFTInteger);
            else if (EQUAL(papszFieldTypes[iField], "Real"))
                oField.SetType(OFTReal);
            else if (EQUAL(papszFieldTypes[iField], "String"))
                oField.SetType(OFTString);
            else if (EQUAL(papszFieldTypes[iField], "Date"))
                oField.SetType(OFTDate); 
            else if (EQUAL(papszFieldTypes[iField], "Time"))
                oField.SetType(OFTTime);
            else if (EQUAL(papszFieldTypes[iField], "DateTime"))
                oField.SetType(OFTDateTime);
            else
                CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]);
        }

        if( EQUAL(oField.GetNameRef(),"WKT")
            && oField.GetType() == OFTString 
            && iWktGeomReadField == -1 )
        {
            iWktGeomReadField = iField;
            poFeatureDefn->SetGeomType( wkbUnknown );
        }

        /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */
        if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") )
            iNfdcLatitudeS = iField;
        else if ( pszNfdcGeomField != NULL &&
                  EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) &&
                  EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") )
            iNfdcLongitudeS = iField;

        /* GNIS specific */
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) )
        {
            oField.SetType(OFTReal);
            iLatitudeField = iField;
        }
        else if ( pszGeonamesGeomFieldPrefix != NULL &&
                  EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) &&
                  (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") ||
                   EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) )
        {
            oField.SetType(OFTReal);
            iLongitudeField = iField;
        }

        poFeatureDefn->AddFieldDefn( &oField );

    }

    if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 )
    {
        bDontHonourStrings = TRUE;
        poFeatureDefn->SetGeomType( wkbPoint );
    }
    else if ( iLatitudeField != -1 && iLongitudeField != -1 )
    {
        poFeatureDefn->SetGeomType( wkbPoint );
    }

/* -------------------------------------------------------------------- */
/*      Build field definitions for Eurostat TSV files.                 */
/* -------------------------------------------------------------------- */

    CPLString osSeqDim;
    for( iField = 0; bIsEurostatTSV && iField < nFieldCount; iField++ )
    {
        if( iField == 0 )
        {
            char** papszDims = CSLTokenizeString2( papszTokens[0], ",\\", 0 );
            nEurostatDims = CSLCount(papszDims) - 1;
            for(int iSubField = 0; iSubField < nEurostatDims; iSubField++)
            {
                OGRFieldDefn oField(papszDims[iSubField], OFTString);
                poFeatureDefn->AddFieldDefn( &oField );
            }

            osSeqDim = papszDims[nEurostatDims];
            CSLDestroy(papszDims);
        }
        else
        {
            if( papszTokens[iField][0] != '\0' 
                && papszTokens[iField][strlen(papszTokens[iField])-1] == ' ' )
                papszTokens[iField][strlen(papszTokens[iField])-1] = '\0';

            OGRFieldDefn oField(CPLSPrintf("%s_%s", osSeqDim.c_str(), papszTokens[iField]), OFTReal);
            poFeatureDefn->AddFieldDefn( &oField );

            OGRFieldDefn oField2(CPLSPrintf("%s_%s_flag", osSeqDim.c_str(), papszTokens[iField]), OFTString);
            poFeatureDefn->AddFieldDefn( &oField2 );
        }
    }

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */

    CSLDestroy( papszTokens );
    CSLDestroy( papszFieldTypes );
}
Beispiel #12
0
OGRErr OGRCSVLayer::WriteHeader()
{
    if( !bNew )
        return OGRERR_NONE;

/* -------------------------------------------------------------------- */
/*      Write field names if we haven't written them yet.               */
/*      Write .csvt file if needed                                      */
/* -------------------------------------------------------------------- */
    bNew = FALSE;
    bHasFieldNames = TRUE;

    for(int iFile=0;iFile<((bCreateCSVT) ? 2 : 1);iFile++)
    {
        VSILFILE* fpCSVT = NULL;
        if (bCreateCSVT && iFile == 0)
        {
            char* pszDirName = CPLStrdup(CPLGetDirname(pszFilename));
            char* pszBaseName = CPLStrdup(CPLGetBasename(pszFilename));
            fpCSVT = VSIFOpenL(CPLFormFilename(pszDirName, pszBaseName, ".csvt"), "wb");
            CPLFree(pszDirName);
            CPLFree(pszBaseName);
        }
        else
        {
            if( strncmp(pszFilename, "/vsistdout/", 11) == 0 ||
                strncmp(pszFilename, "/vsizip/", 8) == 0 )
                fpCSV = VSIFOpenL( pszFilename, "wb" );
            else
                fpCSV = VSIFOpenL( pszFilename, "w+b" );

            if( fpCSV == NULL )
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "Failed to create %s:\n%s",
                          pszFilename, VSIStrerror( errno ) );
                return OGRERR_FAILURE;
            }
        }

        if (bWriteBOM && fpCSV)
        {
            VSIFWriteL("\xEF\xBB\xBF", 1, 3, fpCSV);
        }

        if (eGeometryFormat == OGR_CSV_GEOM_AS_WKT)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "%s", "WKT");
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "String");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "X%cY%cZ", chDelimiter, chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_XY)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "X%cY", chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }
        else if (eGeometryFormat == OGR_CSV_GEOM_AS_YX)
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "Y%cX", chDelimiter);
            if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real");
            if (poFeatureDefn->GetFieldCount() > 0)
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }
        }

        for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
        {
            char *pszEscaped;

            if( iField > 0 )
            {
                if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
                if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ",");
            }

            pszEscaped = 
                CPLEscapeString( poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), 
                                 -1, CPLES_CSV );

            if (fpCSV) VSIFPrintfL( fpCSV, "%s", pszEscaped );
            CPLFree( pszEscaped );

            if (fpCSVT)
            {
                switch( poFeatureDefn->GetFieldDefn(iField)->GetType() )
                {
                  case OFTInteger:  VSIFPrintfL( fpCSVT, "%s", "Integer"); break;
                  case OFTReal:     VSIFPrintfL( fpCSVT, "%s", "Real"); break;
                  case OFTDate:     VSIFPrintfL( fpCSVT, "%s", "Date"); break;
                  case OFTTime:     VSIFPrintfL( fpCSVT, "%s", "Time"); break;
                  case OFTDateTime: VSIFPrintfL( fpCSVT, "%s", "DateTime"); break;
                  default:          VSIFPrintfL( fpCSVT, "%s", "String"); break;
                }

                int nWidth = poFeatureDefn->GetFieldDefn(iField)->GetWidth();
                int nPrecision = poFeatureDefn->GetFieldDefn(iField)->GetPrecision();
                if (nWidth != 0)
                {
                    if (nPrecision != 0)
                        VSIFPrintfL( fpCSVT, "(%d.%d)", nWidth, nPrecision);
                    else
                        VSIFPrintfL( fpCSVT, "(%d)", nWidth);
                }
            }
        }

        /* The CSV driver will not recognize single column tables, so add */
        /* a fake second blank field */
        if( poFeatureDefn->GetFieldCount() == 1 )
        {
            if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter );
        }

        if( bUseCRLF )
        {
            if (fpCSV) VSIFPutcL( 13, fpCSV );
            if (fpCSVT) VSIFPutcL( 13, fpCSVT );
        }
        if (fpCSV) VSIFPutcL( '\n', fpCSV );
        if (fpCSVT) VSIFPutcL( '\n', fpCSVT );
        if (fpCSVT) VSIFCloseL(fpCSVT);
    }

    if (fpCSV == NULL) 
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, FILE* fp, const char* tocHeader)
{
    int i, j;
    unsigned int locationSectionPhysicalLocation;
    
    unsigned short nSections;
    unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0, boundaryRectangleSectionSubHeaderLength = 0;
    unsigned int boundaryRectangleTablePhysIndex = 0, boundaryRectangleTableLength = 0;
    unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0, frameFileIndexSectionSubHeaderLength = 0;
    unsigned int frameFileIndexSubsectionPhysIndex = 0, frameFileIndexSubsectionLength = 0;
    
    unsigned int boundaryRectangleTableOffset;
    unsigned short boundaryRectangleCount;
    
    unsigned int frameIndexTableOffset;
    unsigned int nFrameFileIndexRecords;
    unsigned short nFrameFilePathnameRecords;
    unsigned short frameFileIndexRecordLength;

    int newBoundaryId = 0;

    RPFToc* toc;
    
    tocHeader += 1; /* skip endian */
    tocHeader += 2; /* skip header length */
    tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
    tocHeader += 1; /* skip new  */
    tocHeader += 15; /* skip standard_num  */
    tocHeader += 8; /* skip standard_date  */
    tocHeader += 1; /* skip classification  */
    tocHeader += 2; /* skip country  */
    tocHeader += 2; /* skip release  */
    
    memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
    CPL_MSBPTR32(&locationSectionPhysicalLocation);
    
    if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
                   locationSectionPhysicalLocation );
        return NULL;
    }
    
    /* Skip location section length (4) and component location table offset (2)*/
    VSIFSeekL( fp, 4 + 2, SEEK_CUR);
    
    /* How many sections: # of section location records */
    VSIFReadL( &nSections, 1, sizeof(nSections), fp);
    CPL_MSBPTR16( &nSections );
    
    /* Skip location record length(2) + component aggregate length(4) */
    VSIFSeekL( fp, 2 + 4, SEEK_CUR);
    
    for (i = 0; i < nSections; i++)
    {
        unsigned short id;
        unsigned int sectionLength, physIndex;
        VSIFReadL( &id, 1, sizeof(id), fp);
        CPL_MSBPTR16( &id );
        
        VSIFReadL( &sectionLength, 1, sizeof(sectionLength), fp);
        CPL_MSBPTR32( &sectionLength );
        
        VSIFReadL( &physIndex, 1, sizeof(physIndex), fp);
        CPL_MSBPTR32( &physIndex );
        
        if (id == LID_BoundaryRectangleSectionSubheader)
        {
            boundaryRectangleSectionSubHeaderPhysIndex = physIndex;
            boundaryRectangleSectionSubHeaderLength = sectionLength;
        }
        else if (id == LID_BoundaryRectangleTable)
        {
            boundaryRectangleTablePhysIndex = physIndex;
            boundaryRectangleTableLength = sectionLength;
        }
        else if (id == LID_FrameFileIndexSectionSubHeader)
        {
            frameFileIndexSectionSubHeaderPhysIndex = physIndex;
            frameFileIndexSectionSubHeaderLength = sectionLength;
        }
        else if (id == LID_FrameFileIndexSubsection)
        {
            frameFileIndexSubsectionPhysIndex = physIndex;
            frameFileIndexSubsectionLength = sectionLength;
        }
    }
    
    if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
        return NULL;
    }
    if (boundaryRectangleTablePhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
        return NULL;
    }
    if (frameFileIndexSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
        return NULL;
    }
    if (frameFileIndexSubsectionPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
        return NULL;
    }
    
    if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
                   boundaryRectangleSectionSubHeaderPhysIndex );
        return NULL;
    }
    
    VSIFReadL( &boundaryRectangleTableOffset, 1, sizeof(boundaryRectangleTableOffset), fp);
    CPL_MSBPTR32( &boundaryRectangleTableOffset );
    
    VSIFReadL( &boundaryRectangleCount, 1, sizeof(boundaryRectangleCount), fp);
    CPL_MSBPTR16( &boundaryRectangleCount );
    
    if( VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
                   boundaryRectangleTablePhysIndex );
        return NULL;
    }
    
    toc = (RPFToc*)CPLMalloc(sizeof(RPFToc));
    toc->nEntries = boundaryRectangleCount;
    toc->entries = (RPFTocEntry*)CPLMalloc(boundaryRectangleCount * sizeof(RPFTocEntry));
    memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));
    
    for(i=0;i<toc->nEntries;i++)
    {
        toc->entries[i].isOverviewOrLegend = 0;
        
        VSIFReadL( toc->entries[i].type, 1, 5, fp);
        toc->entries[i].type[5] = 0;
        RPFTOCTrim(toc->entries[i].type);
        
        VSIFReadL( toc->entries[i].compression, 1, 5, fp);
        toc->entries[i].compression[5] = 0;
        RPFTOCTrim(toc->entries[i].compression);
        
        VSIFReadL( toc->entries[i].scale, 1, 12, fp);
        toc->entries[i].scale[12] = 0;
        RPFTOCTrim(toc->entries[i].scale);
        if (toc->entries[i].scale[0] == '1' &&
            toc->entries[i].scale[1] == ':')
        {
            memmove(toc->entries[i].scale,
                    toc->entries[i].scale+2,
                    strlen(toc->entries[i].scale+2)+1);
        }
        
        VSIFReadL( toc->entries[i].zone, 1, 1, fp);
        toc->entries[i].zone[1] = 0;
        RPFTOCTrim(toc->entries[i].zone);
        
        VSIFReadL( toc->entries[i].producer, 1, 5, fp);
        toc->entries[i].producer[5] = 0;
        RPFTOCTrim(toc->entries[i].producer);

        VSIFReadL( &toc->entries[i].nwLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].nwLat);

        VSIFReadL( &toc->entries[i].nwLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].nwLong);

        VSIFReadL( &toc->entries[i].swLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].swLat);

        VSIFReadL( &toc->entries[i].swLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].swLong);

        VSIFReadL( &toc->entries[i].neLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].neLat);

        VSIFReadL( &toc->entries[i].neLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].neLong);

        VSIFReadL( &toc->entries[i].seLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].seLat);
        
        VSIFReadL( &toc->entries[i].seLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].seLong);
        
        VSIFReadL( &toc->entries[i].vertResolution, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].vertResolution);
        
        VSIFReadL( &toc->entries[i].horizResolution, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].horizResolution);
        
        VSIFReadL( &toc->entries[i].vertInterval, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].vertInterval);

        VSIFReadL( &toc->entries[i].horizInterval, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].horizInterval);
        
        VSIFReadL( &toc->entries[i].nVertFrames, 1, sizeof(int), fp);
        CPL_MSBPTR32( &toc->entries[i].nVertFrames );
        
        VSIFReadL( &toc->entries[i].nHorizFrames, 1, sizeof(int), fp);
        CPL_MSBPTR32( &toc->entries[i].nHorizFrames );
        
        toc->entries[i].frameEntries = (RPFTocFrameEntry*)
                VSIMalloc3(toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames, sizeof(RPFTocFrameEntry));
        if (toc->entries[i].frameEntries == NULL)
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                      "RPFTOCReadFromBuffer : Out of memory. Probably due to corrupted TOC file.");
            RPFTOCFree(toc);
            return NULL;
        }
        memset(toc->entries[i].frameEntries, 0,
               toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames * sizeof(RPFTocFrameEntry));
        
        CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
                 i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
                 toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
    }
    
    if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
                   frameFileIndexSectionSubHeaderPhysIndex );
        RPFTOCFree(toc);
        return NULL;
    }
    
    /* Skip 1 byte security classification */
    VSIFSeekL( fp, 1, SEEK_CUR );
    
    VSIFReadL( &frameIndexTableOffset, 1, sizeof(frameIndexTableOffset), fp);
    CPL_MSBPTR32( &frameIndexTableOffset );
    
    VSIFReadL( &nFrameFileIndexRecords, 1, sizeof(nFrameFileIndexRecords), fp);
    CPL_MSBPTR32( &nFrameFileIndexRecords );
    
    VSIFReadL( &nFrameFilePathnameRecords, 1, sizeof(nFrameFilePathnameRecords), fp);
    CPL_MSBPTR16( &nFrameFilePathnameRecords );
    
    VSIFReadL( &frameFileIndexRecordLength, 1, sizeof(frameFileIndexRecordLength), fp);
    CPL_MSBPTR16( &frameFileIndexRecordLength );
    
    for (i=0;i<(int)nFrameFileIndexRecords;i++)
    {
        RPFTocEntry* entry;
        RPFTocFrameEntry* frameEntry;
        unsigned short boundaryId, frameRow, frameCol;
        unsigned int offsetFrameFilePathName;
        unsigned short pathLength;
        
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
            RPFTOCFree(toc);
            return NULL;
        }

        VSIFReadL( &boundaryId, 1, sizeof(boundaryId), fp);
        CPL_MSBPTR16( &boundaryId );
        
        if (i == 0 && boundaryId == 0)
            newBoundaryId = 1;
        if (newBoundaryId == 0)
            boundaryId--;
        
        if (boundaryId >= toc->nEntries)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
                     boundaryId, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        entry = &toc->entries[boundaryId];
        entry->boundaryId = boundaryId;
        
        VSIFReadL( &frameRow, 1, sizeof(frameRow), fp);
        CPL_MSBPTR16( &frameRow );
        
        VSIFReadL( &frameCol, 1, sizeof(frameCol), fp);
        CPL_MSBPTR16( &frameCol );


        if (newBoundaryId == 0)
        {
            frameRow--;
            frameCol--;
        }
        else
        {
            /* Trick so that frames are numbered north to south */
            frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
        }
   
        if (frameRow >= entry->nVertFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                        "Invalid TOC file. Bad row num (%d) for frame file index %d.",
                        frameRow, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        if (frameCol >= entry->nHorizFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                        "Invalid TOC file. Bad col num (%d) for frame file index %d.",
                        frameCol, i);
            RPFTOCFree(toc);
            return NULL;
        }

        frameEntry = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
        frameEntry->frameRow = frameRow;
        frameEntry->frameCol = frameCol;

        if (frameEntry->exists)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "Invalid TOC file. Frame entry(%d,%d) for frame file index %d is a duplicate.",
                      frameRow, frameCol, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        VSIFReadL( &offsetFrameFilePathName, 1, sizeof(offsetFrameFilePathName), fp);
        CPL_MSBPTR32( &offsetFrameFilePathName );
        

        VSIFReadL( frameEntry->filename, 1, 12, fp);
        frameEntry->filename[12] = '\0';

        /* Check if the filename is an overview or legend */
        for (j=0;j<12;j++)
        {
            if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
                strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
                strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
                strcmp(&(frameEntry->filename[j]),".lgd") == 0)
            {
                entry->isOverviewOrLegend = TRUE;
                break;
            }
        }
        
        /* Extract series code */
        if (entry->seriesAbbreviation == NULL)
        {
            const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
            if (series)
            {
                entry->seriesAbbreviation = series->abbreviation;
                entry->seriesName = series->name;
            }
        }

        /* Get file geo reference */
        VSIFReadL( frameEntry->georef, 1, 6, fp);
        frameEntry->georef[6] = '\0';

        /* Go to start of pathname record */
        /* New path_off offset from start of frame file index section of TOC?? */
        /* Add pathoffset wrt frame file index table subsection (loc[3]) */
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
            RPFTOCFree(toc);
            return NULL;
        }

        VSIFReadL( &pathLength, 1, sizeof(pathLength), fp);
        CPL_MSBPTR16( &pathLength );
        
        /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
           this leads to 4 GB allocation... Protect against this case */
        if (pathLength > 256)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Path length is big : %d. Probably corrupted TOC file.", (int)pathLength);
            RPFTOCFree(toc);
            return NULL;
        }
        
        frameEntry->directory = (char *)CPLMalloc(pathLength+1);
        VSIFReadL( frameEntry->directory, 1, pathLength, fp);
        frameEntry->directory[pathLength] = 0;
        if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
            frameEntry->directory[pathLength-1] = 0;
        
        if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
            memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);
        
        {
            char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
            VSIStatBufL sStatBuf;
            char* subdir;
            if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
                subdir = CPLStrdup(frameEntry->directory);
            else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
                subdir = CPLStrdup(baseDir);
            else
                subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, NULL));
#if !defined(_WIN32) && !defined(_WIN32_CE)
            if( VSIStatL( subdir, &sStatBuf ) != 0 && subdir[strlen(baseDir)] != 0)
            {
                char* c = subdir + strlen(baseDir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
            }
#endif
            frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
                    subdir,
                    frameEntry->filename, NULL));
            if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
            {
#if !defined(_WIN32) && !defined(_WIN32_CE)
                char* c = frameEntry->fullFilePath + strlen(subdir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
                if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
#endif
                {
                    frameEntry->fileExists = 0;
                    CPLError( CE_Warning, CPLE_AppDefined, 
                        "File %s does not exist.", frameEntry->fullFilePath );
                }
#if !defined(_WIN32) && !defined(_WIN32_CE)
                else
                {
                    frameEntry->fileExists = 1;
                }
#endif
            }
            else
            {
                frameEntry->fileExists = 1;
            }
            CPLFree(subdir);
            CPLFree(baseDir);
        }

        CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);

        frameEntry->exists = 1;
    }
    
    return toc;
}
Beispiel #14
0
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, VSILFILE* fp, const char* tocHeader)
{
    tocHeader += 1; /* skip endian */
    tocHeader += 2; /* skip header length */
    tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
    tocHeader += 1; /* skip new  */
    tocHeader += 15; /* skip standard_num  */
    tocHeader += 8; /* skip standard_date  */
    tocHeader += 1; /* skip classification  */
    tocHeader += 2; /* skip country  */
    tocHeader += 2; /* skip release  */

    unsigned int locationSectionPhysicalLocation;
    memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
    CPL_MSBPTR32(&locationSectionPhysicalLocation);

    if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
                   locationSectionPhysicalLocation );
        return nullptr;
    }

    int nSections;
    NITFLocation* pasLocations = NITFReadRPFLocationTable(fp, &nSections);

    unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0;
    unsigned int boundaryRectangleTablePhysIndex = 0;
    unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0;
    unsigned int frameFileIndexSubsectionPhysIndex = 0;

    for( int i = 0; i < nSections; i++ )
    {
        if (pasLocations[i].nLocId == LID_BoundaryRectangleSectionSubheader)
        {
            boundaryRectangleSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_BoundaryRectangleTable)
        {
            boundaryRectangleTablePhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSectionSubHeader)
        {
            frameFileIndexSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSubsection)
        {
            frameFileIndexSubsectionPhysIndex = pasLocations[i].nLocOffset;
        }
    }

    CPLFree(pasLocations);

    if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
        return nullptr;
    }
    if (boundaryRectangleTablePhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
        return nullptr;
    }
    if (frameFileIndexSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
        return nullptr;
    }
    if (frameFileIndexSubsectionPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
        return nullptr;
    }

    if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
                   boundaryRectangleSectionSubHeaderPhysIndex );
        return nullptr;
    }

    unsigned int boundaryRectangleTableOffset;
    bool bOK = VSIFReadL( &boundaryRectangleTableOffset, sizeof(boundaryRectangleTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &boundaryRectangleTableOffset );

    unsigned short boundaryRectangleCount;
    bOK &= VSIFReadL( &boundaryRectangleCount, sizeof(boundaryRectangleCount), 1, fp) == 1;
    CPL_MSBPTR16( &boundaryRectangleCount );

    if( !bOK || VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
                   boundaryRectangleTablePhysIndex );
        return nullptr;
    }

    RPFToc* toc = reinterpret_cast<RPFToc *>( CPLMalloc( sizeof( RPFToc ) ) );
    toc->nEntries = boundaryRectangleCount;
    toc->entries = reinterpret_cast<RPFTocEntry *>(
        CPLMalloc( boundaryRectangleCount * sizeof(RPFTocEntry) ) );
    memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));

    for( int i = 0; i < toc->nEntries; i++ )
    {
        toc->entries[i].isOverviewOrLegend = 0;

        bOK &= VSIFReadL( toc->entries[i].type, 1, 5, fp) == 5;
        toc->entries[i].type[5] = 0;
        RPFTOCTrim(toc->entries[i].type);

        bOK &= VSIFReadL( toc->entries[i].compression, 1, 5, fp) == 5;
        toc->entries[i].compression[5] = 0;
        RPFTOCTrim(toc->entries[i].compression);

        bOK &= VSIFReadL( toc->entries[i].scale, 1, 12, fp) == 12;
        toc->entries[i].scale[12] = 0;
        RPFTOCTrim(toc->entries[i].scale);
        if (toc->entries[i].scale[0] == '1' &&
            toc->entries[i].scale[1] == ':')
        {
            memmove(toc->entries[i].scale,
                    toc->entries[i].scale+2,
                    strlen(toc->entries[i].scale+2)+1);
        }

        bOK &= VSIFReadL( toc->entries[i].zone, 1, 1, fp) == 1;
        toc->entries[i].zone[1] = 0;
        RPFTOCTrim(toc->entries[i].zone);

        bOK &= VSIFReadL( toc->entries[i].producer, 1, 5, fp) == 5;
        toc->entries[i].producer[5] = 0;
        RPFTOCTrim(toc->entries[i].producer);

        bOK &= VSIFReadL( &toc->entries[i].nwLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLat);

        bOK &= VSIFReadL( &toc->entries[i].nwLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLong);

        bOK &= VSIFReadL( &toc->entries[i].swLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLat);

        bOK &= VSIFReadL( &toc->entries[i].swLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLong);

        bOK &= VSIFReadL( &toc->entries[i].neLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLat);

        bOK &= VSIFReadL( &toc->entries[i].neLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLong);

        bOK &= VSIFReadL( &toc->entries[i].seLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLat);

        bOK &= VSIFReadL( &toc->entries[i].seLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLong);

        bOK &= VSIFReadL( &toc->entries[i].vertResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertResolution);

        bOK &= VSIFReadL( &toc->entries[i].horizResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizResolution);

        bOK &= VSIFReadL( &toc->entries[i].vertInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertInterval);

        bOK &= VSIFReadL( &toc->entries[i].horizInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizInterval);

        bOK &= VSIFReadL( &toc->entries[i].nVertFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nVertFrames );

        bOK &= VSIFReadL( &toc->entries[i].nHorizFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nHorizFrames );

        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        if( toc->entries[i].vertInterval <= 1e-10 ||
            !CPLIsFinite(toc->entries[i].vertInterval) ||
            toc->entries[i].horizInterval <= 1e-10 ||
            !CPLIsFinite(toc->entries[i].horizInterval) ||
            !(fabs(toc->entries[i].seLong) <= 360.0) ||
            !(fabs(toc->entries[i].nwLong) <= 360.0) ||
            !(fabs(toc->entries[i].nwLat) <= 90.0) ||
            !(fabs(toc->entries[i].seLat) <= 90.0) ||
            toc->entries[i].seLong < toc->entries[i].nwLong ||
            toc->entries[i].nwLat < toc->entries[i].seLat ||
            toc->entries[i].nHorizFrames == 0 ||
            toc->entries[i].nVertFrames == 0 ||
            toc->entries[i].nHorizFrames > INT_MAX / toc->entries[i].nVertFrames )
        {
            CPLError(CE_Failure, CPLE_FileIO, "Invalid TOC entry");
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        // TODO: We could probably use another data structure, like a list,
        // instead of an array referenced by the frame coordinate...
        if( static_cast<int>(toc->entries[i].nHorizFrames *
                                  toc->entries[i].nVertFrames) >
                 atoi(CPLGetConfigOption("RPFTOC_MAX_FRAME_COUNT", "1000000")) )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "nHorizFrames=%d x nVertFrames=%d > %d. Please raise "
                     "the value of the RPFTOC_MAX_FRAME_COUNT configuration "
                     "option to more than %d if this dataset is legitimate.",
                     toc->entries[i].nHorizFrames, toc->entries[i].nVertFrames,
                     atoi(CPLGetConfigOption("RPFTOC_MAX_FRAME_COUNT", "1000000")),
                     toc->entries[i].nHorizFrames * toc->entries[i].nVertFrames );
            toc->entries[i].frameEntries = nullptr;
        }
        else
        {
            toc->entries[i].frameEntries = reinterpret_cast<RPFTocFrameEntry*>(
                VSI_CALLOC_VERBOSE( toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames,
                                    sizeof(RPFTocFrameEntry) ) );
        }
        if (toc->entries[i].frameEntries == nullptr)
        {
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
                 i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
                 toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
    }

    if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
                   frameFileIndexSectionSubHeaderPhysIndex );
        RPFTOCFree(toc);
        return nullptr;
    }

    /* Skip 1 byte security classification */
    bOK &= VSIFSeekL( fp, 1, SEEK_CUR ) == 0;

    unsigned int frameIndexTableOffset;
    bOK &= VSIFReadL( &frameIndexTableOffset, sizeof(frameIndexTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &frameIndexTableOffset );

    unsigned int nFrameFileIndexRecords;
    bOK &= VSIFReadL( &nFrameFileIndexRecords, sizeof(nFrameFileIndexRecords), 1, fp) == 1;
    CPL_MSBPTR32( &nFrameFileIndexRecords );

    unsigned short nFrameFilePathnameRecords;
    bOK &= VSIFReadL( &nFrameFilePathnameRecords, sizeof(nFrameFilePathnameRecords), 1, fp) == 1;
    CPL_MSBPTR16( &nFrameFilePathnameRecords );

    unsigned short frameFileIndexRecordLength;
    bOK &= VSIFReadL( &frameFileIndexRecordLength, sizeof(frameFileIndexRecordLength), 1, fp) == 1;
    CPL_MSBPTR16( &frameFileIndexRecordLength );
    if( frameFileIndexRecordLength < 3 * sizeof(short) )
    {
        CPLError(CE_Failure, CPLE_FileIO, "Invalid file");
        RPFTOCFree(toc);
        return nullptr;
    }

    if( !bOK )
    {
        CPLError(CE_Failure, CPLE_FileIO, "I/O error");
        RPFTOCFree(toc);
        return nullptr;
    }

    int newBoundaryId = 0;

    for( int i = 0; i < static_cast<int>( nFrameFileIndexRecords ); i++ )
    {
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
            RPFTOCFree(toc);
            return nullptr;
        }

        unsigned short boundaryId;
        if( VSIFReadL( &boundaryId, sizeof(boundaryId), 1, fp) != 1 )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        CPL_MSBPTR16( &boundaryId );

        if (i == 0 && boundaryId == 0)
            newBoundaryId = 1;
        if (newBoundaryId == 0)
            boundaryId--;

        if (boundaryId >= toc->nEntries)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
                     boundaryId, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        RPFTocEntry* entry = &toc->entries[boundaryId];
        entry->boundaryId = boundaryId;

        unsigned short frameRow;
        bOK &= VSIFReadL( &frameRow, sizeof(frameRow), 1, fp) == 1;
        CPL_MSBPTR16( &frameRow );

        unsigned short frameCol;
        bOK &= VSIFReadL( &frameCol, sizeof(frameCol), 1, fp) == 1;
        CPL_MSBPTR16( &frameCol );
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }

        if (newBoundaryId == 0)
        {
            frameRow--;
            frameCol--;
        }
        else
        {
            /* Trick so that frames are numbered north to south */
            frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
        }

        if (frameRow >= entry->nVertFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad row num (%d) for frame file index %d.",
                        frameRow, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        if (frameCol >= entry->nHorizFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad col num (%d) for frame file index %d.",
                        frameCol, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        RPFTocFrameEntry* frameEntry
            = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
        frameEntry->frameRow = frameRow;
        frameEntry->frameCol = frameCol;

        if (frameEntry->exists)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Frame entry(%d,%d) for frame file index %d was already found.",
                      frameRow, frameCol, i);
            CPLFree(frameEntry->directory);
            frameEntry->directory = nullptr;
            CPLFree(frameEntry->fullFilePath);
            frameEntry->fullFilePath = nullptr;
            frameEntry->exists = 0;
        }

        unsigned int offsetFrameFilePathName;
        bOK &= VSIFReadL( &offsetFrameFilePathName, sizeof(offsetFrameFilePathName), 1, fp) == 1;
        CPL_MSBPTR32( &offsetFrameFilePathName );

        bOK &= VSIFReadL( frameEntry->filename, 1, 12, fp) == 12;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        frameEntry->filename[12] = '\0';
        bOK &= strlen(frameEntry->filename) > 0;

        /* Check if the filename is an overview or legend */
        for( int j = 0; j < 12; j++ )
        {
            if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
                strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
                strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
                strcmp(&(frameEntry->filename[j]),".lgd") == 0)
            {
                entry->isOverviewOrLegend = TRUE;
                break;
            }
        }

        /* Extract series code */
        if (entry->seriesAbbreviation == nullptr)
        {
            const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
            if (series)
            {
                entry->seriesAbbreviation = series->abbreviation;
                entry->seriesName = series->name;
            }
        }

        /* Get file geo reference */
        bOK &= VSIFReadL( frameEntry->georef, 1, 6, fp) == 6;
        frameEntry->georef[6] = '\0';

        /* Go to start of pathname record */
        /* New path_off offset from start of frame file index section of TOC?? */
        /* Add pathoffset wrt frame file index table subsection (loc[3]) */
        if( !bOK || VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Invalid TOC file. Unable to seek to "
                      "frameFileIndexSubsectionPhysIndex + "
                      "offsetFrameFilePathName(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
            RPFTOCFree(toc);
            return nullptr;
        }

        unsigned short pathLength;
        bOK &= VSIFReadL( &pathLength, sizeof(pathLength), 1, fp) == 1;
        CPL_MSBPTR16( &pathLength );

        /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
           this leads to 4 GB allocation... Protect against this case */
        if (!bOK || pathLength == 0 || pathLength > 256)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Path length is invalid : %d. Probably corrupted TOC file.",
                      static_cast<int>( pathLength ) );
            RPFTOCFree(toc);
            return nullptr;
        }

        frameEntry->directory = reinterpret_cast<char *>( CPLMalloc(pathLength+1) );
        bOK &= VSIFReadL( frameEntry->directory, 1, pathLength, fp) == pathLength;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        frameEntry->directory[pathLength] = 0;
        if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
            frameEntry->directory[pathLength-1] = 0;

        if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
        {
            memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);

            // Some A.TOC have subdirectory names like ".//X/" ... (#5979)
            // Check if it was not intended to be "./X/" instead.
            VSIStatBufL sStatBuf;
            if( frameEntry->directory[0] == '/' &&
                VSIStatL(CPLFormFilename(CPLGetDirname(pszFilename), frameEntry->directory+1, nullptr), &sStatBuf) == 0 &&
                VSI_ISDIR(sStatBuf.st_mode) )
            {
                memmove(frameEntry->directory, frameEntry->directory+1, strlen(frameEntry->directory+1)+1);
            }
        }

        {
            char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
            VSIStatBufL sStatBuf;
            char* subdir = nullptr;
            if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
                subdir = CPLStrdup(frameEntry->directory);
            else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
                subdir = CPLStrdup(baseDir);
            else
                subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, nullptr));
#if !defined(_WIN32) && !defined(_WIN32_CE)
            if( VSIStatL( subdir, &sStatBuf ) != 0 && strlen(subdir) > strlen(baseDir) && subdir[strlen(baseDir)] != 0)
            {
                char* c = subdir + strlen(baseDir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
            }
#endif
            frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
                    subdir,
                    frameEntry->filename, nullptr));
            if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
            {
#if !defined(_WIN32) && !defined(_WIN32_CE)
                if( strlen(frameEntry->fullFilePath) > strlen(subdir) )
                {
                    char* c = frameEntry->fullFilePath + strlen(subdir)+1;
                    while(*c)
                    {
                        if (*c >= 'A' && *c <= 'Z')
                            *c += 'a' - 'A';
                        c++;
                    }
                }
                if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
#endif
                {
                    frameEntry->fileExists = 0;
                    CPLError( CE_Warning, CPLE_AppDefined,
                        "File %s does not exist.", frameEntry->fullFilePath );
                }
#if !defined(_WIN32) && !defined(_WIN32_CE)
                else
                {
                    frameEntry->fileExists = 1;
                }
#endif
            }
            else
            {
                frameEntry->fileExists = 1;
            }
            CPLFree(subdir);
            CPLFree(baseDir);
        }

        CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);

        frameEntry->exists = 1;
    }

    return toc;
}
Beispiel #15
0
GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( poOpenInfo->nHeaderBytes < 1024)
        return NULL;

    if( !EQUALN((const char *) poOpenInfo->pabyHeader + 52,
                "ACQUISITION DATE =", 18)
        && !EQUALN((const char *) poOpenInfo->pabyHeader + 36,
                "ACQUISITION DATE =", 18) )
        return NULL;

/* -------------------------------------------------------------------- */
/*  Create a corresponding GDALDataset.                                 */
/* -------------------------------------------------------------------- */
    FASTDataset *poDS = new FASTDataset();

    poDS->fpHeader = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (poDS->fpHeader == NULL)
    {
        delete poDS;
        return NULL;
    }

    poDS->pszFilename = poOpenInfo->pszFilename;
    poDS->pszDirname = CPLStrdup( CPLGetDirname( poOpenInfo->pszFilename ) );

/* -------------------------------------------------------------------- */
/*  Read the administrative record.                                     */
/* -------------------------------------------------------------------- */
    char *pszHeader =
        static_cast<char *>( CPLMalloc( ADM_HEADER_SIZE + 1 ) );

    size_t nBytesRead = 0;
    if( VSIFSeekL( poDS->fpHeader, 0, SEEK_SET ) >= 0 )
        nBytesRead = VSIFReadL( pszHeader, 1, ADM_HEADER_SIZE, poDS->fpHeader );
    if ( nBytesRead < ADM_MIN_HEADER_SIZE )
    {
        CPLDebug( "FAST", "Header file too short. Reading failed" );
        CPLFree(pszHeader);
        delete poDS;
        return NULL;
    }
    pszHeader[nBytesRead] = '\0';

    // Read acquisition date
    char *pszTemp = GetValue( pszHeader, ACQUISITION_DATE,
                              ACQUISITION_DATE_SIZE, TRUE );
    if (pszTemp == NULL)
    {
        CPLDebug( "FAST", "Cannot get ACQUISITION_DATE, using empty value." );
        pszTemp = CPLStrdup("");
    }
    poDS->SetMetadataItem( "ACQUISITION_DATE", pszTemp );
    CPLFree( pszTemp );

    // Read satellite name (will read the first one only)
    pszTemp = GetValue( pszHeader, SATELLITE_NAME, SATELLITE_NAME_SIZE, TRUE );
    if (pszTemp == NULL)
    {
        CPLDebug( "FAST", "Cannot get SATELLITE_NAME, using empty value." );
        pszTemp = CPLStrdup( "" );
    }
    poDS->SetMetadataItem( "SATELLITE", pszTemp );
    if ( STARTS_WITH_CI(pszTemp, "LANDSAT") )
        poDS->iSatellite = LANDSAT;
    // TODO(schwehr): Was this a bug that both are IRS?
    // else if ( STARTS_WITH_CI(pszTemp, "IRS") )
    //    poDS->iSatellite = IRS;
    else
      poDS->iSatellite = IRS;  // TODO(schwehr): Should this be FAST_UNKNOWN?
    CPLFree( pszTemp );

    // Read sensor name (will read the first one only)
    pszTemp = GetValue( pszHeader, SENSOR_NAME, SENSOR_NAME_SIZE, TRUE );
    if (pszTemp == NULL)
    {
        CPLDebug( "FAST", "Cannot get SENSOR_NAME, using empty value." );
        pszTemp = CPLStrdup("");
    }
    poDS->SetMetadataItem( "SENSOR", pszTemp );
    CPLFree( pszTemp );

    // Read filenames
    poDS->nBands = 0;

    if (strstr( pszHeader, FILENAME ) == NULL)
    {
        if (strstr(pszHeader, "GENERATING AGENCY =EUROMAP"))
        {
            // If we don't find the FILENAME field, let's try with the Euromap
            // PAN / LISS3 / WIFS IRS filename convention.
            if ((EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS 1C") ||
                 EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS 1D")) &&
                (EQUAL(poDS->GetMetadataItem("SENSOR"), "PAN") ||
                 EQUAL(poDS->GetMetadataItem("SENSOR"), "LISS3") ||
                 EQUAL(poDS->GetMetadataItem("SENSOR"), "WIFS")))
            {
                poDS->TryEuromap_IRS_1C_1D_ChannelNameConvention();
            }
            else if (EQUAL(poDS->GetMetadataItem("SATELLITE"), "CARTOSAT-1") &&
                     (EQUAL(poDS->GetMetadataItem("SENSOR"), "FORE") ||
                      EQUAL(poDS->GetMetadataItem("SENSOR"), "AFT")))
            {
                // See appendix F in
                // http://www.euromap.de/download/p5fast_20050301.pdf
                const CPLString osSuffix = CPLGetExtension( poDS->pszFilename );
                const char *papszBasenames[] =
                    { "BANDF", "bandf", "BANDA", "banda" };
                for ( int i = 0; i < 4; i++ )
                {
                    const CPLString osChannelFilename =
                        CPLFormFilename( poDS->pszDirname, papszBasenames[i],
                                         osSuffix );
                    if( poDS->OpenChannel( osChannelFilename, 0 ) )
                    {
                        poDS->nBands = 1;
                        break;
                    }
                }
            }
            else if( EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS P6") )
            {
                // If BANDS_PRESENT="2345", the file bands are "BAND2.DAT",
                // "BAND3.DAT", etc.
                pszTemp =
                    GetValue( pszHeader, BANDS_PRESENT, BANDS_PRESENT_SIZE,
                              TRUE );
                if (pszTemp)
                {
                    for( int i=0; pszTemp[i] != '\0'; i++ )
                    {
                        if( pszTemp[i] >= '2' && pszTemp[i] <= '5' )
                        {
                            if( poDS->FOpenChannel(
                                   poDS->pszFilename,
                                   poDS->nBands, pszTemp[i] - '0'))
                                poDS->nBands++;
                        }
                    }
                    CPLFree( pszTemp );
                }
            }
        }
    }

    // If the previous lookup for band files didn't success, fallback to the
    // standard way of finding them, either by the FILENAME field, either with
    // the usual patterns like bandX.dat, etc.
    if( !poDS->nBands )
    {
        pszTemp = pszHeader;
        for ( int i = 0; i < 7; i++ )
        {
            char *pszFilename = NULL ;
            if ( pszTemp )
                pszTemp = strstr( pszTemp, FILENAME );
            if ( pszTemp )
            {
                // Skip the parameter name
                pszTemp += strlen(FILENAME);
                // Skip whitespaces and equal signs
                while ( *pszTemp == ' ' )
                    pszTemp++;
                while ( *pszTemp == '=' )
                    pszTemp++;
                pszFilename =
                    CPLScanString( pszTemp, FILENAME_SIZE, TRUE, FALSE );
            }
            else
                pszTemp = NULL;
            if ( poDS->FOpenChannel( pszFilename, poDS->nBands,
                                     poDS->nBands + 1 ) )
                poDS->nBands++;
            if ( pszFilename )
                CPLFree( pszFilename );
        }
    }

    if ( !poDS->nBands )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Failed to find and open band data files." );
        CPLFree(pszHeader);
        delete poDS;
        return NULL;
    }

    // Read number of pixels/lines and bit depth
    pszTemp = GetValue( pszHeader, PIXELS, PIXELS_SIZE, FALSE );
    if ( pszTemp )
    {
        poDS->nRasterXSize = atoi( pszTemp );
        CPLFree( pszTemp );
    }
    else
    {
        CPLDebug( "FAST", "Failed to find number of pixels in line." );
        CPLFree(pszHeader);
        delete poDS;
        return NULL;
    }

    pszTemp = GetValue( pszHeader, LINES1, LINES_SIZE, FALSE );
    if ( !pszTemp )
        pszTemp = GetValue( pszHeader, LINES2, LINES_SIZE, FALSE );
    if ( pszTemp )
    {
        poDS->nRasterYSize = atoi( pszTemp );
        CPLFree( pszTemp );
    }
    else
    {
        CPLDebug( "FAST", "Failed to find number of lines in raster." );
        CPLFree(pszHeader);
        delete poDS;
        return NULL;
    }

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
    {
        CPLFree(pszHeader);
        delete poDS;
        return NULL;
    }

    pszTemp = GetValue( pszHeader, BITS_PER_PIXEL, BITS_PER_PIXEL_SIZE, FALSE );
    if ( pszTemp )
    {
        switch( atoi(pszTemp) )
        {
            case 8:
            default:
                poDS->eDataType = GDT_Byte;
                break;
            // For a strange reason, some Euromap products declare 10 bits
            // output, but are 16 bits.
            case 10:
            case 16:
                poDS->eDataType = GDT_UInt16;
                break;
        }
        CPLFree( pszTemp );
    }
    else
    {
        poDS->eDataType = GDT_Byte;
    }

/* -------------------------------------------------------------------- */
/*  Read radiometric record.                                            */
/* -------------------------------------------------------------------- */
    const char *pszFirst = NULL;
    const char *pszSecond = NULL;

    // Read gains and biases. This is a trick!
    pszTemp = strstr( pszHeader, "BIASES" );// It may be "BIASES AND GAINS"
                                            // or "GAINS AND BIASES"
    const char* pszGains = strstr( pszHeader, "GAINS" );
    if( pszTemp == NULL || pszGains == NULL )
    {
        CPLDebug( "FAST", "No BIASES and/or GAINS" );
        CPLFree( pszHeader );
        delete poDS;
        return NULL;
    }
    if ( pszTemp > pszGains )
    {
        pszFirst = "GAIN%d";
        pszSecond = "BIAS%d";
    }
    else
    {
        pszFirst = "BIAS%d";
        pszSecond = "GAIN%d";
    }

    // Now search for the first number occurrence after that string.
    for ( int i = 1; i <= poDS->nBands; i++ )
    {
        char *pszValue = NULL;
        size_t nValueLen = VALUE_SIZE;

        pszTemp = strpbrk( pszTemp, "-.0123456789" );
        if ( pszTemp )
        {
            nValueLen = strspn( pszTemp, "+-.0123456789" );
            pszValue =
                CPLScanString( pszTemp, static_cast<int>(nValueLen),
                               TRUE, TRUE );
            poDS->SetMetadataItem( CPLSPrintf(pszFirst, i ), pszValue );
            CPLFree( pszValue );
        }
        pszTemp += nValueLen;
        pszTemp = strpbrk( pszTemp, "-.0123456789" );
        if ( pszTemp )
        {
            nValueLen = strspn( pszTemp, "+-.0123456789" );
            pszValue =
                CPLScanString( pszTemp, static_cast<int>(nValueLen),
                               TRUE, TRUE );
            poDS->SetMetadataItem( CPLSPrintf(pszSecond, i ), pszValue );
            CPLFree( pszValue );
        }
        pszTemp += nValueLen;
    }

/* -------------------------------------------------------------------- */
/*  Read geometric record.                                              */
/* -------------------------------------------------------------------- */
   // Coordinates of pixel's centers
    double dfULX = 0.0;
    double dfULY = 0.0;
    double dfURX = 0.0;
    double dfURY = 0.0;
    double dfLLX = 0.0;
    double dfLLY = 0.0;
    double dfLRX = 0.0;
    double dfLRY = 0.0;

    // Read projection name
    pszTemp = GetValue( pszHeader, PROJECTION_NAME,
                        PROJECTION_NAME_SIZE, FALSE );
    long iProjSys = 0;
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
        iProjSys = USGSMnemonicToCode( pszTemp );
    else
        iProjSys = 1L;  // UTM by default
    CPLFree( pszTemp );

    // Read ellipsoid name
    pszTemp = GetValue( pszHeader, ELLIPSOID_NAME, ELLIPSOID_NAME_SIZE, FALSE );
    long iDatum = 0;   // Clarke, 1866 (NAD1927) by default.
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
        iDatum = USGSEllipsoidToCode( pszTemp );
    CPLFree( pszTemp );

    // Read zone number.
    pszTemp = GetValue( pszHeader, ZONE_NUMBER, ZONE_NUMBER_SIZE, FALSE );
    long iZone = 0;
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
        iZone = atoi( pszTemp );
    CPLFree( pszTemp );

    // Read 15 USGS projection parameters
    double adfProjParms[15] = { 0.0 };
    pszTemp = strstr( pszHeader, USGS_PARAMETERS );
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
    {
        pszTemp += strlen( USGS_PARAMETERS );
        for ( int i = 0; i < 15; i++ )
        {
            pszTemp = strpbrk( pszTemp, "-.0123456789" );
            if ( pszTemp )
                adfProjParms[i] = CPLScanDouble( pszTemp, VALUE_SIZE );
            pszTemp = strpbrk( pszTemp, " \t" );
        }
    }

    // Coordinates should follow the word "PROJECTION", otherwise we can
    // be confused by other occurrences of the corner keywords.
    char *pszGeomRecord = strstr( pszHeader, "PROJECTION" );
    // Read corner coordinates
    pszTemp = strstr( pszGeomRecord, CORNER_UPPER_LEFT );
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
    {
        pszTemp += strlen( CORNER_UPPER_LEFT ) + 28;
        dfULX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
        pszTemp += CORNER_VALUE_SIZE + 1;
        dfULY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
    }

    pszTemp = strstr( pszGeomRecord, CORNER_UPPER_RIGHT );
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
    {
        pszTemp += strlen( CORNER_UPPER_RIGHT ) + 28;
        dfURX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
        pszTemp += CORNER_VALUE_SIZE + 1;
        dfURY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
    }

    pszTemp = strstr( pszGeomRecord, CORNER_LOWER_LEFT );
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
    {
        pszTemp += strlen( CORNER_LOWER_LEFT ) + 28;
        dfLLX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
        pszTemp += CORNER_VALUE_SIZE + 1;
        dfLLY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
    }

    pszTemp = strstr( pszGeomRecord, CORNER_LOWER_RIGHT );
    if ( pszTemp && !EQUAL( pszTemp, "" ) )
    {
        pszTemp += strlen( CORNER_LOWER_RIGHT ) + 28;
        dfLRX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
        pszTemp += CORNER_VALUE_SIZE + 1;
        dfLRY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
    }

    if ( dfULX != 0.0 && dfULY != 0.0
         && dfURX != 0.0 && dfURY != 0.0
         && dfLLX != 0.0 && dfLLY != 0.0
         && dfLRX != 0.0 && dfLRY != 0.0 )
    {
        // Strip out zone number from the easting values, if either
        if ( dfULX >= 1000000.0 )
            dfULX -= static_cast<double>( iZone ) * 1000000.0;
        if ( dfURX >= 1000000.0 )
            dfURX -= static_cast<double>( iZone ) * 1000000.0;
        if ( dfLLX >= 1000000.0 )
            dfLLX -= static_cast<double>( iZone ) * 1000000.0;
        if ( dfLRX >= 1000000.0 )
            dfLRX -= static_cast<double>( iZone ) * 1000000.0;

        // In EOSAT FAST Rev C, the angles are in decimal degrees
        // otherwise they are in packed DMS format.
        const int bAnglesInPackedDMSFormat =
            strstr( pszHeader, "REV            C" ) == NULL;

        // Create projection definition
        OGRSpatialReference oSRS;
        OGRErr eErr =
            oSRS.importFromUSGS( iProjSys, iZone, adfProjParms, iDatum, bAnglesInPackedDMSFormat );
        if ( eErr != OGRERR_NONE )
            CPLDebug( "FAST", "Import projection from USGS failed: %d", eErr );
        oSRS.SetLinearUnits( SRS_UL_METER, 1.0 );

        // Read datum name
        pszTemp = GetValue( pszHeader, DATUM_NAME, DATUM_NAME_SIZE, FALSE );
        if ( pszTemp )
        {
            if ( EQUAL( pszTemp, "WGS84" ) )
                oSRS.SetWellKnownGeogCS( "WGS84" );
            else if ( EQUAL( pszTemp, "NAD27" ) )
                oSRS.SetWellKnownGeogCS( "NAD27" );
            else if ( EQUAL( pszTemp, "NAD83" ) )
                oSRS.SetWellKnownGeogCS( "NAD83" );
            CPLFree( pszTemp );
        }
        else
        {
            // Reasonable fallback
            oSRS.SetWellKnownGeogCS( "WGS84" );
        }

        if ( poDS->pszProjection )
            CPLFree( poDS->pszProjection );
        eErr = oSRS.exportToWkt( &poDS->pszProjection );
        if ( eErr != OGRERR_NONE )
            CPLDebug("FAST", "Export projection to WKT USGS failed: %d", eErr);

        // Generate GCPs
        GDAL_GCP *pasGCPList
            = static_cast<GDAL_GCP *>( CPLCalloc( sizeof( GDAL_GCP ), 4 ) );
        GDALInitGCPs( 4, pasGCPList );
        CPLFree(pasGCPList[0].pszId);
        CPLFree(pasGCPList[1].pszId);
        CPLFree(pasGCPList[2].pszId);
        CPLFree(pasGCPList[3].pszId);

        /* Let's order the GCP in TL, TR, BR, BL order to benefit from the */
        /* GDALGCPsToGeoTransform optimization */
        pasGCPList[0].pszId = CPLStrdup("UPPER_LEFT");
        pasGCPList[0].dfGCPX = dfULX;
        pasGCPList[0].dfGCPY = dfULY;
        pasGCPList[0].dfGCPZ = 0.0;
        pasGCPList[0].dfGCPPixel = 0.5;
        pasGCPList[0].dfGCPLine = 0.5;
        pasGCPList[1].pszId = CPLStrdup("UPPER_RIGHT");
        pasGCPList[1].dfGCPX = dfURX;
        pasGCPList[1].dfGCPY = dfURY;
        pasGCPList[1].dfGCPZ = 0.0;
        pasGCPList[1].dfGCPPixel = poDS->nRasterXSize-0.5;
        pasGCPList[1].dfGCPLine = 0.5;
        pasGCPList[2].pszId = CPLStrdup("LOWER_RIGHT");
        pasGCPList[2].dfGCPX = dfLRX;
        pasGCPList[2].dfGCPY = dfLRY;
        pasGCPList[2].dfGCPZ = 0.0;
        pasGCPList[2].dfGCPPixel = poDS->nRasterXSize-0.5;
        pasGCPList[2].dfGCPLine = poDS->nRasterYSize-0.5;
        pasGCPList[3].pszId = CPLStrdup("LOWER_LEFT");
        pasGCPList[3].dfGCPX = dfLLX;
        pasGCPList[3].dfGCPY = dfLLY;
        pasGCPList[3].dfGCPZ = 0.0;
        pasGCPList[3].dfGCPPixel = 0.5;
        pasGCPList[3].dfGCPLine = poDS->nRasterYSize-0.5;

        // Calculate transformation matrix, if accurate
        const bool transform_ok
            = CPL_TO_BOOL(
                GDALGCPsToGeoTransform( 4, pasGCPList,
                                        poDS->adfGeoTransform, 0 ) );
        if( !transform_ok )
        {
            poDS->adfGeoTransform[0] = 0.0;
            poDS->adfGeoTransform[1] = 1.0;
            poDS->adfGeoTransform[2] = 0.0;
            poDS->adfGeoTransform[3] = 0.0;
            poDS->adfGeoTransform[4] = 0.0;
            poDS->adfGeoTransform[5] = 1.0;
            if ( poDS->pszProjection )
                CPLFree( poDS->pszProjection );
            poDS->pszProjection = CPLStrdup("");
        }

        GDALDeinitGCPs(4, pasGCPList);
        CPLFree(pasGCPList);
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    const int nPixelOffset = GDALGetDataTypeSize(poDS->eDataType) / 8;
    const int nLineOffset = poDS->nRasterXSize * nPixelOffset;

    for( int i = 1; i <= poDS->nBands; i++ )
    {
        poDS->SetBand( i, new FASTRasterBand( poDS, i, poDS->fpChannels[i - 1],
            0, nPixelOffset, nLineOffset, poDS->eDataType, TRUE));
    }

    CPLFree( pszHeader );

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

    // opens overviews.
    poDS->oOvManager.Initialize(poDS, poDS->pszFilename);

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The FAST driver does not support update access to existing"
                  " datasets." );
        return NULL;
    }

    return poDS;
}
Beispiel #16
0
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) {
/* -------------------------------------------------------------------- */
/*      Is this a TerraSAR-X product file?                              */
/* -------------------------------------------------------------------- */
    if (!TSXDataset::Identify( poOpenInfo ))
    {
        return NULL; /* nope */
    }

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The TSX driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    CPLString osFilename;

    if( poOpenInfo->bIsDirectory )
    {
        osFilename =
            CPLFormCIFilename( poOpenInfo->pszFilename,
                               CPLGetFilename( poOpenInfo->pszFilename ),
                               "xml" );
    }
    else
        osFilename = poOpenInfo->pszFilename;

    /* Ingest the XML */
    CPLXMLNode *psData = CPLParseXMLFile( osFilename );
    if (psData == NULL)
        return NULL;

    /* find the product components */
    CPLXMLNode *psComponents
        = CPLGetXMLNode( psData, "=level1Product.productComponents" );
    if (psComponents == NULL) {
        CPLError( CE_Failure, CPLE_OpenFailed,
            "Unable to find <productComponents> tag in file.\n" );
        CPLDestroyXMLNode(psData);
        return NULL;
    }

    /* find the product info tag */
    CPLXMLNode *psProductInfo
        = CPLGetXMLNode( psData, "=level1Product.productInfo" );
    if (psProductInfo == NULL) {
        CPLError( CE_Failure, CPLE_OpenFailed,
            "Unable to find <productInfo> tag in file.\n" );
        CPLDestroyXMLNode(psData);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */

    TSXDataset *poDS = new TSXDataset();

/* -------------------------------------------------------------------- */
/*      Read in product info.                                           */
/* -------------------------------------------------------------------- */

    poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo,
        "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) );
    poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo,
        "generationInfo.groundOperationsType", "unknown" ) );
    poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo,
        "missionInfo.orbitCycle", "unknown" ) );
    poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo,
        "missionInfo.absOrbit", "unknown" ) );
    poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo,
        "missionInfo.orbitDirection", "unknown" ) );
    poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo,
        "acquisitionInfo.imagingMode", "unknown" ) );
    poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo,
        "productVariantInfo.productVariant", "unknown" ) );
    char *pszDataType = CPLStrdup( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageDataType", "unknown" ) );
    poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType );

    /* Get raster information */
    int nRows = atoi( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.numberOfRows", "" ) );
    int nCols = atoi( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.numberOfColumns", "" ) );

    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.rowSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) );

    /* Get equivalent number of looks */
    poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) );
    poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.rangeLooks", "unknown" ) );

    const char *pszProductVariant = CPLGetXMLValue( psProductInfo,
        "productVariantInfo.productVariant", "unknown" );

    poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant );

    /* Determine what product variant this is */
    if (STARTS_WITH_CI(pszProductVariant, "SSC"))
        poDS->nProduct = eSSC;
    else if (STARTS_WITH_CI(pszProductVariant, "MGD"))
        poDS->nProduct = eMGD;
    else if (STARTS_WITH_CI(pszProductVariant, "EEC"))
        poDS->nProduct = eEEC;
    else if (STARTS_WITH_CI(pszProductVariant, "GEC"))
        poDS->nProduct = eGEC;
    else
        poDS->nProduct = eUnknown;

    /* Start reading in the product components */
    char *pszGeorefFile = NULL;
    CPLErr geoTransformErr=CE_Failure;
    for ( CPLXMLNode *psComponent = psComponents->psChild;
          psComponent != NULL;
          psComponent = psComponent->psNext)
    {
        const char *pszType = NULL;
        const char *pszPath = CPLFormFilename(
                CPLGetDirname( osFilename ),
                GetFilePath(psComponent, &pszType),
                "" );
        const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " ");

        if ( !STARTS_WITH_CI(pszType, " ") ) {
            if (STARTS_WITH_CI(pszType, "MAPPING_GRID") ) {
                /* the mapping grid... save as a metadata item this path */
                poDS->SetMetadataItem( "MAPPING_GRID", pszPath );
            }
            else if (STARTS_WITH_CI(pszType, "GEOREF")) {
                /* save the path to the georef data for later use */
                CPLFree( pszGeorefFile );
                pszGeorefFile = CPLStrdup( pszPath );
            }
        }
        else if( !STARTS_WITH_CI(pszPolLayer, " ") &&
            STARTS_WITH_CI(psComponent->pszValue, "imageData") ) {
            /* determine the polarization of this band */
            ePolarization ePol;
            if ( STARTS_WITH_CI(pszPolLayer, "HH") ) {
                ePol = HH;
            }
            else if ( STARTS_WITH_CI(pszPolLayer, "HV") ) {
                ePol = HV;
            }
            else if ( STARTS_WITH_CI(pszPolLayer, "VH") ) {
                ePol = VH;
            }
            else {
                ePol = VV;
            }

            GDALDataType eDataType = STARTS_WITH_CI(pszDataType, "COMPLEX") ?
                GDT_CInt16 : GDT_UInt16;

            /* try opening the file that represents that band */
            GDALDataset *poBandData = reinterpret_cast<GDALDataset *>(
                GDALOpen( pszPath, GA_ReadOnly ) );
            if ( poBandData != NULL ) {
                TSXRasterBand *poBand
                    = new TSXRasterBand( poDS, eDataType, ePol, poBandData );
                poDS->SetBand( poDS->GetRasterCount() + 1, poBand );

                //copy georeferencing info from the band
                //need error checking??
                //it will just save the info from the last band
                CPLFree( poDS->pszProjection );
                poDS->pszProjection = CPLStrdup(poBandData->GetProjectionRef());
                geoTransformErr = poBandData->GetGeoTransform(poDS->adfGeoTransform);
            }
        }
    }

    //now check if there is a geotransform
    if ( strcmp(poDS->pszProjection, "") && geoTransformErr==CE_None)
    {
        poDS->bHaveGeoTransform = TRUE;
    }
    else
    {
        poDS->bHaveGeoTransform = FALSE;
        CPLFree( poDS->pszProjection );
        poDS->pszProjection = CPLStrdup("");
        poDS->adfGeoTransform[0] = 0.0;
        poDS->adfGeoTransform[1] = 1.0;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = 0.0;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = 1.0;
    }

    CPLFree(pszDataType);

/* -------------------------------------------------------------------- */
/*      Check and set matrix representation.                            */
/* -------------------------------------------------------------------- */

    if (poDS->GetRasterCount() == 4) {
        poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
    }

/* -------------------------------------------------------------------- */
/*      Read the four corners and centre GCPs in                        */
/* -------------------------------------------------------------------- */

    CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData,
        "=level1Product.productInfo.sceneInfo" );
    if (psSceneInfo != NULL)
    {
        /* extract the GCPs from the provided file */
        bool success = false;
        if (pszGeorefFile != NULL)
            success = poDS->getGCPsFromGEOREF_XML(pszGeorefFile);

        //if the gcp's cannot be extracted from the georef file, try to get the corner coordinates
        //for now just SSC because the others don't have refColumn and refRow
        if (!success && poDS->nProduct == eSSC)
        {
            int nGCP = 0;
            double dfAvgHeight = CPLAtof(CPLGetXMLValue(psSceneInfo,
                "sceneAverageHeight", "0.0"));

            //count and allocate gcps - there should be five - 4 corners and a centre
            poDS->nGCPCount = 0;
            CPLXMLNode *psNode = psSceneInfo->psChild;
            for ( ; psNode != NULL; psNode = psNode->psNext )
            {
                if (!EQUAL(psNode->pszValue, "sceneCenterCoord") &&
                    !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                    continue;

                poDS->nGCPCount++;
            }
            if (poDS->nGCPCount > 0)
            {
                poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount);

                /* iterate over GCPs */
                for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext )
                {
                    GDAL_GCP *psGCP = poDS->pasGCPList + nGCP;

                    if (!EQUAL(psNode->pszValue, "sceneCenterCoord") &&
                        !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                        continue;

                    psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode, "refColumn",
                        "0.0"));
                    psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode, "refRow", "0.0"));
                    psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode, "lon", "0.0"));
                    psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode, "lat", "0.0"));
                    psGCP->dfGCPZ = dfAvgHeight;
                    psGCP->pszId = CPLStrdup( CPLSPrintf( "%d", nGCP ) );
                    psGCP->pszInfo = CPLStrdup("");

                    nGCP++;
                }

                //set the projection string - the fields are lat/long - seems to be WGS84 datum
                OGRSpatialReference osr;
                osr.SetWellKnownGeogCS( "WGS84" );
                CPLFree(poDS->pszGCPProjection);
                osr.exportToWkt( &(poDS->pszGCPProjection) );
            }
        }

        //gcps override geotransform - does it make sense to have both??
        if (poDS->nGCPCount>0)
        {
            poDS->bHaveGeoTransform = FALSE;
            CPLFree( poDS->pszProjection );
            poDS->pszProjection = CPLStrdup("");
            poDS->adfGeoTransform[0] = 0.0;
            poDS->adfGeoTransform[1] = 1.0;
            poDS->adfGeoTransform[2] = 0.0;
            poDS->adfGeoTransform[3] = 0.0;
            poDS->adfGeoTransform[4] = 0.0;
            poDS->adfGeoTransform[5] = 1.0;
        }

    }
    else {
        CPLError(CE_Warning, CPLE_AppDefined,
            "Unable to find sceneInfo tag in XML document. "
            "Proceeding with caution.");
    }

    CPLFree(pszGeorefFile);

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    CPLDestroyXMLNode(psData);

    return poDS;
}
Beispiel #17
0
GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
    /* Check that this actually is a JAXA PALSAR product */
    if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
        return NULL;
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The JAXAPALSAR driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
    PALSARJaxaDataset *poDS = new PALSARJaxaDataset();

    /* Get the suffix of the filename, we'll need this */
    char *pszSuffix = VSIStrdup( (char *)
                                 (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );

    /* Try to read each of the polarizations */
    char *pszImgFile = (char *)VSIMalloc( 
        strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
        strlen( pszSuffix ) + 8 );

    int nBandNum = 1;

    /* HH */
    FILE *fpHH;
    sprintf( pszImgFile, "%s%sIMG-HH%s", 
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHH = VSIFOpenL( pszImgFile, "rb" );
    if (fpHH != NULL) { 
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
        nBandNum++;
    }

    /* HV */
    FILE *fpHV;
    sprintf( pszImgFile, "%s%sIMG-HV%s", 
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHV = VSIFOpenL( pszImgFile, "rb" );
    if (fpHV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
        nBandNum++;
    }

    /* VH */
    FILE *fpVH;
    sprintf( pszImgFile, "%s%sIMG-VH%s", 
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVH = VSIFOpenL( pszImgFile, "rb" );
    if (fpVH != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
        nBandNum++;
    }

    /* VV */
    FILE *fpVV;
    sprintf( pszImgFile, "%s%sIMG-VV%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVV = VSIFOpenL( pszImgFile, "rb" );
    if (fpVV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
        nBandNum++;
    }

    VSIFree( pszImgFile );

    /* did we get at least one band? */
    if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to find any image data. Aborting opening as PALSAR image.");
        delete poDS;
        return NULL;
    }

    /* read metadata from Leader file. */
    char *pszLeaderFilename = (char *)VSIMalloc( 
        strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
        strlen(pszSuffix) + 5 );
    sprintf( pszLeaderFilename, "%s%sLED%s", 
             CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );

    FILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
    /* check if the leader is actually present */
    if (fpLeader != NULL) {
        ReadMetadata(poDS, fpLeader);
        VSIFCloseL(fpLeader);
    }

    VSIFree(pszLeaderFilename);

    VSIFree( pszSuffix );

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}
Beispiel #18
0
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) {
/* -------------------------------------------------------------------- */
/*      Is this a TerraSAR-X product file?                              */
/* -------------------------------------------------------------------- */
	if (!TSXDataset::Identify( poOpenInfo )) {
		return NULL; /* nope */
	}
    
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The TSX driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
	/* Ingest the XML */
	CPLXMLNode *psData, *psComponents, *psProductInfo;
	psData = CPLParseXMLFile( poOpenInfo->pszFilename );

	/* find the product components */
	psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" );
	if (psComponents == NULL) {
		CPLError( CE_Failure, CPLE_OpenFailed, 
			"Unable to find <productComponents> tag in file.\n" );
		return NULL;
	}

	/* find the product info tag */
	psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" );
	if (psComponents == NULL) {
		CPLError( CE_Failure, CPLE_OpenFailed,
			"Unable to find <productInfo> tag in file.\n" );
		return NULL;
	}

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
	
    TSXDataset *poDS = new TSXDataset();
	poDS->fp = poOpenInfo->fp;
	poOpenInfo->fp = NULL;

/* -------------------------------------------------------------------- */
/*      Read in product info.                                           */
/* -------------------------------------------------------------------- */

    poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo,
        "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) );
	poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, 
		"generationInfo.groundOperationsType", "unknown" ) );
	poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo,
		"missionInfo.orbitCycle", "unknown" ) );
	poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo,
		"missionInfo.absOrbit", "unknown" ) );
	poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo,
		"missionInfo.orbitDirection", "unknown" ) );
	poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo,
		"acquisitionInfo.imagingMode", "unknown" ) );
	poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo,
		"productVariantInfo.productVariant", "unknown" ) ); 
	char *pszDataType = strdup( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageDataType", "unknown" ) );
	poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); 
	
	/* Get raster information */
	int nRows = atoi( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.numberOfRows", "" ) );
	int nCols = atoi( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.numberOfColumns", "" ) );

	poDS->nRasterXSize = nCols;
	poDS->nRasterYSize = nRows;

	poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.rowSpacing", "unknown" ) );
	poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.columnSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) );

	/* Get equivalent number of looks */
	poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.azimuthLooks", "unknown" ) );
	poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.rangeLooks", "unknown" ) );

    const char *pszProductVariant;
    pszProductVariant = CPLGetXMLValue( psProductInfo, 
        "productVariantInfo.productVariant", "unknown" );

    poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant );

    /* Determine what product variant this is */
    if (EQUALN(pszProductVariant,"SSC",3))
        poDS->nProduct = eSSC;
    else if (EQUALN(pszProductVariant,"MGD",3))
        poDS->nProduct = eMGD;
    else if (EQUALN(pszProductVariant,"EEC",3))
        poDS->nProduct = eEEC;
    else if (EQUALN(pszProductVariant,"GEC",3))
        poDS->nProduct = eGEC;
    else
        poDS->nProduct = eUnknown;

	/* Start reading in the product components */
	const char *pszPath;
	char *pszGeorefFile = NULL;
	CPLXMLNode *psComponent;
	for (psComponent = psComponents->psChild; psComponent != NULL;
		 psComponent = psComponent->psNext)
	{
		char *pszType;
		pszPath = CPLFormFilename( 
				CPLGetDirname( poOpenInfo->pszFilename ),
				GetFilePath(psComponent, &pszType), 
				"" );
		const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " ");

		if ( !EQUALN(pszType," ",1) ) {
			if (EQUALN(pszType, "MAPPING_GRID", 12) ) {
				/* the mapping grid... save as a metadata item this path */
				poDS->SetMetadataItem( "MAPPING_GRID", pszPath );	
			}
			else if (EQUALN(pszType, "GEOREF", 6)) {
				/* save the path to the georef data for later use */
				pszGeorefFile = strdup( pszPath );
			}
			CPLFree(pszType);
		}
		else if( !EQUALN(pszPolLayer, " ", 1) && 
			EQUALN(psComponent->pszValue, "imageData", 9) ) {
			/* determine the polarization of this band */
			ePolarization ePol;
			if ( EQUALN(pszPolLayer, "HH", 2) ) {
				ePol = HH;
			}
			else if ( EQUALN(pszPolLayer, "HV" , 2) ) {
				ePol = HV;
			}
			else if ( EQUALN(pszPolLayer, "VH", 2) ) {
				ePol = VH;
			}
			else {
				ePol = VV;
			}

			GDALDataType eDataType = EQUALN(pszDataType, "COMPLEX", 7) ?
				GDT_CInt16 : GDT_UInt16;

			/* try opening the file that represents that band */
			TSXRasterBand *poBand;
			GDALDataset *poBandData;

			poBandData = (GDALDataset *) GDALOpen( pszPath, GA_ReadOnly );
			if ( poBandData != NULL ) {
				poBand = new TSXRasterBand( poDS, eDataType, ePol, 
					poBandData );
				poDS->SetBand( poDS->GetRasterCount() + 1, poBand );
			}
		}
	}

	CPLFree(pszDataType);


/* -------------------------------------------------------------------- */
/*      Check and set matrix representation.                            */
/* -------------------------------------------------------------------- */

	if (poDS->GetRasterCount() == 4) {
		poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
	}

/* -------------------------------------------------------------------- */
/*      Read the four corners and centre GCPs in                        */
/* -------------------------------------------------------------------- */

    CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, 
        "=level1Product.productInfo.sceneInfo" );
    /* for SSC products */
    if (poDS->nProduct == eSSC && psSceneInfo != NULL) {
        CPLXMLNode *psNode;
        int nGCP = 0;
        double dfAvgHeight = atof(CPLGetXMLValue(psSceneInfo, 
            "sceneAverageHeight", "0.0"));
        char szID[3];

        poDS->nGCPCount = 5; /* 5 GCPs provided */
        poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), 
            poDS->nGCPCount);

        /* iterate over GCPs */
        for (psNode = psSceneInfo->psChild; psNode != NULL; 
             psNode = psNode->psNext )
        {
            GDAL_GCP *psGCP = poDS->pasGCPList + nGCP;

            if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && 
                !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                continue;

            CPLSPrintf( szID, "%d", nGCP );
            
            psGCP->dfGCPPixel = atof(CPLGetXMLValue(psNode, "refColumn", 
                "0.0"));
            psGCP->dfGCPLine = atof(CPLGetXMLValue(psNode, "refRow", "0.0"));
            psGCP->dfGCPX = atof(CPLGetXMLValue(psNode, "lon", "0.0"));
            psGCP->dfGCPY = atof(CPLGetXMLValue(psNode, "lat", "0.0"));
            psGCP->dfGCPZ = dfAvgHeight;
            psGCP->pszId = CPLStrdup( szID );
            psGCP->pszInfo = CPLStrdup("");

            nGCP++;
        }
    }
    else if (psSceneInfo != NULL) {
        /* extract the GCPs from the provided file */

        /* TODO */
    }
    else {
        CPLError(CE_Warning, CPLE_AppDefined, 
            "Unable to find sceneInfo tag in XML document. " 
            "Proceeding with caution.");
    }

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    CPLDestroyXMLNode(psData);

    return poDS;
}
Beispiel #19
0
/**
 * GDALMDReaderALOS()
 */
GDALMDReaderALOS::GDALMDReaderALOS(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    CPLString osDirName = CPLGetDirname(pszPath);
    CPLString osBaseName = CPLGetBasename(pszPath);

    const char* pszIMDSourceFilename = CPLFormFilename(osDirName, "summary", ".txt");
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }
    else
    {
        pszIMDSourceFilename = CPLFormFilename( osDirName, "SUMMARY", ".TXT");
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    const char *pszHDRFileName;
    if( osBaseName.size() >= 6 )
    {
        // check if this is separate band or whole image
        // test without 6 symbols
        pszHDRFileName = CPLFormFilename(osDirName, CPLSPrintf("HDR%s",
                                                    osBaseName + 6), "txt");
        if (CPLCheckForFile((char*)pszHDRFileName, papszSiblingFiles))
        {
            m_osHDRSourceFilename = pszHDRFileName;
        }
        else
        {
            pszHDRFileName = CPLFormFilename(osDirName, CPLSPrintf("HDR%s",
                                            osBaseName + 6), "TXT");
            if (CPLCheckForFile((char*)pszHDRFileName, papszSiblingFiles))
            {
                m_osHDRSourceFilename = pszHDRFileName;
            }
        }
    }

    // test without 3 symbols
    if( osBaseName.size() >= 3 && m_osHDRSourceFilename.empty())
    {
        pszHDRFileName = CPLFormFilename(osDirName, CPLSPrintf("HDR%s",
                                         osBaseName + 3), "txt");
        if (CPLCheckForFile((char*)pszHDRFileName, papszSiblingFiles))
        {
            m_osHDRSourceFilename = pszHDRFileName;
        }
        else
        {
            pszHDRFileName = CPLFormFilename(osDirName, CPLSPrintf("HDR%s",
                                             osBaseName + 3), "TXT");
            if (CPLCheckForFile((char*)pszHDRFileName, papszSiblingFiles))
            {
                m_osHDRSourceFilename = pszHDRFileName;
            }
        }
    }

    // test without 6 symbols
    const char *pszRPCFileName;
    if( osBaseName.size() >= 6 )
    {
        pszRPCFileName = CPLFormFilename(osDirName, CPLSPrintf("RPC%s",
                                                    osBaseName + 6), "txt");
        if (CPLCheckForFile((char*)pszRPCFileName, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPCFileName;
        }
        else
        {
            pszRPCFileName = CPLFormFilename(osDirName, CPLSPrintf("RPC%s",
                                            osBaseName + 6), "TXT");
            if (CPLCheckForFile((char*)pszRPCFileName, papszSiblingFiles))
            {
                m_osRPBSourceFilename = pszRPCFileName;
            }
        }
    }

    // test without 3 symbols
    if( osBaseName.size() >= 3 && m_osRPBSourceFilename.empty())
    {
        pszRPCFileName = CPLFormFilename(osDirName, CPLSPrintf("RPC%s",
                                         osBaseName + 3), "txt");
        if (CPLCheckForFile((char*)pszRPCFileName, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPCFileName;
        }
        else
        {
            pszRPCFileName = CPLFormFilename(osDirName, CPLSPrintf("RPC%s",
                                             osBaseName + 3), "TXT");
            if (CPLCheckForFile((char*)pszRPCFileName, papszSiblingFiles))
            {
                m_osRPBSourceFilename = pszRPCFileName;
            }
        }
    }

    if(m_osIMDSourceFilename.size())
        CPLDebug( "MDReaderALOS", "IMD Filename: %s",
              m_osIMDSourceFilename.c_str() );
    if(m_osHDRSourceFilename.size())
        CPLDebug( "MDReaderALOS", "HDR Filename: %s",
              m_osHDRSourceFilename.c_str() );
    if(m_osRPBSourceFilename.size())
        CPLDebug( "MDReaderALOS", "RPB Filename: %s",
              m_osRPBSourceFilename.c_str() );
}
Beispiel #20
0
/**
 * GDALMDReaderPleiades()
 */
GDALMDReaderPleiades::GDALMDReaderPleiades(const char *pszPath,
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    const char* pszBaseName = CPLGetBasename(pszPath);
    size_t nBaseNameLen = strlen(pszBaseName);
    if( nBaseNameLen < 4 || nBaseNameLen > 511 )
        return;

    const char* pszDirName = CPLGetDirname(pszPath);

    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                CPLSPrintf("DIM_%s", pszBaseName + 4), "XML" );
    const char* pszRPBSourceFilename = CPLFormFilename( pszDirName,
                                CPLSPrintf("RPC_%s", pszBaseName + 4), "XML" );

    // find last underline
    char sBaseName[512];
    int nLastUnderline = 0;
    for(size_t i = 4; i < nBaseNameLen; i++)
    {
        sBaseName[i - 4] = pszBaseName[i];
        if(pszBaseName[i] == '_')
            nLastUnderline = i - 4;
    }

    sBaseName[nLastUnderline] = 0;

    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }
    else
    {
        pszIMDSourceFilename = CPLFormFilename( pszDirName, CPLSPrintf("DIM_%s",
                                                            sBaseName), "XML" );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
    {
        m_osRPBSourceFilename = pszRPBSourceFilename;
    }
    else
    {
        pszRPBSourceFilename = CPLFormFilename( pszDirName, CPLSPrintf("RPC_%s",
                                                            sBaseName), "XML" );
        if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPBSourceFilename;
        }
    }

    if( m_osIMDSourceFilename.size() )
        CPLDebug( "MDReaderPleiades", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
    if( m_osRPBSourceFilename.size() )
        CPLDebug( "MDReaderPleiades", "RPB Filename: %s",
                  m_osRPBSourceFilename.c_str() );
}
Beispiel #21
0
/**
 * GDALMDReaderGeoEye()
 */
GDALMDReaderGeoEye::GDALMDReaderGeoEye(const char *pszPath, 
        char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles)
{
    
    const char* pszBaseName = CPLGetBasename(pszPath);
    const char* pszDirName = CPLGetDirname(pszPath);
    size_t nBaseNameLen = strlen(pszBaseName);
    if( nBaseNameLen > 511 )
        return;

    // get _metadata.txt file
    
    // split file name by _rgb_ or _pan_
    char szMetadataName[512] = {0};
    size_t i;
    for(i = 0; i < nBaseNameLen; i++)
    {
        szMetadataName[i] = pszBaseName[i];
        if(EQUALN(pszBaseName + i, "_rgb_", 5) || EQUALN(pszBaseName + i, "_pan_", 5))
        {
            break;
        }
    }
    
    // form metadata file name
    CPLStrlcpy(szMetadataName + i, "_metadata.txt", 14);
    const char* pszIMDSourceFilename = CPLFormFilename( pszDirName,
                                                        szMetadataName, NULL );
    if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
    {
        m_osIMDSourceFilename = pszIMDSourceFilename;
    }                                                     
    else
    {
        CPLStrlcpy(szMetadataName + i, "_METADATA.TXT", 14);
        pszIMDSourceFilename = CPLFormFilename( pszDirName, szMetadataName, NULL );
        if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles))
        {
            m_osIMDSourceFilename = pszIMDSourceFilename;
        }
    }

    // get _rpc.txt file
    
    const char* pszRPBSourceFilename = CPLFormFilename( pszDirName,
                                                        CPLSPrintf("%s_rpc",
                                                        pszBaseName),
                                                        "txt" );
    if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
    {
        m_osRPBSourceFilename = pszRPBSourceFilename;
    }
    else
    {
        pszRPBSourceFilename = CPLFormFilename( pszDirName, CPLSPrintf("%s_RPC",
                                                pszBaseName), "TXT" );
        if (CPLCheckForFile((char*)pszRPBSourceFilename, papszSiblingFiles))
        {
            m_osRPBSourceFilename = pszRPBSourceFilename;
        }
    }

    if( m_osIMDSourceFilename.size() )
        CPLDebug( "MDReaderGeoEye", "IMD Filename: %s",
                  m_osIMDSourceFilename.c_str() );
    if( m_osRPBSourceFilename.size() )
        CPLDebug( "MDReaderGeoEye", "RPB Filename: %s",
                  m_osRPBSourceFilename.c_str() );
}
GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, GDALAccess eAccessIn,
                            char **papszSiblingsIn )

{
/* -------------------------------------------------------------------- */
/*      Ensure that C: is treated as C:\ so we can stat it on           */
/*      Windows.  Similar to what is done in CPLStat().                 */
/* -------------------------------------------------------------------- */
#ifdef WIN32
    if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' )
    {
        char    szAltPath[10];
        
        strcpy( szAltPath, pszFilenameIn );
        strcat( szAltPath, "\\" );
        pszFilename = CPLStrdup( szAltPath );
    }
    else
#endif
        pszFilename = CPLStrdup( pszFilenameIn );

/* -------------------------------------------------------------------- */
/*      Initialize.                                                     */
/* -------------------------------------------------------------------- */

    nHeaderBytes = 0;
    pabyHeader = NULL;
    bIsDirectory = FALSE;
    bStatOK = FALSE;
    eAccess = eAccessIn;
    fp = NULL;
    
/* -------------------------------------------------------------------- */
/*      Collect information about the file.                             */
/* -------------------------------------------------------------------- */
    VSIStatBufL  sStat;

    if( VSIStatL( pszFilename, &sStat ) == 0 )
    {
        bStatOK = TRUE;

        if( VSI_ISREG( sStat.st_mode ) )
        {
            pabyHeader = (GByte *) CPLCalloc(1025,1);

            fp = VSIFOpen( pszFilename, "rb" );

            if( fp != NULL )
            {
                nHeaderBytes = (int) VSIFRead( pabyHeader, 1, 1024, fp );

                VSIRewind( fp );
            }
            /* XXX: ENOENT is used to catch the case of virtual filesystem
             * when we do not have a real file with such a name. Under some
             * circumstances EINVAL reported instead of ENOENT in Windows
             * (for filenames containing colon, e.g. "smth://name"). 
             * See also: #2437 */
            else if( errno == 27 /* "File to large" */ 
                     || errno == ENOENT || errno == EINVAL
#ifdef EOVERFLOW
                     || errno == EOVERFLOW
#else
                     || errno == 75 /* Linux EOVERFLOW */
                     || errno == 79 /* Solaris EOVERFLOW */ 
#endif
                     )
            {
                fp = VSIFOpenL( pszFilename, "rb" );
                if( fp != NULL )
                {
                    nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fp );
                    VSIFCloseL( fp );
                    fp = NULL;
                }
            }
        }
        else if( VSI_ISDIR( sStat.st_mode ) )
            bIsDirectory = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Capture sibling list either from passed in values, or by        */
/*      scanning for them.                                              */
/* -------------------------------------------------------------------- */
    if( papszSiblingsIn != NULL )
    {
        papszSiblingFiles = CSLDuplicate( papszSiblingsIn );
    }
    else if( bStatOK && !bIsDirectory )
    {
        if( CSLTestBoolean( 
                CPLGetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "NO" )) )
        {
            /* skip reading the directory */
            papszSiblingFiles = NULL;
        }
        else
        {
            CPLString osDir = CPLGetDirname( pszFilename );
            papszSiblingFiles = VSIReadDir( osDir );
        }
    }
    else
        papszSiblingFiles = NULL;
}
GDALOpenInfo::GDALOpenInfo(const char *pszFilenameIn, GDALAccess eAccessIn,
                           char **papszSiblingsIn)

{
/* -------------------------------------------------------------------- */
/*      Ensure that C: is treated as C:\ so we can stat it on           */
/*      Windows.  Similar to what is done in CPLStat().                 */
/* -------------------------------------------------------------------- */
#ifdef WIN32
    if (strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':')
    {
        char szAltPath[10];

        strcpy(szAltPath, pszFilenameIn);
        strcat(szAltPath, "\\");
        pszFilename = CPLStrdup(szAltPath);
    }
    else
#endif
    pszFilename = CPLStrdup(pszFilenameIn);

/* -------------------------------------------------------------------- */
/*      Initialize.                                                     */
/* -------------------------------------------------------------------- */

    nHeaderBytes = 0;
    pabyHeader   = NULL;
    bIsDirectory = FALSE;
    bStatOK      = FALSE;
    eAccess      = eAccessIn;
    fp           = NULL;

#ifdef HAVE_READLINK
    int bHasRetried = FALSE;
#endif

/* -------------------------------------------------------------------- */
/*      Collect information about the file.                             */
/* -------------------------------------------------------------------- */
    VSIStatBufL sStat;

#ifdef HAVE_READLINK
retry:
#endif
    if (VSIStatExL(pszFilename, &sStat,
                   VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG) == 0)
    {
        bStatOK = TRUE;

        if (VSI_ISREG(sStat.st_mode))
        {
            pabyHeader = (GByte*) CPLCalloc(1025, 1);

            fp = VSIFOpen(pszFilename, "rb");

            if (fp != NULL)
            {
                nHeaderBytes = (int) VSIFRead(pabyHeader, 1, 1024, fp);

                VSIRewind(fp);
            }
            /* XXX: ENOENT is used to catch the case of virtual filesystem
             * when we do not have a real file with such a name. Under some
             * circumstances EINVAL reported instead of ENOENT in Windows
             * (for filenames containing colon, e.g. "smth://name").
             * See also: #2437 */
            else if (errno == 27 /* "File to large" */
                     || errno == ENOENT || errno == EINVAL
#ifdef EOVERFLOW
                     || errno == EOVERFLOW
#else
                     || errno == 75 /* Linux EOVERFLOW */
                     || errno == 79 /* Solaris EOVERFLOW */
#endif
                     )
            {
                VSILFILE *fpL = VSIFOpenL(pszFilename, "rb");
                if (fpL != NULL)
                {
                    nHeaderBytes = (int) VSIFReadL(pabyHeader, 1, 1024, fpL);
                    VSIFCloseL(fpL);
                }
            }
        }
        else if (VSI_ISDIR(sStat.st_mode))
            bIsDirectory = TRUE;
    }

#ifdef HAVE_READLINK
    else if (!bHasRetried)
    {
        /* If someone creates a file with "ln -sf /vsicurl/http://download.osgeo.org/gdal/data/gtiff/utm.tif my_remote_utm.tif" */
        /* we will be able to open it by passing my_remote_utm.tif */
        /* This helps a lot for GDAL based readers that only provide file explorers to open datasets */
        char szPointerFilename[2048];
        int  nBytes = readlink(pszFilename, szPointerFilename, sizeof(szPointerFilename));
        if (nBytes != -1)
        {
            szPointerFilename[MIN(nBytes, (int)sizeof(szPointerFilename) - 1)] = 0;
            CPLFree(pszFilename);
            pszFilename     = CPLStrdup(szPointerFilename);
            papszSiblingsIn = NULL;
            bHasRetried     = TRUE;
            goto retry;
        }
    }
#endif

/* -------------------------------------------------------------------- */
/*      Capture sibling list either from passed in values, or by        */
/*      scanning for them.                                              */
/* -------------------------------------------------------------------- */
    if (papszSiblingsIn != NULL)
    {
        papszSiblingFiles = CSLDuplicate(papszSiblingsIn);
    }
    else if (bStatOK && !bIsDirectory)
    {
        const char *pszOptionVal =
            CPLGetConfigOption("GDAL_DISABLE_READDIR_ON_OPEN", "NO");
        if (EQUAL(pszOptionVal, "EMPTY_DIR"))
        {
            papszSiblingFiles = CSLAddString(NULL, CPLGetFilename(pszFilename));
        }
        else if (CSLTestBoolean(pszOptionVal))
        {
            /* skip reading the directory */
            papszSiblingFiles = NULL;
        }
        else
        {
            CPLString osDir = CPLGetDirname(pszFilename);
            papszSiblingFiles = VSIReadDir(osDir);
        }
    }
    else
        papszSiblingFiles = NULL;
}