Example #1
0
//! @cond Doxygen_Suppress
int
PamParseHistogram( CPLXMLNode *psHistItem,
                   double *pdfMin, double *pdfMax,
                   int *pnBuckets, GUIntBig **ppanHistogram,
                   int * /* pbIncludeOutOfRange */,
                   int * /* pbApproxOK */ )
{
    if( psHistItem == nullptr )
        return FALSE;

    *pdfMin = CPLAtofM(CPLGetXMLValue( psHistItem, "HistMin", "0"));
    *pdfMax = CPLAtofM(CPLGetXMLValue( psHistItem, "HistMax", "1"));
    *pnBuckets = atoi(CPLGetXMLValue( psHistItem, "BucketCount","2"));

    if( *pnBuckets <= 0 || *pnBuckets > INT_MAX / 2 )
        return FALSE;

    if( ppanHistogram == nullptr )
        return TRUE;

    // Fetch the histogram and use it.
    const char *pszHistCounts = CPLGetXMLValue( psHistItem,
                                                "HistCounts", "" );

    // Sanity check to test consistency of BucketCount and HistCounts.
    if( strlen(pszHistCounts) < 2 * static_cast<size_t>(*pnBuckets) - 1 )
    {
        CPLError(
            CE_Failure, CPLE_AppDefined,
            "HistCounts content isn't consistent with BucketCount value" );
        return FALSE;
    }

    *ppanHistogram = static_cast<GUIntBig *>(
        VSICalloc(sizeof(GUIntBig),*pnBuckets) );
    if( *ppanHistogram == nullptr )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory,
                  "Cannot allocate memory for %d buckets", *pnBuckets );
        return FALSE;
    }

    for( int iBucket = 0; iBucket < *pnBuckets; iBucket++ )
    {
        (*ppanHistogram)[iBucket] = CPLAtoGIntBig(pszHistCounts);

        // Skip to next number.
        while( *pszHistCounts != '\0' && *pszHistCounts != '|' )
            pszHistCounts++;
        if( *pszHistCounts == '|' )
            pszHistCounts++;
    }

    return TRUE;
}
Example #2
0
static void GDALGeoLocRescale(char**& papszMD, const char* pszItem,
                                  double dfRatio, double dfDefaultVal)
{
    double dfVal = CPLAtofM(CSLFetchNameValueDef(papszMD, pszItem,
                                            CPLSPrintf("%.18g", dfDefaultVal)));
    dfVal *= dfRatio;
    papszMD = CSLSetNameValue(papszMD, pszItem, CPLSPrintf("%.18g", dfVal));
}
Example #3
0
CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
    int i;
    ZMapDataset *poGDS = (ZMapDataset *) poDS;

    if (poGDS->fp == NULL)
        return CE_Failure;

    if (nBlockXOff < poGDS->nColNum + 1)
    {
        VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET);
        poGDS->nColNum = -1;
    }

    if (nBlockXOff > poGDS->nColNum + 1)
    {
        for(i=poGDS->nColNum + 1;i<nBlockXOff;i++)
        {
            if (IReadBlock(i,0,pImage) != CE_None)
                return CE_Failure;
        }
    }

    char* pszLine;
    i = 0;
    double dfExp = pow(10.0, poGDS->nDecimalCount);
    while(i<nRasterYSize)
    {
        pszLine = (char*)CPLReadLineL(poGDS->fp);
        if (pszLine == NULL)
            return CE_Failure;
        int nExpected = nRasterYSize - i;
        if (nExpected > poGDS->nValuesPerLine)
            nExpected = poGDS->nValuesPerLine;
        if ((int)strlen(pszLine) != nExpected * poGDS->nFieldSize)
            return CE_Failure;

        for(int j=0;j<nExpected;j++)
        {
            char* pszValue = pszLine + j * poGDS->nFieldSize;
            char chSaved = pszValue[poGDS->nFieldSize];
            pszValue[poGDS->nFieldSize] = 0;
            if (strchr(pszValue, '.') != NULL)
                ((double*)pImage)[i+j] = CPLAtofM(pszValue);
            else
                ((double*)pImage)[i+j] = atoi(pszValue) * dfExp;
            pszValue[poGDS->nFieldSize] = chSaved;
        }

        i += nExpected;
    }

    poGDS->nColNum ++;

    return CE_None;
}
Example #4
0
CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff,
                                   CPL_UNUSED int nBlockYOff,
                                   void * pImage )
{
    ZMapDataset *poGDS = reinterpret_cast<ZMapDataset *>( poDS );

    if (poGDS->fp == NULL)
        return CE_Failure;

    if (nBlockXOff < poGDS->nColNum + 1)
    {
        VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET);
        poGDS->nColNum = -1;
    }

    if (nBlockXOff > poGDS->nColNum + 1)
    {
        for( int i = poGDS->nColNum + 1; i < nBlockXOff; i++ )
        {
            if (IReadBlock(i,0,pImage) != CE_None)
                return CE_Failure;
        }
    }

    int i = 0;
    const double dfExp = std::pow(10.0, poGDS->nDecimalCount);
    while(i<nRasterYSize)
    {
        char* pszLine = const_cast<char *>( CPLReadLineL(poGDS->fp) );
        if (pszLine == NULL)
            return CE_Failure;
        int nExpected = nRasterYSize - i;
        if (nExpected > poGDS->nValuesPerLine)
            nExpected = poGDS->nValuesPerLine;
        if( static_cast<int>( strlen(pszLine) )
            != nExpected * poGDS->nFieldSize )
            return CE_Failure;

        for( int j = 0; j < nExpected; j++ )
        {
            char* pszValue = pszLine + j * poGDS->nFieldSize;
            const char chSaved = pszValue[poGDS->nFieldSize];
            pszValue[poGDS->nFieldSize] = 0;
            if (strchr(pszValue, '.') != NULL)
                reinterpret_cast<double *>( pImage )[i+j] = CPLAtofM(pszValue);
            else
                reinterpret_cast<double *>( pImage )[i+j]
                    = atoi(pszValue) * dfExp;
            pszValue[poGDS->nFieldSize] = chSaved;
        }

        i += nExpected;
    }

    poGDS->nColNum ++;

    return CE_None;
}
Example #5
0
CPLXMLNode *
PamFindMatchingHistogram( CPLXMLNode *psSavedHistograms,
                          double dfMin, double dfMax, int nBuckets,
                          int bIncludeOutOfRange, int bApproxOK )

{
    if( psSavedHistograms == nullptr )
        return nullptr;

    for( CPLXMLNode *psXMLHist = psSavedHistograms->psChild;
         psXMLHist != nullptr;
         psXMLHist = psXMLHist->psNext )
    {
        if( psXMLHist->eType != CXT_Element
            || !EQUAL(psXMLHist->pszValue,"HistItem") )
            continue;

        const double dfHistMin =
            CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMin", "0"));
        const double dfHistMax =
            CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMax", "0"));

        if( !(ARE_REAL_EQUAL(dfHistMin, dfMin) )
            || !(ARE_REAL_EQUAL(dfHistMax, dfMax) )
            || atoi(CPLGetXMLValue( psXMLHist,
                                    "BucketCount","0")) != nBuckets
            || !atoi(CPLGetXMLValue( psXMLHist,
                                     "IncludeOutOfRange","0")) !=
                !bIncludeOutOfRange
            || (!bApproxOK && atoi(CPLGetXMLValue( psXMLHist,
                                                   "Approximate","0"))) )

            continue;

        return psXMLHist;
    }

    return nullptr;
}
double VRTSourcedRasterBand::GetMaximum(int *pbSuccess )
{
    const char *pszValue = NULL;

    if( (pszValue = GetMetadataItem("STATISTICS_MAXIMUM")) != NULL )
    {
        if( pbSuccess != NULL )
            *pbSuccess = TRUE;

        return CPLAtofM(pszValue);
    }

    if ( bAntiRecursionFlag )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VRTSourcedRasterBand::GetMaximum() called recursively on the same band. "
                  "It looks like the VRT is referencing itself." );
        if( pbSuccess != NULL )
            *pbSuccess = FALSE;
        return 0.0;
    }
    bAntiRecursionFlag = TRUE;

    double dfMax = 0;
    for( int iSource = 0; iSource < nSources; iSource++ )
    {
        int bSuccess = FALSE;
        double dfSourceMax = papoSources[iSource]->GetMaximum(GetXSize(), GetYSize(), &bSuccess);
        if (!bSuccess)
        {
            dfMax = GDALRasterBand::GetMaximum(pbSuccess);
            bAntiRecursionFlag = FALSE;
            return dfMax;
        }

        if (iSource == 0 || dfSourceMax > dfMax)
            dfMax = dfSourceMax;
    }

    bAntiRecursionFlag = FALSE;

    if( pbSuccess != NULL )
        *pbSuccess = TRUE;

    return dfMax;
}
Example #7
0
GDALDataset *SAGADataset::Open( GDALOpenInfo * poOpenInfo )

{
    /* -------------------------------------------------------------------- */
    /*	We assume the user is pointing to the binary (ie. .sdat) file.	    */
    /* -------------------------------------------------------------------- */
    if( !EQUAL(CPLGetExtension( poOpenInfo->pszFilename ), "sdat"))
    {
        return NULL;
    }

    CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
    CPLString osName = CPLGetBasename( poOpenInfo->pszFilename );
    CPLString osHDRFilename;

    osHDRFilename = CPLFormCIFilename( osPath, osName, ".sgrd" );


    VSILFILE	*fp;

    fp = VSIFOpenL( osHDRFilename, "r" );
    
    if( fp == NULL )
    {
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Is this file a SAGA header file?  Read a few lines of text      */
    /*      searching for something starting with nrows or ncols.           */
    /* -------------------------------------------------------------------- */
    const char		*pszLine;
    int				nRows = -1, nCols = -1;
    double			dXmin = 0.0, dYmin = 0.0, dCellsize = 0.0, dNoData = 0.0, dZFactor = 0.0;
    int				nLineCount			= 0;
    char			szDataFormat[20]	= "DOUBLE";
    char            szByteOrderBig[10]	= "FALSE";
    char			szTopToBottom[10]	= "FALSE";
    char            **papszHDR			= NULL;
    
	
    while( (pszLine = CPLReadLineL( fp )) != NULL )    
    {
        char	**papszTokens;

        nLineCount++;

        if( nLineCount > 50 || strlen(pszLine) > 1000 )
            break;

        papszHDR = CSLAddString( papszHDR, pszLine );

        papszTokens = CSLTokenizeStringComplex( pszLine, " =", TRUE, FALSE );
        if( CSLCount( papszTokens ) < 2 )
        {		
            CSLDestroy( papszTokens );
            continue;
        }

        if( EQUALN(papszTokens[0],"CELLCOUNT_X",strlen("CELLCOUNT_X")) )
            nCols = atoi(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"CELLCOUNT_Y",strlen("CELLCOUNT_Y")) )
            nRows = atoi(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"POSITION_XMIN",strlen("POSITION_XMIN")) )
            dXmin = CPLAtofM(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"POSITION_YMIN",strlen("POSITION_YMIN")) )
            dYmin = CPLAtofM(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"CELLSIZE",strlen("CELLSIZE")) )
            dCellsize = CPLAtofM(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"NODATA_VALUE",strlen("NODATA_VALUE")) )
            dNoData = CPLAtofM(papszTokens[1]);
        else if( EQUALN(papszTokens[0],"DATAFORMAT",strlen("DATAFORMAT")) )
            strncpy( szDataFormat, papszTokens[1], sizeof(szDataFormat)-1 );
        else if( EQUALN(papszTokens[0],"BYTEORDER_BIG",strlen("BYTEORDER_BIG")) )
            strncpy( szByteOrderBig, papszTokens[1], sizeof(szByteOrderBig)-1 );
        else if( EQUALN(papszTokens[0],"TOPTOBOTTOM",strlen("TOPTOBOTTOM")) )
            strncpy( szTopToBottom, papszTokens[1], sizeof(szTopToBottom)-1 );
        else if( EQUALN(papszTokens[0],"Z_FACTOR",strlen("Z_FACTOR")) )
            dZFactor = CPLAtofM(papszTokens[1]);

        CSLDestroy( papszTokens );
    }

    VSIFCloseL( fp );

    CSLDestroy( papszHDR );

    /* -------------------------------------------------------------------- */
    /*      Did we get the required keywords?  If not we return with        */
    /*      this never having been considered to be a match. This isn't     */
    /*      an error!                                                       */
    /* -------------------------------------------------------------------- */
    if( nRows == -1 || nCols == -1 )
    {
        return NULL;
    }

    if (!GDALCheckDatasetDimensions(nCols, nRows))
    {
        return NULL;
    }
    
    if( EQUALN(szTopToBottom,"TRUE",strlen("TRUE")) )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Currently the SAGA Binary Grid driver does not support\n"
                  "SAGA grids written TOPTOBOTTOM.\n");
        return NULL;
    }
    if( dZFactor != 1.0)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "Currently the SAGA Binary Grid driver does not support\n"
                  "ZFACTORs other than 1.\n");
    }
	
	
	
    /* -------------------------------------------------------------------- */
    /*      Create a corresponding GDALDataset.                             */
    /* -------------------------------------------------------------------- */
    SAGADataset	*poDS = new SAGADataset();

    poDS->eAccess = poOpenInfo->eAccess;
    if( poOpenInfo->eAccess == GA_ReadOnly )
    	poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
    	poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );

    if( poDS->fp == NULL )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "VSIFOpenL(%s) failed unexpectedly.", 
                  poOpenInfo->pszFilename );
        return NULL;
    }

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

    SAGARasterBand *poBand = new SAGARasterBand( poDS, 1 );


    /* -------------------------------------------------------------------- */
    /*      Figure out the byte order.                                      */
    /* -------------------------------------------------------------------- */
    if( EQUALN(szByteOrderBig,"TRUE",strlen("TRUE")) )
        poBand->m_ByteOrder = 1;
    else if( EQUALN(szByteOrderBig,"FALSE",strlen("FALSE")) )
        poBand->m_ByteOrder = 0;


    /* -------------------------------------------------------------------- */
    /*      Figure out the data type.                                       */
    /* -------------------------------------------------------------------- */
    if( EQUAL(szDataFormat,"BIT") )
    {
        poBand->SetDataType(GDT_Byte);
        poBand->m_nBits = 8;
    }
    else if( EQUAL(szDataFormat,"BYTE_UNSIGNED") )
    {
        poBand->SetDataType(GDT_Byte);
        poBand->m_nBits = 8;
    }
    else if( EQUAL(szDataFormat,"BYTE") )
    {
        poBand->SetDataType(GDT_Byte);
        poBand->m_nBits = 8;
    }
    else if( EQUAL(szDataFormat,"SHORTINT_UNSIGNED") )
    {
        poBand->SetDataType(GDT_UInt16);
        poBand->m_nBits = 16;
    }
    else if( EQUAL(szDataFormat,"SHORTINT") )
    {
        poBand->SetDataType(GDT_Int16);
        poBand->m_nBits = 16;
    }
    else if( EQUAL(szDataFormat,"INTEGER_UNSIGNED") )
    {
        poBand->SetDataType(GDT_UInt32);
        poBand->m_nBits = 32;
    }
    else if( EQUAL(szDataFormat,"INTEGER") )
    {
        poBand->SetDataType(GDT_Int32);
        poBand->m_nBits = 32;
    }
    else if( EQUAL(szDataFormat,"FLOAT") )
    {
        poBand->SetDataType(GDT_Float32);
        poBand->m_nBits = 32;
    }
    else if( EQUAL(szDataFormat,"DOUBLE") )
    {
        poBand->SetDataType(GDT_Float64);
        poBand->m_nBits = 64;
    }
    else
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "SAGA driver does not support the dataformat %s.", 
                  szDataFormat );
        delete poBand;
        delete poDS;
        return NULL;
    }	

    /* -------------------------------------------------------------------- */
    /*      Save band information                                           */
    /* -------------------------------------------------------------------- */
    poBand->m_Xmin		= dXmin;
    poBand->m_Ymin		= dYmin;
    poBand->m_NoData	= dNoData;
    poBand->m_Cellsize	= dCellsize;
    poBand->m_Rows		= nRows;
    poBand->m_Cols		= nCols;
	
    poDS->SetBand( 1, poBand );

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

/* -------------------------------------------------------------------- */
/*      Check for a .prj file.                                          */
/* -------------------------------------------------------------------- */
    const char  *pszPrjFilename = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpenL( pszPrjFilename, "r" );

    if( fp != NULL )
    {
        char  **papszLines;
        OGRSpatialReference oSRS;

        VSIFCloseL( fp );
        
        papszLines = CSLLoad( pszPrjFilename );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            CPLFree( poDS->pszProjection );
            oSRS.exportToWkt( &(poDS->pszProjection) );
        }

        CSLDestroy( papszLines );
    }

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

    return poDS;
}
Example #8
0
OGRErr OGRSpatialReference::importFromOzi( const char * const* papszLines )
{
    int iLine;
    const char *pszDatum, *pszProj = NULL, *pszProjParms = NULL;

    Clear();

    int nLines = CSLCount((char**)papszLines);
    if( nLines < 5 )
        return OGRERR_NOT_ENOUGH_DATA;

    pszDatum = papszLines[4];

    for ( iLine = 5; iLine < nLines; iLine++ )
    {
        if ( EQUALN(papszLines[iLine], "Map Projection", 14) )
        {
            pszProj = papszLines[iLine];
        }
        else if ( EQUALN(papszLines[iLine], "Projection Setup", 16) )
        {
            pszProjParms = papszLines[iLine];
        }
    }

    if ( ! ( pszDatum && pszProj && pszProjParms ) )
        return OGRERR_NOT_ENOUGH_DATA;

/* -------------------------------------------------------------------- */
/*      Operate on the basis of the projection name.                    */
/* -------------------------------------------------------------------- */
    char    **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE );
    char    **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", 
                                                         TRUE, TRUE );
    char    **papszDatum = NULL;
                                                         
    if (CSLCount(papszProj) < 2)
    {
        goto not_enough_data;
    }

    if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) )
    {
    }

    else if ( EQUALN(papszProj[1], "Mercator", 8) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        double dfScale = CPLAtof(papszProjParms[3]);
        if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */
        SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                     dfScale,
                     CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
               CPLAtof(papszProjParms[3]),
               CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) )
    {
        if (CSLCount(papszProjParms) < 8) goto not_enough_data;
        SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]),
                CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Sinusoidal", 10) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        SetSinusoidal( CPLAtof(papszProjParms[2]),
                       CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) )
    {
        if (CSLCount(papszProjParms) < 8) goto not_enough_data;
        SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]),
                 CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                 CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "(UTM) Universal Transverse Mercator", 35) && nLines > 5 )
    {
        /* Look for the UTM zone in the calibration point data */
        for ( iLine = 5; iLine < nLines; iLine++ )
        {
            if ( EQUALN(papszLines[iLine], "Point", 5) )
            {
                char    **papszTok = NULL;
                papszTok = CSLTokenizeString2( papszLines[iLine], ",",
                                               CSLT_ALLOWEMPTYTOKENS
                                               | CSLT_STRIPLEADSPACES
                                               | CSLT_STRIPENDSPACES );
                if ( CSLCount(papszTok) < 17
                     || EQUAL(papszTok[2], "")
                     || EQUAL(papszTok[13], "")
                     || EQUAL(papszTok[14], "")
                     || EQUAL(papszTok[15], "")
                     || EQUAL(papszTok[16], "") )
                {
                    CSLDestroy(papszTok);
                    continue;
                }
                SetUTM( CPLAtofM(papszTok[13]), EQUAL(papszTok[16], "N") );
                CSLDestroy(papszTok);
                break;
            }
        }
        if ( iLine == nLines )    /* Try to guess the UTM zone */
        {
            float fMinLongitude = INT_MAX;
            float fMaxLongitude = INT_MIN;
            float fMinLatitude = INT_MAX;
            float fMaxLatitude = INT_MIN;
            int bFoundMMPLL = FALSE;
            for ( iLine = 5; iLine < nLines; iLine++ )
            {
                if ( EQUALN(papszLines[iLine], "MMPLL", 5) )
                {
                    char    **papszTok = NULL;
                    papszTok = CSLTokenizeString2( papszLines[iLine], ",",
                                                   CSLT_ALLOWEMPTYTOKENS
                                                   | CSLT_STRIPLEADSPACES
                                                   | CSLT_STRIPENDSPACES );
                    if ( CSLCount(papszTok) < 4 )
                    {
                        CSLDestroy(papszTok);
                        continue;
                    }
                    float fLongitude = CPLAtofM(papszTok[2]);
                    float fLatitude = CPLAtofM(papszTok[3]);
                    CSLDestroy(papszTok);

                    bFoundMMPLL = TRUE;

                    if ( fMinLongitude > fLongitude )
                        fMinLongitude = fLongitude;
                    if ( fMaxLongitude < fLongitude )
                        fMaxLongitude = fLongitude;
                    if ( fMinLatitude > fLatitude )
                        fMinLatitude = fLatitude;
                    if ( fMaxLatitude < fLatitude )
                        fMaxLatitude = fLatitude;
                }
            }
            float fMedianLatitude = ( fMinLatitude + fMaxLatitude ) / 2;
            float fMedianLongitude = ( fMinLongitude + fMaxLongitude ) / 2;
            if ( bFoundMMPLL && fMaxLatitude <= 90 )
            {
                int nUtmZone;
                if ( fMedianLatitude >= 56 && fMedianLatitude <= 64 && 
                     fMedianLongitude >= 3 && fMedianLongitude <= 12 )
                    nUtmZone = 32;                                             /* Norway exception */
                else if ( fMedianLatitude >= 72 && fMedianLatitude <= 84 && 
                         fMedianLongitude >= 0 && fMedianLongitude <= 42 )
                    nUtmZone = (int) ((fMedianLongitude + 3 ) / 12) * 2 + 31;  /* Svalbard exception */
                else
                    nUtmZone = (int) ((fMedianLongitude + 180 ) / 6) + 1;
                SetUTM( nUtmZone, fMedianLatitude >= 0 );
            }
            else
                CPLDebug( "OSR_Ozi", "UTM Zone not found");
        }
    }

    else if ( EQUALN(papszProj[1], "(I) France Zone I", 17) )
    {
        SetLCC1SP( 49.5, 2.337229167, 0.99987734, 600000, 1200000 );
    }

    else if ( EQUALN(papszProj[1], "(II) France Zone II", 19) )
    {
        SetLCC1SP( 46.8, 2.337229167, 0.99987742, 600000, 2200000 );
    }

    else if ( EQUALN(papszProj[1], "(III) France Zone III", 21) )
    {
        SetLCC1SP( 44.1, 2.337229167, 0.99987750, 600000, 3200000 );
    }

    else if ( EQUALN(papszProj[1], "(IV) France Zone IV", 19) )
    {
        SetLCC1SP( 42.165, 2.337229167, 0.99994471, 234.358, 4185861.369 );
    }

/*
 *  Note : The following projections have not been implemented yet
 *
 */

/*
    else if ( EQUALN(papszProj[1], "(BNG) British National Grid", 27) )
    {
    }

    else if ( EQUALN(papszProj[1], "(IG) Irish Grid", 15) )
    {
    }

    else if ( EQUALN(papszProj[1], "(NZG) New Zealand Grid", 22) )
    {
    }

    else if ( EQUALN(papszProj[1], "(NZTM2) New Zealand TM 2000", 27) )
    {
    }

    else if ( EQUALN(papszProj[1], "(SG) Swedish Grid", 27) )
    {
    }

    else if ( EQUALN(papszProj[1], "(SUI) Swiss Grid", 26) )
    {
    }

    else if ( EQUALN(papszProj[1], "(A)Lambert Azimuthual Equal Area", 32) )
    {
    }

    else if ( EQUALN(papszProj[1], "(EQC) Equidistant Conic", 23) )
    {
    }

    else if ( EQUALN(papszProj[1], "Polyconic (American)", 20) )
    {
    }

    else if ( EQUALN(papszProj[1], "Van Der Grinten", 15) )
    {
    }

    else if ( EQUALN(papszProj[1], "Vertical Near-Sided Perspective", 31) )
    {
    }

    else if ( EQUALN(papszProj[1], "(WIV) Wagner IV", 15) )
    {
    }

    else if ( EQUALN(papszProj[1], "Bonne", 5) )
    {
    }

    else if ( EQUALN(papszProj[1], "(MT0) Montana State Plane Zone 2500", 35) )
    {
    }

    else if ( EQUALN(papszProj[1], "ITA1) Italy Grid Zone 1", 23) )
    {
    }

    else if ( EQUALN(papszProj[1], "ITA2) Italy Grid Zone 2", 23) )
    {
    }

    else if ( EQUALN(papszProj[1], "(VICMAP-TM) Victoria Aust.(pseudo AMG)", 38) )
    {
    }

    else if ( EQUALN(papszProj[1], "VICGRID) Victoria Australia", 27) )
    {
    }

    else if ( EQUALN(papszProj[1], "(VG94) VICGRID94 Victoria Australia", 35) )
    {
    }

    else if ( EQUALN(papszProj[1], "Gnomonic", 8) )
    {
    }
*/

    else
    {
        CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] );
        SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"",
                                       papszProj[1]) );
    }

/* -------------------------------------------------------------------- */
/*      Try to translate the datum/spheroid.                            */
/* -------------------------------------------------------------------- */
    papszDatum = CSLTokenizeString2( pszDatum, ",",
                                               CSLT_ALLOWEMPTYTOKENS
                                               | CSLT_STRIPLEADSPACES
                                               | CSLT_STRIPENDSPACES );
    if ( papszDatum == NULL)
        goto not_enough_data;
        
    if ( !IsLocal() )
    {

/* -------------------------------------------------------------------- */
/*      Verify that we can find the CSV file containing the datums      */
/* -------------------------------------------------------------------- */
        if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ),
                            "EPSG_DATUM_CODE",
                            "4326", CC_Integer ) == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                    "Unable to open OZI support file %s.\n"
                    "Try setting the GDAL_DATA environment variable to point\n"
                    "to the directory containing OZI csv files.",
                    CSVFilename( "ozi_datum.csv" ) );
            goto other_error;
        }

/* -------------------------------------------------------------------- */
/*      Search for matching datum                                       */
/* -------------------------------------------------------------------- */
        const char *pszOziDatum = CSVFilename( "ozi_datum.csv" );
        CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                    CC_ApproxString, "NAME" );
        if( strlen(osDName) == 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "Failed to find datum %s in ozi_datum.csv.",
                    papszDatum[0] );
            goto other_error;
        }

        int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                            CC_ApproxString, "EPSG_DATUM_CODE" ) );

        if ( nDatumCode > 0 ) // There is a matching EPSG code
        {
            OGRSpatialReference oGCS;
            oGCS.importFromEPSG( nDatumCode );
            CopyGeogCSFrom( &oGCS );
        }
        else // We use the parameters from the CSV files
        {
            CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "ELLIPSOID_CODE" );
            double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAX" ) );
            double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAY" ) );
            double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAZ" ) );


    /* -------------------------------------------------------------------- */
    /*      Verify that we can find the CSV file containing the ellipsoids  */
    /* -------------------------------------------------------------------- */
            if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ),
                                "ELLIPSOID_CODE",
                                "20", CC_Integer ) == NULL )
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                    "Unable to open OZI support file %s.\n"
                    "Try setting the GDAL_DATA environment variable to point\n"
                    "to the directory containing OZI csv files.",
                    CSVFilename( "ozi_ellips.csv" ) );
                goto other_error;
            }

    /* -------------------------------------------------------------------- */
    /*      Lookup the ellipse code.                                        */
    /* -------------------------------------------------------------------- */
            const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" );

            CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                        CC_ApproxString, "NAME" );
            if( strlen(osEName) == 0 )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Failed to find ellipsoid %s in ozi_ellips.csv.",
                        osEllipseCode.c_str() );
                goto other_error;
            }

            double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                        CC_ApproxString, "A" ));
            double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                            CC_ApproxString, "INVF" ));

    /* -------------------------------------------------------------------- */
    /*      Create geographic coordinate system.                            */
    /* -------------------------------------------------------------------- */

            SetGeogCS( osDName, osDName, osEName, dfA, dfInvF );
            SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ );

        }
    }

/* -------------------------------------------------------------------- */
/*      Grid units translation                                          */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
        SetLinearUnits( SRS_UL_METER, 1.0 );

    FixupOrdering();

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_NONE;

not_enough_data:

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_NOT_ENOUGH_DATA;

other_error:

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_FAILURE;
}
Example #9
0
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, 
                               const char *pszVRTPath )

{
/* -------------------------------------------------------------------- */
/*      Validate a bit.                                                 */
/* -------------------------------------------------------------------- */
    if( psTree == NULL || psTree->eType != CXT_Element
        || !EQUAL(psTree->pszValue,"VRTRasterBand") )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Invalid node passed to VRTRasterBand::XMLInit()." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char* pszBand = CPLGetXMLValue( psTree, "band", NULL);
    if( pszBand != NULL )
    {
        nBand = atoi(pszBand);
    }

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL);
    if( pszDataType != NULL )
    {
        eDataType = GDALGetDataTypeByName(pszDataType);
    }

/* -------------------------------------------------------------------- */
/*      Apply any band level metadata.                                  */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
    
    if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
        SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );

    if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL )
        bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) );

    SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) );

    SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
        SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
    {
        CPLXMLNode *psEntry;

        CSLDestroy( papszCategoryNames );
        papszCategoryNames = NULL;

        CPLStringList oCategoryNames;

        for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            if( psEntry->eType != CXT_Element 
                || !EQUAL(psEntry->pszValue,"Category") 
                || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
                continue;
            
            oCategoryNames.AddString(
                                (psEntry->psChild) ? psEntry->psChild->pszValue : "");
        }

        papszCategoryNames = oCategoryNames.StealList();
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
    {
        CPLXMLNode *psEntry;
        GDALColorTable oTable;
        int        iEntry = 0;

        for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            GDALColorEntry sCEntry;

            sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
            sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
            sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
            sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }
        
        SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != NULL )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = NULL;

        psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* ==================================================================== */
/*      Overviews                                                       */
/* ==================================================================== */
    CPLXMLNode *psNode;

    for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"Overview") )
            continue;

/* -------------------------------------------------------------------- */
/*      Prepare filename.                                               */
/* -------------------------------------------------------------------- */
        char *pszSrcDSName = NULL;
        CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename");
        const char *pszFilename = 
            psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL;

        if( pszFilename == NULL )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Missing <SourceFilename> element in Overview." );
            return CE_Failure;
        }

        if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL &&
            !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO")))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "<SourceFilename> points to a MEM dataset, which is rather suspect! "
                    "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" );
            return CE_Failure;
        }

        if( pszVRTPath != NULL
            && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) )
        {
            pszSrcDSName = CPLStrdup(
                CPLProjectRelativeFilename( pszVRTPath, pszFilename ) );
        }
        else
            pszSrcDSName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Get the raster band.                                            */
/* -------------------------------------------------------------------- */
        int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1"));

        apoOverviews.resize( apoOverviews.size() + 1 );
        apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName;
        apoOverviews[apoOverviews.size()-1].nBand = nSrcBand;
        
        CPLFree( pszSrcDSName );
    }

/* ==================================================================== */
/*      Mask band (specific to that raster band)                        */
/* ==================================================================== */
    CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand");
    if (psMaskBandNode)
        psNode = psMaskBandNode->psChild;
    else
        psNode = NULL;
    for( ; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"VRTRasterBand") )
            continue;

        if( ((VRTDataset*)poDS)->poMaskBand != NULL)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                       "Illegal mask band at raster band level when a dataset mask band already exists." );
            break;
        }

        const char *pszSubclass = CPLGetXMLValue( psNode, "subclass",
                                                    "VRTSourcedRasterBand" );
        VRTRasterBand  *poBand = NULL;

        if( EQUAL(pszSubclass,"VRTSourcedRasterBand") )
            poBand = new VRTSourcedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") )
            poBand = new VRTDerivedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTRawRasterBand") )
            poBand = new VRTRawRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") )
            poBand = new VRTWarpedRasterBand( GetDataset(), 0 );
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                        "VRTRasterBand of unrecognised subclass '%s'.",
                        pszSubclass );
            break;
        }


        if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None )
        {
            SetMaskBand(poBand);
        }

        break;
    }

    return CE_None;
}
Example #10
0
int AAIGDataset::ParseHeader(const char *pszHeader, const char *pszDataType)
{
    char **papszTokens = CSLTokenizeString2(pszHeader, " \n\r\t", 0);
    const int nTokens = CSLCount(papszTokens);

    int i = 0;
    if ( (i = CSLFindString(papszTokens, "ncols")) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterXSize = atoi(papszTokens[i + 1]);
    if ( (i = CSLFindString(papszTokens, "nrows")) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterYSize = atoi(papszTokens[i + 1]);

    if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize))
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    // TODO(schwehr): Would be good to also factor the file size into the max.
    // TODO(schwehr): Allow the user to disable this check.
    // The driver allocates a panLineOffset array based on nRasterYSize
    constexpr int kMaxDimSize = 10000000;  // 1e7 cells.
    if (nRasterXSize > kMaxDimSize || nRasterYSize > kMaxDimSize)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    double dfCellDX = 0.0;
    double dfCellDY = 0.0;
    if ( (i = CSLFindString(papszTokens, "cellsize")) < 0 )
    {
        int iDX, iDY;
        if( (iDX = CSLFindString(papszTokens, "dx")) < 0 ||
            (iDY = CSLFindString(papszTokens, "dy")) < 0 ||
            iDX + 1 >= nTokens ||
            iDY + 1 >= nTokens )
        {
            CSLDestroy(papszTokens);
            return FALSE;
        }

        dfCellDX = CPLAtofM(papszTokens[iDX + 1]);
        dfCellDY = CPLAtofM(papszTokens[iDY + 1]);
    }
    else
    {
        if (i + 1 >= nTokens)
        {
            CSLDestroy(papszTokens);
            return FALSE;
        }
        dfCellDY = CPLAtofM(papszTokens[i + 1]);
        dfCellDX = dfCellDY;
    }

    int j = 0;
    if ((i = CSLFindString(papszTokens, "xllcorner")) >= 0 &&
        (j = CSLFindString(papszTokens, "yllcorner")) >= 0 &&
        i + 1 < nTokens && j + 1 < nTokens)
    {
        adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]);

        // Small hack to compensate from insufficient precision in cellsize
        // parameter in datasets of
        // http://ccafs-climate.org/data/A2a_2020s/hccpr_hadcm3
        if ((nRasterXSize % 360) == 0 &&
            fabs(adfGeoTransform[0] - (-180.0)) < 1e-12 &&
            dfCellDX == dfCellDY &&
            fabs(dfCellDX - (360.0 / nRasterXSize)) < 1e-9)
        {
            dfCellDY = 360.0 / nRasterXSize;
            dfCellDX = dfCellDY;
        }

        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] =
            CPLAtofM(papszTokens[j + 1]) + nRasterYSize * dfCellDY;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }
    else if ((i = CSLFindString(papszTokens, "xllcenter")) >= 0 &&
             (j = CSLFindString(papszTokens, "yllcenter")) >= 0 &&
             i + 1 < nTokens && j + 1 < nTokens)
    {
        SetMetadataItem(GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT);

        adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]) - 0.5 * dfCellDX;
        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] = CPLAtofM(papszTokens[j + 1]) - 0.5 * dfCellDY +
                             nRasterYSize * dfCellDY;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }
    else
    {
        adfGeoTransform[0] = 0.0;
        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] = 0.0;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }

    if( (i = CSLFindString( papszTokens, "NODATA_value" )) >= 0 &&
        i + 1 < nTokens)
    {
        const char *pszNoData = papszTokens[i + 1];

        bNoDataSet = true;
        dfNoDataValue = CPLAtofM(pszNoData);
        if( pszDataType == nullptr &&
            (strchr(pszNoData, '.') != nullptr ||
             strchr(pszNoData, ',') != nullptr ||
             std::numeric_limits<int>::min() > dfNoDataValue ||
             dfNoDataValue > std::numeric_limits<int>::max()) )
        {
            eDataType = GDT_Float32;
            if( !CPLIsInf(dfNoDataValue) &&
                (fabs(dfNoDataValue) < std::numeric_limits<float>::min() ||
                 fabs(dfNoDataValue) > std::numeric_limits<float>::max()) )
            {
                eDataType = GDT_Float64;
            }
        }
        if( eDataType == GDT_Float32 )
        {
            dfNoDataValue = MapNoDataToFloat(dfNoDataValue);
        }
    }

    CSLDestroy(papszTokens);

    return TRUE;
}
GDALDataset *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE dataset?                             */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the large file API.                         */
/* -------------------------------------------------------------------- */
    VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    ISIS3Dataset 	*poDS;

    poDS = new ISIS3Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }
    
    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*	Assume user is pointing to label (ie .lbl) file for detached option */
/* -------------------------------------------------------------------- */
    //  Image can be inline or detached and point to an image name
    //  the Format can be Tiled or Raw
    //  Object = Core
    //      StartByte   = 65537
    //      Format      = Tile
    //      TileSamples = 128
    //      TileLines   = 128
    //OR-----
    //  Object = Core
    //      StartByte = 1
    //      ^Core     = r0200357_detatched.cub
    //      Format    = BandSequential
    //OR-----
    //  Object = Core
    //      StartByte = 1
    //      ^Core     = r0200357_detached_tiled.cub
    //      Format      = Tile
    //      TileSamples = 128
    //      TileLines   = 128
    
/* -------------------------------------------------------------------- */
/*      What file contains the actual data?                             */
/* -------------------------------------------------------------------- */
    const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" );
    CPLString osQubeFile;

    if( EQUAL(pszCore,"") )
        osQubeFile = poOpenInfo->pszFilename;
    else
    {
        CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
        osQubeFile = CPLFormFilename( osPath, pszCore, NULL );
        poDS->osExternalCube = osQubeFile;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS3 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType = GDT_Byte;
    OGRSpatialReference oSRS;

    int	nRows = -1;
    int nCols = -1;
    int nBands = 1;
    int nSkipBytes = 0;
    int tileSizeX = 0;
    int tileSizeY = 0;
    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double scaleFactor = 1.0;
    double dfNoData = 0.0;
    int	bNoDataSet = FALSE;
    char chByteOrder = 'M';  //default to MSB
    char szLayout[32] = "BandSequential"; //default to band seq.
    const char *target_name; //planet name
    //projection parameters
    const char *map_proj_name;
    int	bProjectionSet = TRUE;
    char proj_target_name[200]; 
    char geog_name[60];  
    char datum_name[60];  
    char sphere_name[60];
    char bIsGeographic = TRUE;
    double semi_major = 0.0;
    double semi_minor = 0.0;
    double iflattening = 0.0;
    float center_lat = 0.0;
    float center_lon = 0.0;
    float first_std_parallel = 0.0;
    float second_std_parallel = 0.0;
    double radLat, localRadius;
    VSILFILE	*fp;

    /*************   Skipbytes     *****************************/
    nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1;

    /*******   Grab format type (BandSequential, Tiled)  *******/
    const char *value;

    value = poDS->GetKeyword( "IsisCube.Core.Format", "" );
    if (EQUAL(value,"Tile") )  { //Todo
        strcpy(szLayout,"Tiled");
       /******* Get Tile Sizes *********/
       tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples",""));
       tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines",""));
       if (tileSizeX <= 0 || tileSizeY <= 0)
       {
           CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d",
                     tileSizeX, tileSizeY);
           delete poDS;
           return NULL;
       }
    }
    else if (EQUAL(value,"BandSequential") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    nCols = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Samples",""));
    nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines",""));
    nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands",""));
     
    /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/
    const char *itype;

    itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" );
    if (EQUAL(itype,"UnsignedByte") ) {
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"UnsignedWord") ) {
        eDataType = GDT_UInt16;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"SignedWord") ) {
        eDataType = GDT_Int16;
        dfNoData = NULL2;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"Real") || EQUAL(value,"") ) {
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
    }
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout type not supported. Abort\n\n", itype);
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder");
    if (EQUAL(value,"Lsb"))
        chByteOrder = 'I';
    
    /***********   Grab Cellsize ************/
    value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution");
    if (strlen(value) > 0 ) {
        dfXDim = atof(value); /* values are in meters */
        dfYDim = -atof(value);
    }
    
    /***********   Grab UpperLeftCornerY ************/
    value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY");
    if (strlen(value) > 0) {
        dfULYMap = atof(value);
    }
     
    /***********   Grab UpperLeftCornerX ************/
    value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX");
    if( strlen(value) > 0 ) {
        dfULXMap = atof(value);
    }
     
    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. Mars ***/
    target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName");
     
    /***********   Grab MAP_PROJECTION_TYPE ************/
    map_proj_name = 
        poDS->GetKeyword( "IsisCube.Mapping.ProjectionName");

    /***********   Grab SEMI-MAJOR ************/
    semi_major = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius"));

    /***********   Grab semi-minor ************/
    semi_minor = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius"));

    /***********   Grab CENTER_LAT ************/
    center_lat = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude"));

    /***********   Grab CENTER_LON ************/
    center_lon = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude"));

    /***********   Grab 1st std parallel ************/
    first_std_parallel = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel"));

    /***********   Grab 2nd std parallel ************/
    second_std_parallel = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel"));
     
    /***********   Grab scaleFactor ************/
    scaleFactor = 
        atof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor"));
     
    /*** grab      LatitudeType = Planetographic ****/
    // Need to further study how ocentric/ographic will effect the gdal library
    // So far we will use this fact to define a sphere or ellipse for some 
    // projections

    // Frank - may need to talk this over
    value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType");
    if (EQUAL( value, "\"Planetocentric\"" ))
        bIsGeographic = FALSE; 
     
    //Set oSRS projection and parameters
    //############################################################
    //ISIS3 Projection types
    //  Equirectangular 
    //  LambertConformal 
    //  Mercator 
    //  ObliqueCylindrical //Todo
    //  Orthographic 
    //  PolarStereographic 
    //  SimpleCylindrical 
    //  Sinusoidal 
    //  TransverseMercator
    
#ifdef DEBUG
    CPLDebug( "ISIS3", "using projection %s", map_proj_name);
#endif

    if ((EQUAL( map_proj_name, "Equirectangular" )) ||
        (EQUAL( map_proj_name, "SimpleCylindrical" )) )  {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "Orthographic" )) {
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "Sinusoidal" )) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "Mercator" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "PolarStereographic" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "TransverseMercator" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "LambertConformal" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else {
        CPLDebug( "ISIS3",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name );
        bProjectionSet = FALSE;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        strcpy(proj_target_name, map_proj_name);
        strcat(proj_target_name, " ");
        strcat(proj_target_name, target_name);
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     
        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        strcpy(geog_name, "GCS_");
        strcat(geog_name, target_name);
        
        //The datum name will be the same basic name as the planet
        strcpy(datum_name, "D_");
        strcat(datum_name, target_name);
     
        strcpy(sphere_name, target_name);
        //strcat(sphere_name, "_IAU_IAG");  //Might not be IAU defined so don't add
          
        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        if ((semi_major - semi_minor) < 0.0000001) 
           iflattening = 0;
        else
           iflattening = semi_major / (semi_major - semi_minor);
     
        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "Stereographic" ) && (fabs(center_lat) == 90)) ) || 
	           (EQUAL( map_proj_name, "PolarStereographic" )) )  
         {
            if (bIsGeographic) { 
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                               "Reference_Meridian", 0.0 );
            } else {
              //Geocentric, so force a sphere using the semi-minor axis. I hope... 
              strcat(sphere_name, "_polarRadius");
              oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                              semi_minor, 0.0, 
                              "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SimpleCylindrical" )) || 
  	               (EQUAL( map_proj_name, "Orthographic" )) || 
	               (EQUAL( map_proj_name, "Stereographic" )) || 
	               (EQUAL( map_proj_name, "Sinusoidal" )) ) {
            //isis uses the sphereical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else if  (EQUAL( map_proj_name, "Equirectangular" )) { 
            //Calculate localRadius using ISIS3 simple elliptical method 
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            radLat = center_lat * PI / 180;  // in radians
            localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) 
                          + pow(semi_major*sin(radLat),2) );
            strcat(sphere_name, "_localRadius");
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            localRadius, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else { 
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else { 
                //Geocentric, so force a sphere. I hope... 
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }

        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS3 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    
/* -------------------------------------------------------------------- */
/*     Is the CUB detached - if so, reset name to binary file?          */
/* -------------------------------------------------------------------- */
#ifdef notdef
    // Frank - is this correct?
    //The extension already added on so don't add another. But is this needed?
    char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) );
    char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) );
    if (bIsDetached)
        pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" );
#endif

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osQubeFile, "r" );
    else
        poDS->fpImage = VSIFOpenL( osQubeFile, "r+" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open %s with write permission.\n%s", 
                  osQubeFile.c_str(),
                  VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int	    nLineOffset=0, nPixelOffset=0, nBandOffset=0;
    
    if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nLineOffset * nRows;
    }
    else /* Tiled */
    {
    }
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int i;

#ifdef CPL_LSB                               
    int bNativeOrder = !(chByteOrder == 'M');
#else
    int bNativeOrder = (chByteOrder == 'M');
#endif        


    for( i = 0; i < nBands; i++ )
    {
        GDALRasterBand	*poBand;

        if( EQUAL(szLayout,"Tiled") )
        {
            poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType,
                                        tileSizeX, tileSizeY, 
                                        nSkipBytes, 0, 0, 
                                        bNativeOrder );
        }
        else
        {
            poBand = 
                new RawRasterBand( poDS, i+1, poDS->fpImage,
                                   nSkipBytes + nBandOffset * i, 
                                   nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB                               
                                   chByteOrder == 'I' || chByteOrder == 'L',
#else
                                   chByteOrder == 'M',
#endif        
                                   TRUE );
        }

        poDS->SetBand( i+1, poBand );

        if( bNoDataSet )
            ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset( 
            CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0")));
        poBand->SetScale( 
          CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For ISIS3 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    CPLString osPath, osName;

    osPath = CPLGetPath( poOpenInfo->pszFilename );
    osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpenL( pszPrjFile, "r" );
    if( fp != NULL )
    {
        char	**papszLines;
        OGRSpatialReference oSRS;

        VSIFCloseL( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = NULL;
            oSRS.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    
    if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }
    
    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
                               poDS->adfGeoTransform );

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

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

    return( poDS );
}
Example #12
0
/**
 * LoadMetadata()
 */
void GDALMDReaderLandsat::LoadMetadata()
{
    if(m_bIsMetadataLoad)
        return;

    if (!m_osIMDSourceFilename.empty())
    {
        m_papszIMDMD = GDALLoadIMDFile( m_osIMDSourceFilename );
    }

    m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ODL");

    m_bIsMetadataLoad = true;

    // date/time
    // DATE_ACQUIRED = 2013-04-07
    // SCENE_CENTER_TIME = 15:47:03.0882620Z

    // L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID
    const char* pszSatId = CSLFetchNameValue(m_papszIMDMD,
                            "L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID");
    if(NULL != pszSatId)
    {
        m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
                                           CPLStripQuotes(pszSatId));
    }

    // L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER
    const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD,
                            "L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER");
    if(NULL != pszCloudCover)
    {
        double fCC = CPLAtofM(pszCloudCover);
        if(fCC < 0)
        {
            m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
                                               MD_CLOUDCOVER_NA);
        }
        else
        {
            m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD,
                          MD_NAME_CLOUDCOVER, CPLSPrintf("%d", int(fCC)));
        }
    }

    // L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE
    // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME

    // L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED
    // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME

    const char* pszDate = CSLFetchNameValue(m_papszIMDMD,
                          "L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE");
    if(NULL == pszDate)
    {
        pszDate = CSLFetchNameValue(m_papszIMDMD,
                             "L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED");
    }

    if(NULL != pszDate)
    {
        const char* pszTime = CSLFetchNameValue(m_papszIMDMD,
                    "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME");
        if(NULL == pszTime)
        {
            pszTime = CSLFetchNameValue(m_papszIMDMD,
                         "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME");
        }
        if(NULL == pszTime)
            pszTime = "00:00:00.000000Z";

        char buffer[80];
        time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s",
                                                     pszDate, pszTime));
        strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid));
        m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD,
                                           MD_NAME_ACQDATETIME, buffer);
    }
}
Example #13
0
CPLErr XYZRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
    XYZDataset *poGDS = (XYZDataset *) poDS;
    
    if (poGDS->fp == NULL)
        return CE_Failure;

    int nLineInFile = nBlockYOff * nBlockXSize;
    if (poGDS->nDataLineNum > nLineInFile)
    {
        poGDS->nDataLineNum = 0;
        VSIFSeekL(poGDS->fp, 0, SEEK_SET);

        for(int i=0;i<poGDS->nCommentLineCount;i++)
            CPLReadLine2L(poGDS->fp, 100, NULL);

        if (poGDS->bHasHeaderLine)
        {
            const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
            if (pszLine == NULL)
            {
                memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
                return CE_Failure;
            }
            poGDS->nLineNum ++;
        }
    }

    while(poGDS->nDataLineNum < nLineInFile)
    {
        const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
        if (pszLine == NULL)
        {
            memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
            return CE_Failure;
        }
        poGDS->nLineNum ++;

        const char* pszPtr = pszLine;
        char ch;
        int nCol = 0;
        int bLastWasSep = TRUE;
        while((ch = *pszPtr) != '\0')
        {
            if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
            {
                if (!bLastWasSep)
                    nCol ++;
                bLastWasSep = TRUE;
            }
            else
            {
                bLastWasSep = FALSE;
            }
            pszPtr ++;
        }

        /* Skip empty line */
        if (nCol == 0 && bLastWasSep)
            continue;

        poGDS->nDataLineNum ++;
    }

    int i;
    for(i=0;i<nBlockXSize;i++)
    {
        int nCol;
        int bLastWasSep;
        do
        {
            const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
            if (pszLine == NULL)
            {
                memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
                return CE_Failure;
            }
            poGDS->nLineNum ++;

            const char* pszPtr = pszLine;
            char ch;
            nCol = 0;
            bLastWasSep = TRUE;
            while((ch = *pszPtr) != '\0')
            {
                if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
                {
                    if (!bLastWasSep)
                        nCol ++;
                    bLastWasSep = TRUE;
                }
                else
                {
                    if (bLastWasSep && nCol == poGDS->nZIndex)
                    {
                        double dfZ = CPLAtofM(pszPtr);
                        if (eDataType == GDT_Float32)
                        {
                            ((float*)pImage)[i] = (float)dfZ;
                        }
                        else if (eDataType == GDT_Int32)
                        {
                            ((GInt32*)pImage)[i] = (GInt32)dfZ;
                        }
                        else if (eDataType == GDT_Int16)
                        {
                            ((GInt16*)pImage)[i] = (GInt16)dfZ;
                        }
                        else
                        {
                            ((GByte*)pImage)[i] = (GByte)dfZ;
                        }
                    }
                    bLastWasSep = FALSE;
                }
                pszPtr ++;
            }

            /* Skip empty line */
        }
        while (nCol == 0 && bLastWasSep);

        poGDS->nDataLineNum ++;
        nCol ++;
        if (nCol < poGDS->nMinTokens)
        {
            memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
            return CE_Failure;
        }
    }
    CPLAssert(poGDS->nDataLineNum == (nBlockYOff + 1) * nBlockXSize);

    return CE_None;
}
Example #14
0
cgrd::CGRDDataset * cgrd::CGRDDataset::Open ( GDALOpenInfo * poOpenInfo )
{
	char ** papszTokens = NULL;

	/************************************************************************/
	/*      Does this look like a grid file?                                */
	/************************************************************************/

	if ( poOpenInfo->nHeaderBytes < 100
	        || ! ( EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DataMark", 8 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Version", 7 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Alpha", 5 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Compress", 8 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "X0", 2 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Y0", 2 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DX", 2 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DY", 2 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Row", 3 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Col", 3 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "ValueType", 9 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Hzoom", 5 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "XYUnit", 6 ) ||
	               EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "ZUnit", 5 ) ) )
	{
		return NULL;
	}

	papszTokens = CSLTokenizeString2 ( ( const char * ) poOpenInfo->pabyHeader,
	                                   ":\n\r\t", 0 );
	int nTokens = CSLCount ( papszTokens );

	/************************************************************************/
	/*      Create a corresponding GDALDataset.                             */
	/************************************************************************/

	CGRDDataset * poDS = new CGRDDataset();

	/************************************************************************/
	/*      Parse the header.                                               */
	/************************************************************************/

	double dfCellDX = 0;
	double dfCellDY = 0;
	double dfWinULX = 0;
	double dfWinULY = 0;
	int bcompress = 0;
	int nDataType = -1; //char =0 ,integer=1
	int XYUnit; //d=0,m=1,other=2
	int ZUnit;  //d=0,m=1,other=2

	int i;

	if ( ( i = CSLFindString ( papszTokens, "DataMark" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( ( i = CSLFindString ( papszTokens, "Version" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( ( i = CSLFindString ( papszTokens, "Alpha" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( ( i = CSLFindString ( papszTokens, "Compress" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	bcompress = atoi ( papszTokens[i + 1] );

	if ( ( i = CSLFindString ( papszTokens, "X0" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	dfWinULX = CPLAtofM ( papszTokens[i + 1] );

	if ( ( i = CSLFindString ( papszTokens, "Y0" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	dfWinULY = CPLAtofM ( papszTokens[i + 1] );

	if ( ( i = CSLFindString ( papszTokens, "DX" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	dfCellDX = CPLAtofM ( papszTokens[i + 1] );

	if ( ( i = CSLFindString ( papszTokens, "DY" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	dfCellDY = CPLAtofM ( papszTokens[i + 1] );

	if ( ( i = CSLFindString ( papszTokens, "Row" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	poDS->SetnRasterYSize ( atoi ( papszTokens[i + 1] ) );

	if ( ( i = CSLFindString ( papszTokens, "Col" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	poDS->SetnRasterXSize ( atoi ( papszTokens[i + 1] ) );

	poDS->BlockXSize(poDS->GetRasterXSize());
	poDS->BlockYSize(1);

	if ( ( i = CSLFindString ( papszTokens, "ValueType" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( EQUAL ( papszTokens[i + 1], "Char" ) )
	{
		nDataType = 0;
	}

	else if ( EQUAL ( papszTokens[i + 1], "Integer" ) )
	{
		nDataType = 1;
	}

	if ( ( i = CSLFindString ( papszTokens, "Hzoom" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	poDS->SetnHZoom ( atoi ( papszTokens[i + 1] ) );

	if ( ( i = CSLFindString ( papszTokens, "XYUnit" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( EQUAL ( papszTokens[i + 1], "M" ) )
	{
		XYUnit = 1;
	}

	else if ( EQUAL ( papszTokens[i + 1], "D" ) )
	{
		XYUnit = 0;
	}

	else
	{
		XYUnit = 2;
	}

	if ( ( i = CSLFindString ( papszTokens, "ZUnit" ) ) < 0 ||
	        i + 1 >= nTokens )
	{
		CSLDestroy ( papszTokens );
		delete poDS;
		return NULL;
	}

	if ( EQUAL ( papszTokens[i + 1], "M" ) )
	{
		ZUnit = 1;
	}

	else if ( EQUAL ( papszTokens[i + 1], "D" ) )
	{
		ZUnit = 0;
	}

	else
	{
		ZUnit = 2;
	}

	poDS->adfGeoTransform[0] = dfWinULX;
	poDS->adfGeoTransform[1] = dfCellDX;
	poDS->adfGeoTransform[2] = 0.0;
	poDS->adfGeoTransform[3] = dfWinULY;
	poDS->adfGeoTransform[4] = 0.0;
	poDS->adfGeoTransform[5] = dfCellDY;
	poDS->bNoDataSet = TRUE;

	GDALDataType eDataType;

	if ( poDS->GetnHZoom() >= 100 )
	{
		eDataType = GDT_Float64;
	}

	else
	{
		eDataType = GDT_Int32;
	}

	/************************************************************************/
	/*    Default nodata value in grd is -9999. You can set by yourself.    */
	/************************************************************************/

	int nodata = -9999;
	poDS->dfNoDataValue = ( double ) ( nodata / poDS->GetnHZoom() );

	/************************************************************************/
	/*     Open file with large file API.                                   */
	/************************************************************************/

	poDS->fp = VSIFOpenL ( poOpenInfo->pszFilename, "r" );

	if ( poDS->fp == NULL )
	{
		CPLError ( CE_Failure, CPLE_OpenFailed,
		           "VSIFOpenL(%s) failed unexpectedly.",
		           poOpenInfo->pszFilename );
		delete poDS;
		return NULL;
	}

	/************************************************************************/
	/*      Find the start of real data.                                    */
	/************************************************************************/

	int  nStartOfData = 0;

	for ( int i = 1; TRUE ; i++ )
	{
		if ( poOpenInfo->pabyHeader[i] == '\0' )
		{
			CPLError ( CE_Failure, CPLE_AppDefined,
			           "Couldn't find data values in dem file.\n" );
			delete poDS;
			return NULL;
		}

		if ( poOpenInfo->pabyHeader[i - 1] == '\n'
		        || poOpenInfo->pabyHeader[i - 1] == '\r' )
		{
			if ( !isalpha ( poOpenInfo->pabyHeader[i] )
			        && poOpenInfo->pabyHeader[i] != '\n'
			        && poOpenInfo->pabyHeader[i] != '\r' )
			{
				nStartOfData = i;

				/* Beginning of real data found. */
				break;
			}
		}
	}

	/************************************************************************/
	/*     Open file with large file API.                                   */
	/************************************************************************/

	poDS->fp = VSIFOpenL ( poOpenInfo->pszFilename, "r" );

	if ( poDS->fp == NULL )
	{
		CPLError ( CE_Failure, CPLE_OpenFailed,
		           "VSIFOpenL(%s) failed unexpectedly.",
		           poOpenInfo->pszFilename );
		delete poDS;
		return NULL;
	}

	/************************************************************************/
	/*      Create band information objects.                                */
	/************************************************************************/

	CGRDRasterBand * poNewBand =
	    new CGRDRasterBand ( poDS, nStartOfData, eDataType );

	poDS->SetBand ( poNewBand );

	if ( poNewBand->panLineOffset == NULL )
	{
		delete poDS;
		return NULL;
	}

	CSLDestroy ( papszTokens );
	return poDS;
}
Example #15
0
static int ProxyMain( int argc, char ** argv )

{
    // GDALDatasetH	hDataset, hOutDS;
    // int			i;
    // int			nRasterXSize, nRasterYSize;
    // const char		*pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
    // GDALDriverH		hDriver;
    // int			*panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */
    // int         nBandCount = 0, bDefBands = TRUE;
    // double		adfGeoTransform[6];
    // GDALDataType	eOutputType = GDT_Unknown;
    // int			nOXSize = 0, nOYSize = 0;
    // char		*pszOXSize=NULL, *pszOYSize=NULL;
    // char                **papszCreateOptions = NULL;
    // int                 anSrcWin[4], bStrict = FALSE;
    // const char          *pszProjection;
    // int                 bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale=FALSE;
    // double	        dfScaleSrcMin=0.0, dfScaleSrcMax=255.0;
    // double              dfScaleDstMin=0.0, dfScaleDstMax=255.0;
    // double              dfULX, dfULY, dfLRX, dfLRY;
    // char                **papszMetadataOptions = NULL;
    // char                *pszOutputSRS = NULL;
    // int                 bQuiet = FALSE, bGotBounds = FALSE;
    // GDALProgressFunc    pfnProgress = GDALTermProgress;
    // int                 nGCPCount = 0;
    // GDAL_GCP            *pasGCPs = NULL;
    // int                 iSrcFileArg = -1, iDstFileArg = -1;
    // int                 bCopySubDatasets = FALSE;
    // double              adfULLR[4] = { 0,0,0,0 };
    // int                 bSetNoData = FALSE;
    // int                 bUnsetNoData = FALSE;
    // double		dfNoDataReal = 0.0;
    // int                 nRGBExpand = 0;
    // int                 bParsedMaskArgument = FALSE;
    // int                 eMaskMode = MASK_AUTO;
    // int                 nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */
    // int                 bStats = FALSE, bApproxStats = FALSE;

    // GDALDatasetH	hDataset, hOutDS;
  GDALDataset	*hDataset = NULL;
  GDALDataset	*hOutDS = NULL;

    int			i;
    int			nRasterXSize, nRasterYSize;
    const char		*pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
    // GDALDriverH		hDriver;
    GDALDriver		*hDriver;
    GDALDataType	eOutputType = GDT_Unknown;
    char                **papszCreateOptions = NULL;
    int                 bStrict = FALSE;
    int                 bQuiet = FALSE;
    GDALProgressFunc    pfnProgress = GDALTermProgress;
    int                 iSrcFileArg = -1, iDstFileArg = -1;
    int                 bSetNoData = FALSE;
    int                 bUnsetNoData = FALSE;
    double		dfNoDataReal = 0.0;

    GDALRasterBand  *inBand = NULL;    
    GDALRasterBand  *outBand = NULL;    
   GByte *srcBuffer;
   double adfGeoTransform[6];
   int nRasterCount;
    int bReplaceIds = FALSE;
    const char *pszReplaceFilename = NULL;
    const char *pszReplaceFieldFrom = NULL;
    const char *pszReplaceFieldTo = NULL;
    std::map<GByte,GByte> mReplaceTable;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
    /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
    /* for the --format or --formats options */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") )
        {
            CPLSetConfigOption( argv[i+1], argv[i+2] );

            i += 2;
        }
    }

/* -------------------------------------------------------------------- */
/*      Register standard GDAL drivers, and process generic GDAL        */
/*      command options.                                                */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Handle command line arguments.                                  */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i],"-of") && i < argc-1 )
            pszFormat = argv[++i];

        else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
        {
            bQuiet = TRUE;
            pfnProgress = GDALDummyProgress;
        }

        else if( EQUAL(argv[i],"-ot") && i < argc-1 )
        {
            int	iType;
            
            for( iType = 1; iType < GDT_TypeCount; iType++ )
            {
                if( GDALGetDataTypeName((GDALDataType)iType) != NULL
                    && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
                             argv[i+1]) )
                {
                    eOutputType = (GDALDataType) iType;
                }
            }

            if( eOutputType == GDT_Unknown )
            {
                printf( "Unknown output pixel type: %s\n", argv[i+1] );
                Usage();
                GDALDestroyDriverManager();
                exit( 2 );
            }
            i++;
        }
        else if( EQUAL(argv[i],"-not_strict")  )
            bStrict = FALSE;
            
        else if( EQUAL(argv[i],"-strict")  )
            bStrict = TRUE;
            
        else if( EQUAL(argv[i],"-a_nodata") && i < argc - 1 )
        {
            if (EQUAL(argv[i+1], "none"))
            {
                bUnsetNoData = TRUE;
            }
            else
            {
                bSetNoData = TRUE;
                dfNoDataReal = CPLAtofM(argv[i+1]);
            }
            i += 1;
        }   

        else if( EQUAL(argv[i],"-co") && i < argc-1 )
        {
            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
        }   


        else if( EQUAL(argv[i],"-replace_ids") && i < argc-3 )
	{
  	    bReplaceIds = TRUE;
            pszReplaceFilename = (argv[++i]);
            pszReplaceFieldFrom = (argv[++i]);
            pszReplaceFieldTo = (argv[++i]);
        }   

        else if( argv[i][0] == '-' )
        {
            printf( "Option %s incomplete, or not recognised.\n\n", 
                    argv[i] );
            Usage();
            GDALDestroyDriverManager();
            exit( 2 );
        }

        else if( pszSource == NULL )
        {
            iSrcFileArg = i;
            pszSource = argv[i];
        }
        else if( pszDest == NULL )
        {
            pszDest = argv[i];
            iDstFileArg = i;
        }

        else
        {
            printf( "Too many command options.\n\n" );
            Usage();
            GDALDestroyDriverManager();
            exit( 2 );
        }
    }

    if( pszDest == NULL )
    {
        Usage();
        GDALDestroyDriverManager();
        exit( 10 );
    }

    if ( strcmp(pszSource, pszDest) == 0)
    {
        fprintf(stderr, "Source and destination datasets must be different.\n");
        GDALDestroyDriverManager();
        exit( 1 );
    }

   if( bReplaceIds )
    {
      if ( ! pszReplaceFilename |  ! pszReplaceFieldFrom | ! pszReplaceFieldTo )
	      	  Usage();
      // FILE * ifile;
      // if (  (ifile = fopen(pszReplaceFilename, "r")) == NULL )
      // 	{
      // 	  fprintf( stderr, "Replace file %s cannot be read!\n\n", pszReplaceFilename );
      // 	  Usage();
      // 	}
      // else
      // 	fclose( ifile );
      mReplaceTable = InitReplaceTable(pszReplaceFilename,
				       pszReplaceFieldFrom,
				       pszReplaceFieldTo);
      printf("TMP ET size: %d\n",(int)mReplaceTable.size());
    }

/* -------------------------------------------------------------------- */
/*      Attempt to open source file.                                    */
/* -------------------------------------------------------------------- */

    // hDataset = GDALOpenShared( pszSource, GA_ReadOnly );
    hDataset = (GDALDataset *) GDALOpen(pszSource, GA_ReadOnly );
   
    if( hDataset == NULL )
    {
        fprintf( stderr,
                 "GDALOpen failed - %d\n%s\n",
                 CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
        GDALDestroyDriverManager();
        exit( 1 );
    }


/* -------------------------------------------------------------------- */
/*      Collect some information from the source file.                  */
/* -------------------------------------------------------------------- */
    // nRasterXSize = GDALGetRasterXSize( hDataset );
    // nRasterYSize = GDALGetRasterYSize( hDataset );
    nRasterXSize = hDataset->GetRasterXSize();
    nRasterYSize = hDataset->GetRasterYSize();

    if( !bQuiet )
        printf( "Input file size is %d, %d\n", nRasterXSize, nRasterYSize );


/* -------------------------------------------------------------------- */
/*      Find the output driver.                                         */
/* -------------------------------------------------------------------- */
    hDriver = GetGDALDriverManager()->GetDriverByName( pszFormat );
    if( hDriver == NULL )
    {
        int	iDr;
        
        printf( "Output driver `%s' not recognised.\n", pszFormat );
        printf( "The following format drivers are configured and support output:\n" );
        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
        {
            GDALDriverH hDriver = GDALGetDriver(iDr);

            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
                || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
                                        NULL ) != NULL )
            {
                printf( "  %s: %s\n",
                        GDALGetDriverShortName( hDriver  ),
                        GDALGetDriverLongName( hDriver ) );
            }
        }
        printf( "\n" );
        Usage();
        
        GDALClose(  (GDALDatasetH) hDataset );
        GDALDestroyDriverManager();
        CSLDestroy( argv );
        CSLDestroy( papszCreateOptions );
        exit( 1 );
    }


/* -------------------------------------------------------------------- */
/*      Create Dataset and copy info                                    */
/* -------------------------------------------------------------------- */

    nRasterCount = hDataset->GetRasterCount();
    printf("creating\n");
    hOutDS = hDriver->Create( pszDest, nRasterXSize, nRasterYSize,
			     nRasterCount, GDT_Byte, papszCreateOptions);
    printf("created\n");

 
    if( hOutDS != NULL )
       {

	 hDataset->GetGeoTransform( adfGeoTransform);
	 hOutDS->SetGeoTransform( adfGeoTransform );
	 hOutDS->SetProjection( hDataset->GetProjectionRef() );

/* ==================================================================== */
/*      Process all bands.                                              */
/* ==================================================================== */
	 // if (0)
    for( i = 1; i < nRasterCount+1; i++ )
    {
      inBand = hDataset->GetRasterBand( i ); 
      // hOutDS->AddBand(GDT_Byte);
      outBand = hOutDS->GetRasterBand( i );      
      CopyBandInfo( inBand, outBand, 0, 1, 1 );
      nRasterXSize = inBand->GetXSize( );
      nRasterYSize = inBand->GetYSize( );


	GByte old_value, new_value;
	// char tmp_value[255];
	// const char *tmp_value2;
	std::map<GByte,GByte>::iterator it;

	//tmp  
      int        nXBlocks, nYBlocks, nXBlockSize, nYBlockSize;
      int        iXBlock, iYBlock;
     inBand->GetBlockSize( &nXBlockSize, &nYBlockSize );
     // nXBlockSize = nXBlockSize / 4;
     // nYBlockSize = nYBlockSize / 4;

     nXBlocks = (inBand->GetXSize() + nXBlockSize - 1) / nXBlockSize;
     nYBlocks = (inBand->GetYSize() + nYBlockSize - 1) / nYBlockSize;

     printf("blocks: %d %d %d %d\n",nXBlockSize,nYBlockSize,nXBlocks,nYBlocks);

      printf("TMP ET creating raster %d x %d\n",nRasterXSize, nRasterYSize);
    //   srcBuffer = new GByte[nRasterXSize * nRasterYSize];
    // printf("reading\n");
    //   inBand->RasterIO( GF_Read, 0, 0, nRasterXSize, nRasterYSize, 
    //   			srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, 
    //   			0, 0 );
      // srcBuffer = (GByte *) CPLMalloc(sizeof(GByte)*nRasterXSize * nRasterYSize);

      srcBuffer = (GByte *) CPLMalloc(nXBlockSize * nYBlockSize);

      for( iYBlock = 0; iYBlock < nYBlocks; iYBlock++ )
      {
	  // if(iYBlock%1000 == 0)
	    // printf("iXBlock: %d iYBlock: %d\n",iXBlock,iYBlock);
          if(iYBlock%1000 == 0)
              printf("iYBlock: %d / %d\n",iYBlock,nYBlocks);
          for( iXBlock = 0; iXBlock < nXBlocks; iXBlock++ )
          {
              int        nXValid, nYValid;
	      
	      // inBand->ReadBlock( iXBlock, iYBlock, srcBuffer );
	      inBand->RasterIO( GF_Read,  iXBlock, iYBlock, nXBlockSize, nYBlockSize, 
	      			srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 
	      			0, 0 );

             // Compute the portion of the block that is valid
             // for partial edge blocks.
	      if( (iXBlock+1) * nXBlockSize > inBand->GetXSize() )
		nXValid = inBand->GetXSize() - iXBlock * nXBlockSize;
	      else
		nXValid = nXBlockSize;

	      if( (iYBlock+1) * nYBlockSize > inBand->GetYSize() )
		nYValid = inBand->GetYSize() - iYBlock * nYBlockSize;
	      else
		nYValid = nYBlockSize;
	      // printf("iXBlock: %d iYBlock: %d read,  nXValid: %d nYValid: %d\n",iXBlock,iYBlock,nXValid, nYValid);

	   // if(0)
	      if ( pszReplaceFilename )
	   	{
	   	  for( int iY = 0; iY < nYValid; iY++ )
	   	    {
	   	      for( int iX = 0; iX < nXValid; iX++ )
	   		{
	   		  // panHistogram[pabyData[iX + iY * nXBlockSize]] += 1;
	   		   old_value = new_value = srcBuffer[iX + iY * nXBlockSize];
	   		  // sprintf(tmp_value,"%d",old_value);
	   		  it = mReplaceTable.find(old_value);
	   		  if ( it != mReplaceTable.end() ) new_value = it->second;
	   		  if ( old_value != new_value ) 
			    {
			      srcBuffer[iX + iY * nXBlockSize] = new_value;
	   		   // printf("old_value %d new_value %d  final %d\n",old_value,new_value, srcBuffer[iX + iY * nXBlockSize]);
			    }
	   		  // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, 
	   		  // 			     tmp_value, CC_Integer, pszReplaceFieldTo);
	   		  // if( tmp_value2 != NULL )
	   		  //   {
	   		  // 	new_value = atoi(tmp_value2);
	   		  //   }
	   		  // new_value = old_value +1;
	   		  // 
			  
	   		}
	   	    }
		  
	   	}
	      
	      // printf("writing\n");
	      // outBand->WriteBlock( iXBlock, iYBlock, srcBuffer );
	      outBand->RasterIO( GF_Write,  iXBlock, iYBlock, nXBlockSize, nYBlockSize, 
	      			srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 
	      			0, 0 );
	      // printf("wrote\n");

	 }
     }

     CPLFree(srcBuffer);

    printf("read\n");

    printf("mod\n");

    // if ( pszReplaceFilename )
    //   {
    // 	GByte old_value, new_value;
    // 	// char tmp_value[255];
    // 	// const char *tmp_value2;
    // 	std::map<GByte,GByte>::iterator it;
    // 	for ( int j=0; j<nRasterXSize*nRasterYSize; j++ ) 
    // 	  {
    // 	    old_value = new_value = srcBuffer[j];
    // 	    // sprintf(tmp_value,"%d",old_value);
    // 	    it = mReplaceTable.find(old_value);
    // 	    if ( it != mReplaceTable.end() ) new_value = it->second;
    // 	    // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, 
    // 	    // 			     tmp_value, CC_Integer, pszReplaceFieldTo);
    // 	    // if( tmp_value2 != NULL )
    // 	    //   {
    // 	    // 	new_value = atoi(tmp_value2);
    // 	    //   }
    // 	    // new_value = old_value +1;
    // 	    if ( old_value != new_value ) srcBuffer[j] = new_value;
    // 	    // printf("old_value %d new_value %d  final %d\n",old_value,new_value, srcBuffer[j]);
    // 	  }
    // printf("writing\n");

    //   outBand->RasterIO( GF_Write, 0, 0, nRasterXSize, nRasterYSize, 
    //   			srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, 
    //   			0, 0 );
    // printf("wrote\n");

    //    delete [] srcBuffer;
    //   }
    }
       }
 

    if( hOutDS != NULL )
      GDALClose(  (GDALDatasetH) hOutDS );
    if( hDataset != NULL )
      GDALClose(  (GDALDatasetH) hDataset );


    GDALDumpOpenDatasets( stderr );
    // GDALDestroyDriverManager();
    CSLDestroy( argv );
    CSLDestroy( papszCreateOptions );
    
    return hOutDS == NULL;
}
Example #16
0
int main( int argc, char ** argv )
{
    GDALDriverH     hDriver;
    const char      *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
    int             bFormatExplicitlySet = FALSE;
    char            **papszLayers = NULL;
    const char      *pszBurnAttribute = NULL;
    double          dfIncreaseBurnValue = 0.0;
    double          dfMultiplyBurnValue = 1.0;
    const char      *pszWHERE = NULL, *pszSQL = NULL;
    GDALDataType    eOutputType = GDT_Float64;
    char            **papszCreateOptions = NULL;
    GUInt32         nXSize = 0, nYSize = 0;
    double          dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0;
    int             bIsXExtentSet = FALSE, bIsYExtentSet = FALSE;
    GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower;
    void            *pOptions = NULL;
    char            *pszOutputSRS = NULL;
    int             bQuiet = FALSE;
    GDALProgressFunc pfnProgress = GDALTermProgress;
    int             i;
    OGRGeometry     *poSpatialFilter = NULL;
    int             bClipSrc = FALSE;
    OGRGeometry     *poClipSrc = NULL;
    const char      *pszClipSrcDS = NULL;
    const char      *pszClipSrcSQL = NULL;
    const char      *pszClipSrcLayer = NULL;
    const char      *pszClipSrcWhere = NULL;
    int              bNoDataSet = FALSE;
    double           dfNoDataValue = 0;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    GDALAllRegister();
    OGRRegisterAll();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i],"--help") )
            Usage();
        else if( EQUAL(argv[i],"-of") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszFormat = argv[++i];
            bFormatExplicitlySet = TRUE;
        }

        else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
        {
            bQuiet = TRUE;
            pfnProgress = GDALDummyProgress;
        }

        else if( EQUAL(argv[i],"-ot") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            int	iType;
            
            for( iType = 1; iType < GDT_TypeCount; iType++ )
            {
                if( GDALGetDataTypeName((GDALDataType)iType) != NULL
                    && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
                             argv[i+1]) )
                {
                    eOutputType = (GDALDataType) iType;
                }
            }

            if( eOutputType == GDT_Unknown )
            {
                Usage(CPLSPrintf("Unknown output pixel type: %s.",
                                 argv[i + 1] ));
            }
            i++;
        }

        else if( EQUAL(argv[i],"-txe") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            dfXMin = CPLAtof(argv[++i]);
            dfXMax = CPLAtof(argv[++i]);
            bIsXExtentSet = TRUE;
        }   

        else if( EQUAL(argv[i],"-tye") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            dfYMin = CPLAtof(argv[++i]);
            dfYMax = CPLAtof(argv[++i]);
            bIsYExtentSet = TRUE;
        }   

        else if( EQUAL(argv[i],"-outsize") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            nXSize = atoi(argv[++i]);
            nYSize = atoi(argv[++i]);
        }   

        else if( EQUAL(argv[i],"-co") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
        }   

        else if( EQUAL(argv[i],"-zfield") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszBurnAttribute = argv[++i];
        }

        else if( EQUAL(argv[i],"-z_increase") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            dfIncreaseBurnValue = CPLAtof(argv[++i]);
        }

        else if( EQUAL(argv[i],"-z_multiply") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            dfMultiplyBurnValue = CPLAtof(argv[++i]);
        }

        else if( EQUAL(argv[i],"-where") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszWHERE = argv[++i];
        }

        else if( EQUAL(argv[i],"-l") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            papszLayers = CSLAddString( papszLayers, argv[++i] );
        }

        else if( EQUAL(argv[i],"-sql") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszSQL = argv[++i];
        }

        else if( EQUAL(argv[i],"-spat") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
            OGRLinearRing  oRing;

            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) );
            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+4]) );
            oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+4]) );
            oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+2]) );
            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) );

            poSpatialFilter = new OGRPolygon();
            ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
            i += 4;
        }

        else if ( EQUAL(argv[i],"-clipsrc") )
        {
            if (i + 1 >= argc)
                Usage(CPLSPrintf("%s option requires 1 or 4 arguments", argv[i]));

            bClipSrc = TRUE;
            errno = 0;
            const double unused = strtod( argv[i + 1], NULL );    // XXX: is it a number or not?
            if ( errno != 0
                 && argv[i + 2] != NULL
                 && argv[i + 3] != NULL
                 && argv[i + 4] != NULL)
            {
                OGRLinearRing  oRing;

                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) );
                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 4]) );
                oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 4]) );
                oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 2]) );
                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) );

                poClipSrc = new OGRPolygon();
                ((OGRPolygon *) poClipSrc)->addRing( &oRing );
                i += 4;

                (void)unused;
            }
            else if (EQUALN(argv[i + 1], "POLYGON", 7)
                     || EQUALN(argv[i + 1], "MULTIPOLYGON", 12))
            {
                OGRGeometryFactory::createFromWkt(&argv[i + 1], NULL, &poClipSrc);
                if ( poClipSrc == NULL )
                {
                    Usage("Invalid geometry. "
                             "Must be a valid POLYGON or MULTIPOLYGON WKT.");
                }
                i++;
            }
            else if (EQUAL(argv[i + 1], "spat_extent") )
            {
                i++;
            }
            else
            {
                pszClipSrcDS = argv[i + 1];
                i++;
            }
        }

        else if ( EQUAL(argv[i], "-clipsrcsql") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcSQL = argv[i + 1];
            i++;
        }

        else if ( EQUAL(argv[i], "-clipsrclayer") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcLayer = argv[i + 1];
            i++;
        }

        else if ( EQUAL(argv[i], "-clipsrcwhere") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcWhere = argv[i + 1];
            i++;
        }

        else if( EQUAL(argv[i],"-a_srs") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            OGRSpatialReference oOutputSRS;

            if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE )
            {
                fprintf( stderr, "Failed to process SRS definition: %s\n", 
                         argv[i+1] );
                GDALDestroyDriverManager();
                exit( 1 );
            }

            oOutputSRS.exportToWkt( &pszOutputSRS );
            i++;
        }   

        else if( EQUAL(argv[i],"-a") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            const char* pszAlgorithm = argv[++i];
            if ( ParseAlgorithmAndOptions( pszAlgorithm, &eAlgorithm, &pOptions )
                 != CE_None )
            {
                fprintf( stderr,
                         "Failed to process algorithm name and parameters.\n" );
                exit( 1 );
            }
            
            char **papszParms = CSLTokenizeString2( pszAlgorithm, ":", FALSE );
            const char* pszNoDataValue = CSLFetchNameValue( papszParms, "nodata" );
            if( pszNoDataValue != NULL )
            {
                bNoDataSet = TRUE;
                dfNoDataValue = CPLAtofM(pszNoDataValue);
            }
            CSLDestroy(papszParms);
        }

        else if( argv[i][0] == '-' )
        {
            Usage(CPLSPrintf("Unknown option name '%s'", argv[i]));
        }

        else if( pszSource == NULL )
        {
            pszSource = argv[i];
        }

        else if( pszDest == NULL )
        {
            pszDest = argv[i];
        }

        else
        {
            Usage("Too many command options.");
        }
    }

    if( pszSource == NULL )
    {
        Usage("Source datasource is not specified.");
    }
    if( pszDest == NULL )
    {
        Usage("Target dataset is not specified.");
    }
    if( pszSQL == NULL && papszLayers == NULL )
    {
        Usage("Neither -sql nor -l are specified.");
    }
    
    if ( bClipSrc && pszClipSrcDS != NULL )
    {
        poClipSrc = LoadGeometry( pszClipSrcDS, pszClipSrcSQL,
                                  pszClipSrcLayer, pszClipSrcWhere );
        if ( poClipSrc == NULL )
        {
            Usage("Cannot load source clip geometry.");
        }
    }
    else if ( bClipSrc && poClipSrc == NULL && !poSpatialFilter )
    {
        Usage("-clipsrc must be used with -spat option or \n"
                 "a bounding box, WKT string or datasource must be "
                 "specified.");
    }

    if ( poSpatialFilter )
    {
        if ( poClipSrc )
        {
            OGRGeometry *poTemp = poSpatialFilter->Intersection( poClipSrc );

            if ( poTemp )
            {
                OGRGeometryFactory::destroyGeometry( poSpatialFilter );
                poSpatialFilter = poTemp;
            }

            OGRGeometryFactory::destroyGeometry( poClipSrc );
            poClipSrc = NULL;
        }
    }
    else
    {
        if ( poClipSrc )
        {
            poSpatialFilter = poClipSrc;
            poClipSrc = NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Find the output driver.                                         */
/* -------------------------------------------------------------------- */
    hDriver = GDALGetDriverByName( pszFormat );
    if( hDriver == NULL )
    {
        int	iDr;
        
        fprintf( stderr,
                 "FAILURE: Output driver `%s' not recognised.\n", pszFormat );
        fprintf( stderr,
        "The following format drivers are configured and support output:\n" );
        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
        {
            GDALDriverH hDriver = GDALGetDriver(iDr);

            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_RASTER, NULL) != NULL &&
                ( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
                || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL) )
            {
                fprintf( stderr, "  %s: %s\n",
                         GDALGetDriverShortName( hDriver  ),
                         GDALGetDriverLongName( hDriver ) );
            }
        }
        printf( "\n" );
        Usage();
    }

/* -------------------------------------------------------------------- */
/*      Open input datasource.                                          */
/* -------------------------------------------------------------------- */
    OGRDataSourceH hSrcDS;

    hSrcDS = OGROpen( pszSource, FALSE, NULL );
    if( hSrcDS == NULL )
    {
        fprintf( stderr, "Unable to open input datasource \"%s\".\n",
                 pszSource );
        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
        exit( 3 );
    }

/* -------------------------------------------------------------------- */
/*      Create target raster file.                                      */
/* -------------------------------------------------------------------- */
    GDALDatasetH    hDstDS;
    int             nLayerCount = CSLCount(papszLayers);
    int             nBands = nLayerCount;

    if ( pszSQL )
        nBands++;

    // FIXME
    if ( nXSize == 0 )
        nXSize = 256;
    if ( nYSize == 0 )
        nYSize = 256;

    if (!bQuiet && !bFormatExplicitlySet)
        CheckExtensionConsistency(pszDest, pszFormat);

    hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands,
                         eOutputType, papszCreateOptions );
    if ( hDstDS == NULL )
    {
        fprintf( stderr, "Unable to create target dataset \"%s\".\n",
                 pszDest );
        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
        exit( 3 );
    }
    
    if( bNoDataSet )
    {
        for( i = 1; i <= nBands; i++ )
        {
            GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, i );
            GDALSetRasterNoDataValue( hBand, dfNoDataValue );
        }
    }

/* -------------------------------------------------------------------- */
/*      If algorithm was not specified assigh default one.              */
/* -------------------------------------------------------------------- */
    if ( !pOptions )
        ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions );

/* -------------------------------------------------------------------- */
/*      Process SQL request.                                            */
/* -------------------------------------------------------------------- */
    if( pszSQL != NULL )
    {
        OGRLayerH hLayer;

        hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL,
                                    (OGRGeometryH)poSpatialFilter, NULL ); 
        if( hLayer != NULL )
        {
            // Custom layer will be rasterized in the first band.
            ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, 1,
                          bIsXExtentSet, bIsYExtentSet,
                          dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
                          dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions,
                          bQuiet, pfnProgress );
        }
    }

/* -------------------------------------------------------------------- */
/*      Process each layer.                                             */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nLayerCount; i++ )
    {
        OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i]);
        if( hLayer == NULL )
        {
            fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", 
                     papszLayers[i] );
            continue;
        }

        if( pszWHERE )
        {
            if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE )
                break;
        }

        if ( poSpatialFilter != NULL )
            OGR_L_SetSpatialFilter( hLayer, (OGRGeometryH)poSpatialFilter );

        // Fetch the first meaningful SRS definition
        if ( !pszOutputSRS )
        {
            OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer );
            if ( hSRS )
                OSRExportToWkt( hSRS, &pszOutputSRS );
        }

        ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize,
                      i + 1 + nBands - nLayerCount,
                      bIsXExtentSet, bIsYExtentSet,
                      dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
                      dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions,
                      bQuiet, pfnProgress );
    }

/* -------------------------------------------------------------------- */
/*      Apply geotransformation matrix.                                 */
/* -------------------------------------------------------------------- */
    double  adfGeoTransform[6];
    adfGeoTransform[0] = dfXMin;
    adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize;
    adfGeoTransform[2] = 0.0;
    adfGeoTransform[3] = dfYMin;
    adfGeoTransform[4] = 0.0;
    adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize;
    GDALSetGeoTransform( hDstDS, adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Apply SRS definition if set.                                    */
/* -------------------------------------------------------------------- */
    if ( pszOutputSRS )
    {
        GDALSetProjection( hDstDS, pszOutputSRS );
        CPLFree( pszOutputSRS );
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    OGR_DS_Destroy( hSrcDS );
    GDALClose( hDstDS );
    OGRGeometryFactory::destroyGeometry( poSpatialFilter );

    CPLFree( pOptions );
    CSLDestroy( papszCreateOptions );
    CSLDestroy( argv );
    CSLDestroy( papszLayers );

    OGRCleanupAll();

    GDALDestroyDriverManager();
 
    return 0;
}
Example #17
0
GDALDataset *VICARDataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a VICAR dataset?                             */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the large file API.                         */
/* -------------------------------------------------------------------- */
    VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    VICARDataset *poDS = new VICARDataset();
    if( ! poDS->oKeywords.Ingest( fpQube, poOpenInfo->pabyHeader ) ) {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }

    VSIFCloseL( fpQube );

    /***** CHECK ENDIANNESS **************/

    const char *value = poDS->GetKeyword( "INTFMT" );
    if (!EQUAL(value,"LOW") ) {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return FALSE;
    }
    value = poDS->GetKeyword( "REALFMT" );
    if (!EQUAL(value,"RIEEE") ) {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return FALSE;
    }

    char chByteOrder = 'M';
    value = poDS->GetKeyword( "BREALFMT" );
    if (EQUAL(value,"VAX") ) {
        chByteOrder = 'I';
    }

    /************ CHECK INSTRUMENT *****************/
    /************ ONLY HRSC TESTED *****************/

    bool bIsDTM = false;
    value = poDS->GetKeyword( "DTM.DTM_OFFSET" );
    if (!EQUAL(value,"") ) {
        bIsDTM = true;
    }

    value = poDS->GetKeyword( "BLTYPE" );
    if (!EQUAL(value,"M94_HRSC") && !bIsDTM ) {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s instrument not tested. Continue with caution!\n\n", value);
    }

    /***********   Grab layout type (BSQ, BIP, BIL) ************/

    char szLayout[10] = "BSQ"; //default to band seq.
    value = poDS->GetKeyword( "ORG" );
    if (!EQUAL(value,"BSQ") )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return FALSE;
    }

    strcpy(szLayout,"BSQ");
    const int nCols = atoi(poDS->GetKeyword("NS"));
    const int nRows = atoi(poDS->GetKeyword("NL"));
    const int nBands = atoi(poDS->GetKeyword("NB"));

    /***********   Grab record bytes  **********/
    int nSkipBytes = atoi(poDS->GetKeyword("NBB"));

    GDALDataType eDataType = GDT_Byte;
    double dfNoData = 0.0;
    if (EQUAL( poDS->GetKeyword( "FORMAT" ), "BYTE" )) {
        eDataType = GDT_Byte;
        dfNoData = NULL1;
    }
    else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "HALF" )) {
        eDataType = GDT_Int16;
        dfNoData = NULL2;
        chByteOrder = 'I';
    }
    else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "FULL" )) {
        eDataType = GDT_UInt32;
        dfNoData = 0;
    }
    else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "REAL" )) {
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        chByteOrder = 'I';
    }
    else {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Could not find known VICAR label entries!\n");
        delete poDS;
        return NULL;
    }

    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be a VICAR file, but failed to find some "
                  "required keywords.",
                  poDS->GetDescription() );
        return FALSE;
    }
/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double xulcenter = 0.0;
    double yulcenter = 0.0;

    value = poDS->GetKeyword("MAP.MAP_SCALE");
    if (strlen(value) > 0 ) {
        dfXDim = CPLAtof(value);
        dfYDim = CPLAtof(value) * -1;
        dfXDim = dfXDim * 1000.0;
        dfYDim = dfYDim * 1000.0;
    }

    double dfSampleOffset_Shift =
        CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Shift", "-0.5" ));

    double dfLineOffset_Shift =
        CPLAtof(CPLGetConfigOption( "PDS_LineProjOffset_Shift", "-0.5" ));

    double dfSampleOffset_Mult =
        CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Mult", "-1.0") );

    double dfLineOffset_Mult =
        CPLAtof( CPLGetConfigOption( "PDS_LineProjOffset_Mult", "1.0") );

    /***********   Grab LINE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("MAP.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = CPLAtof(value);
        dfULYMap = ((yulcenter + dfLineOffset_Shift) * -dfYDim * dfLineOffset_Mult);
    }
    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("MAP.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter = CPLAtof(value);
        dfULXMap = ((xulcenter + dfSampleOffset_Shift) * dfXDim * dfSampleOffset_Mult);
    }

/* ==================================================================== */
/*      Get the coordinate system.                                      */
/* ==================================================================== */
    bool bProjectionSet = true;

    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    const CPLString target_name = poDS->GetKeyword("MAP.TARGET_NAME");

    /**********   Grab MAP_PROJECTION_TYPE *****/
    const CPLString map_proj_name
        = poDS->GetKeyword( "MAP.MAP_PROJECTION_TYPE");

    /******  Grab semi_major & convert to KM ******/
    const double semi_major
        = CPLAtof(poDS->GetKeyword( "MAP.A_AXIS_RADIUS")) * 1000.0;

    /******  Grab semi-minor & convert to KM ******/
    const double semi_minor
        = CPLAtof(poDS->GetKeyword( "MAP.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    const double center_lat =
        CPLAtof(poDS->GetKeyword( "MAP.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    const double center_lon
        = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LONGITUDE"));

    /**********   Grab 1st std parallel *******/
    const double first_std_parallel =
        CPLAtof(poDS->GetKeyword( "MAP.FIRST_STANDARD_PARALLEL"));

    /**********   Grab 2nd std parallel *******/
    const double second_std_parallel =
        CPLAtof(poDS->GetKeyword( "MAP.SECOND_STANDARD_PARALLEL"));

    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    bool bIsGeographic = true;
    value = poDS->GetKeyword("MAP.COORDINATE_SYSTEM_NAME");
    if (EQUAL( value, "PLANETOCENTRIC" ))
        bIsGeographic = false;

/**   Set oSRS projection and parameters --- all PDS supported types added if apparently supported in oSRS
      "AITOFF",  ** Not supported in GDAL??
      "ALBERS",
      "BONNE",
      "BRIESEMEISTER",   ** Not supported in GDAL??
      "CYLINDRICAL EQUAL AREA",
      "EQUIDISTANT",
      "EQUIRECTANGULAR",
      "GNOMONIC",
      "HAMMER",    ** Not supported in GDAL??
      "HENDU",     ** Not supported in GDAL??
      "LAMBERT AZIMUTHAL EQUAL AREA",
      "LAMBERT CONFORMAL",
      "MERCATOR",
      "MOLLWEIDE",
      "OBLIQUE CYLINDRICAL",
      "ORTHOGRAPHIC",
      "SIMPLE CYLINDRICAL",
      "SINUSOIDAL",
      "STEREOGRAPHIC",
      "TRANSVERSE MERCATOR",
      "VAN DER GRINTEN",     ** Not supported in GDAL??
      "WERNER"     ** Not supported in GDAL??
**/
    CPLDebug( "PDS", "using projection %s\n\n", map_proj_name.c_str());

    OGRSpatialReference oSRS;

    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
        (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ||
        (EQUAL( map_proj_name, "EQUIDISTANT" )) )  {
        oSRS.SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) {
        oSRS.SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "SINUSOIDAL" )) {
        oSRS.SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "STEREOGRAPHIC" )) {
        oSRS.SetStereographic ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC")) {
        oSRS.SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.SetLCC ( first_std_parallel, second_std_parallel,
                      center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_AZIMUTHAL_EQUAL_AREA" )) {
        oSRS.SetLAEA( center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "CYLINDRICAL_EQUAL_AREA" )) {
        oSRS.SetCEA  ( first_std_parallel, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MOLLWEIDE" )) {
        oSRS.SetMollweide ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "ALBERS" )) {
        oSRS.SetACEA ( first_std_parallel, second_std_parallel,
                       center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "BONNE" )) {
        oSRS.SetBonne ( first_std_parallel, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "GNOMONIC" )) {
        oSRS.SetGnomonic ( center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "OBLIQUE_CYLINDRICAL" )) { 
        // hope Swiss Oblique Cylindrical is the same
        oSRS.SetSOC ( center_lat, center_lon, 0, 0 );
    } else {
        CPLDebug( "VICAR",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = false;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword

        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        CPLString geog_name = "GCS_" + target_name;

        //The datum and sphere names will be the same basic name aas the planet
        CPLString datum_name = "D_" + target_name;
        CPLString sphere_name = target_name; // + "_IAU_IAG");  //Might not be IAU defined so don't add

        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        double iflattening = 0.0;
        if ((semi_major - semi_minor) < 0.0000001)
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);

        //Set the body size but take into consideration which proj is being used to help w/ compatibility
        //Notice that most PDS projections are spherical based on the fact that ISIS/PICS are spherical
        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) ||
             (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))
        {
            if (bIsGeographic) {
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope...
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || 
                  (EQUAL( map_proj_name, "EQUIDISTANT" )) || 
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || 
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || 
                  (EQUAL( map_proj_name, "SINUSOIDAL" )) ) {
            //isis uses the spherical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        }
        else if (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) {
            //isis uses local radius as a sphere, which is pre-calculated in the PDS label as the semi-major
            sphere_name += "_localRadius";
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        }
        else
        {
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            }
            else
            {
                //Geocentric, so force a sphere. I hope...
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }

        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }

    CPLString osQubeFile = poOpenInfo->pszFilename;
    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( osQubeFile, "psw",
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( osQubeFile, "wld",
                               poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osQubeFile, "r" );
    else
        poDS->fpImage = VSIFOpenL( osQubeFile, "r+" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open %s with write permission.\n%s",
                  osQubeFile.c_str(),
                  VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offsets.                                        */
/* -------------------------------------------------------------------- */

    const long int nItemSize = GDALGetDataTypeSize(eDataType)/8;
    const long int nPixelOffset = nItemSize;
    const long int nLineOffset = nPixelOffset * nCols + atoi(poDS->GetKeyword("NBB")) ;
    const long int nBandOffset = nLineOffset * nRows;

    nSkipBytes = atoi(poDS->GetKeyword("LBLSIZE"));

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    for( int i = 0; i < nBands; i++ )
    {
        GDALRasterBand	*poBand
            = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i,
                                 nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB
                                   chByteOrder == 'I' || chByteOrder == 'L',
#else
                                   chByteOrder == 'M',
#endif
                                   TRUE );

        poDS->SetBand( i+1, poBand );
        poBand->SetNoDataValue( dfNoData );
        if (bIsDTM) {
            poBand->SetScale( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_SCALING_FACTOR") ) );
            poBand->SetOffset( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_OFFSET") ) );
            const char* pszMin = poDS->GetKeyword( "DTM.DTM_MINIMUM_DN", NULL );
            const char* pszMax = poDS->GetKeyword( "DTM.DTM_MAXIMUM_DN", NULL );
            if (pszMin != NULL && pszMax != NULL )
                poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),0,0);
            const char* pszNoData = poDS->GetKeyword( "DTM.DTM_MISSING_DN", NULL );
            if (pszNoData != NULL )
                poBand->SetNoDataValue( CPLAtofM(pszNoData) );
        } else if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" )) {
            float scale=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_SCALING_FACTOR","-1."));
            if (scale < 0.) {
                scale = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_SCALING_FACTOR","1."));
            }
            poBand->SetScale( scale );
            float offset=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_OFFSET","-1."));
            if (offset < 0.) {
                offset = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_OFFSET","0."));
            }
            poBand->SetOffset( offset );
        }
        const char* pszMin = poDS->GetKeyword( "STATISTICS.MINIMUM", NULL );
        const char* pszMax = poDS->GetKeyword( "STATISTICS.MAXIMUM", NULL );
        const char* pszMean = poDS->GetKeyword( "STATISTICS.MEAN", NULL );
        const char* pszStdDev = poDS->GetKeyword( "STATISTICS.STANDARD_DEVIATION", NULL );
        if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL )
                poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),CPLAtofM(pszMean),CPLAtofM(pszStdDev));
    }


/* -------------------------------------------------------------------- */
/*      Instrument-specific keywords as metadata.                       */
/* -------------------------------------------------------------------- */

/******************   HRSC    ******************************/

    if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" ) ) {
        poDS->SetMetadataItem( "SPACECRAFT_NAME", poDS->GetKeyword( "M94_INSTRUMENT.INSTRUMENT_HOST_NAME") );
        poDS->SetMetadataItem( "PRODUCT_TYPE", poDS->GetKeyword( "TYPE"));

        if (EQUAL( poDS->GetKeyword( "M94_INSTRUMENT.DETECTOR_ID"), "MEX_HRSC_SRC" )) {
            static const char *apszKeywords[] =  {
                        "M94_ORBIT.IMAGE_TIME",
                        "FILE.EVENT_TYPE",
                        "FILE.PROCESSING_LEVEL_ID",
                        "M94_INSTRUMENT.DETECTOR_ID", 
                        "M94_CAMERAS.EXPOSURE_DURATION",
                        "HRCONVER.INSTRUMENT_TEMPERATURE", NULL
                    };
            for( int i = 0; apszKeywords[i] != NULL; i++ ) {
                const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] );
                if( pszKeywordValue != NULL )
                    poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue );
            }
        } else {
            static const char *apszKeywords[] =  {
                "M94_ORBIT.START_TIME", "M94_ORBIT.STOP_TIME",
                "M94_INSTRUMENT.DETECTOR_ID",
                "M94_CAMERAS.MACROPIXEL_SIZE",
                "FILE.EVENT_TYPE",
                "M94_INSTRUMENT.MISSION_PHASE_NAME",
                "HRORTHO.SPICE_FILE_NAME",
                "HRCONVER.MISSING_FRAMES", "HRCONVER.OVERFLOW_FRAMES", "HRCONVER.ERROR_FRAMES",
                "HRFOOT.BEST_GROUND_SAMPLING_DISTANCE",
                "DLRTO8.RADIANCE_SCALING_FACTOR", "DLRTO8.RADIANCE_OFFSET",
                "DLRTO8.REFLECTANCE_SCALING_FACTOR", "DLRTO8.REFLECTANCE_OFFSET",
                "HRCAL.RADIANCE_SCALING_FACTOR", "HRCAL.RADIANCE_OFFSET",
                "HRCAL.REFLECTANCE_SCALING_FACTOR", "HRCAL.REFLECTANCE_OFFSET",
                "HRORTHO.DTM_NAME", "HRORTHO.EXTORI_FILE_NAME", "HRORTHO.GEOMETRIC_CALIB_FILE_NAME",
                NULL
            };
            for( int i = 0; apszKeywords[i] != NULL; i++ ) {
                const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i], NULL );
                if( pszKeywordValue != NULL )
                    poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue );
            }
        }
    }
    if (bIsDTM && EQUAL( poDS->GetKeyword( "MAP.TARGET_NAME"), "MARS" )) {
        poDS->SetMetadataItem( "SPACECRAFT_NAME", "MARS_EXPRESS" );
        poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM");
        static const char *apszKeywords[] = {
            "DTM.DTM_MISSING_DN", "DTM.DTM_OFFSET", "DTM.DTM_SCALING_FACTOR", "DTM.DTM_A_AXIS_RADIUS", 
            "DTM.DTM_B_AXIS_RADIUS", "DTM.DTM_C_AXIS_RADIUS", "DTM.DTM_DESC", "DTM.DTM_MINIMUM_DN",
            "DTM.DTM_MAXIMUM_DN", NULL };
        for( int i = 0; apszKeywords[i] != NULL; i++ ) {
            const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] );
            if( pszKeywordValue != NULL )
                poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue );
        }
    }


/******************   DAWN   ******************************/
    else if (EQUAL( poDS->GetKeyword( "INSTRUMENT_ID"), "FC2" )) {
        poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" );
        static const char *apszKeywords[] =  {"ORBIT_NUMBER","FILTER_NUMBER",
        "FRONT_DOOR_STATUS",
        "FIRST_LINE",
        "FIRST_LINE_SAMPLE",
        "PRODUCER_INSTITUTION_NAME",
        "SOURCE_FILE_NAME",
        "PROCESSING_LEVEL_ID",
        "TARGET_NAME",
        "LIMB_IN_IMAGE",
        "POLE_IN_IMAGE",
        "REFLECTANCE_SCALING_FACTOR",
        "SPICE_FILE_NAME",
        "SPACECRAFT_CENTRIC_LATITUDE",
        "SPACECRAFT_EASTERN_LONGITUDE",
        "FOOTPRINT_POSITIVE_LONGITUDE",
            NULL };
        for( int i = 0; apszKeywords[i] != NULL; i++ ) {
            const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] );
            if( pszKeywordValue != NULL )
                poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue );
        }

    }
    else if (bIsDTM && EQUAL( poDS->GetKeyword( "TARGET_NAME"), "VESTA" )) {
        poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" );
        poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM");
        static const char *apszKeywords[] = {
            "DTM_MISSING_DN", "DTM_OFFSET", "DTM_SCALING_FACTOR", "DTM_A_AXIS_RADIUS", 
            "DTM_B_AXIS_RADIUS", "DTM_C_AXIS_RADIUS", "DTM_MINIMUM_DN",
            "DTM_MAXIMUM_DN", "MAP_PROJECTION_TYPE", "COORDINATE_SYSTEM_NAME",
            "POSITIVE_LONGITUDE_DIRECTION", "MAP_SCALE",
            "CENTER_LONGITUDE", "LINE_PROJECTION_OFFSET", "SAMPLE_PROJECTION_OFFSET",
            NULL };
        for( int i = 0; apszKeywords[i] != NULL; i++ ) {
            const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] );
            if( pszKeywordValue != NULL )
                poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue );
        }
    }


/* -------------------------------------------------------------------- */
/*      END Instrument-specific keywords as metadata.                   */
/* -------------------------------------------------------------------- */

    if (EQUAL(poDS->GetKeyword( "EOL"), "1" ))
        poDS->SetMetadataItem( "END-OF-DATASET_LABEL", "PRESENT" );
    poDS->SetMetadataItem( "CONVERSION_DETAILS", "http://www.lpi.usra.edu/meetings/lpsc2014/pdf/1088.pdf" );

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

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

    return( poDS );
}
Example #18
0
GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )

{
    int         i;
    int         bHasHeaderLine;
    int         nCommentLineCount = 0;

    if (!IdentifyEx(poOpenInfo, bHasHeaderLine, nCommentLineCount))
        return NULL;

    CPLString osFilename(poOpenInfo->pszFilename);

    /*  GZipped .xyz files are common, so automagically open them */
    /*  if the /vsigzip/ has not been explicitely passed */
    if (strlen(poOpenInfo->pszFilename) > 6 &&
        EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "xyz.gz") &&
        !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
    {
        osFilename = "/vsigzip/";
        osFilename += poOpenInfo->pszFilename;
    }

/* -------------------------------------------------------------------- */
/*      Find dataset characteristics                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    /* For better performance of CPLReadLine2L() we create a buffered reader */
    /* (except for /vsigzip/ since it has one internally) */
    if (!EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
        fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp);
    
    const char* pszLine;
    int nXIndex = -1, nYIndex = -1, nZIndex = -1;
    int nMinTokens = 0;


    for(i=0;i<nCommentLineCount;i++)
        CPLReadLine2L(fp, 100, NULL);

/* -------------------------------------------------------------------- */
/*      Parse header line                                               */
/* -------------------------------------------------------------------- */
    if (bHasHeaderLine)
    {
        pszLine = CPLReadLine2L(fp, 100, NULL);
        if (pszLine == NULL)
        {
            VSIFCloseL(fp);
            return NULL;
        }
        char** papszTokens = CSLTokenizeString2( pszLine, " ,\t;",
                                                 CSLT_HONOURSTRINGS );
        int nTokens = CSLCount(papszTokens);
        if (nTokens < 3)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "At line %d, found %d tokens. Expected 3 at least",
                      1, nTokens);
            CSLDestroy(papszTokens);
            VSIFCloseL(fp);
            return NULL;
        }
        int i;
        for(i=0;i<nTokens;i++)
        {
            if (EQUAL(papszTokens[i], "x") ||
                EQUALN(papszTokens[i], "lon", 3) ||
                EQUALN(papszTokens[i], "east", 4))
                nXIndex = i;
            else if (EQUAL(papszTokens[i], "y") ||
                     EQUALN(papszTokens[i], "lat", 3) ||
                     EQUALN(papszTokens[i], "north", 5))
                nYIndex = i;
            else if (EQUAL(papszTokens[i], "z") ||
                     EQUALN(papszTokens[i], "alt", 3) ||
                     EQUAL(papszTokens[i], "height"))
                nZIndex = i;
        }
        CSLDestroy(papszTokens);
        papszTokens = NULL;
        if (nXIndex < 0 || nYIndex < 0 || nZIndex < 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Could not find one of the X, Y or Z column names in header line. Defaulting to the first 3 columns");
            nXIndex = 0;
            nYIndex = 1;
            nZIndex = 2;
        }
        nMinTokens = 1 + MAX(MAX(nXIndex, nYIndex), nZIndex);
    }
    else
    {
        nXIndex = 0;
        nYIndex = 1;
        nZIndex = 2;
        nMinTokens = 3;
    }
    
/* -------------------------------------------------------------------- */
/*      Parse data lines                                                */
/* -------------------------------------------------------------------- */

    int nXSize = 0, nYSize = 0;
    int nLineNum = 0;
    int nDataLineNum = 0;
    double dfFirstX = 0;
    double dfX = 0, dfY = 0, dfZ = 0;
    double dfMinX = 0, dfMinY = 0, dfMaxX = 0, dfMaxY = 0;
    double dfLastX = 0, dfLastY = 0;
    double dfStepX = 0, dfStepY = 0;
    GDALDataType eDT = GDT_Byte;
    while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL)
    {
        nLineNum ++;

        const char* pszPtr = pszLine;
        char ch;
        int nCol = 0;
        int bLastWasSep = TRUE;
        while((ch = *pszPtr) != '\0')
        {
            if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
            {
                if (!bLastWasSep)
                    nCol ++;
                bLastWasSep = TRUE;
            }
            else
            {
                if (bLastWasSep)
                {
                    if (nCol == nXIndex)
                        dfX = CPLAtofM(pszPtr);
                    else if (nCol == nYIndex)
                        dfY = CPLAtofM(pszPtr);
                    else if (nCol == nZIndex && eDT != GDT_Float32)
                    {
                        dfZ = CPLAtofM(pszPtr);
                        int nZ = (int)dfZ;
                        if ((double)nZ != dfZ)
                        {
                            eDT = GDT_Float32;
                        }
                        else if ((eDT == GDT_Byte || eDT == GDT_Int16) && (nZ < 0 || nZ > 255))
                        {
                            if (nZ < -32768 || nZ > 32767)
                                eDT = GDT_Int32;
                            else
                                eDT = GDT_Int16;
                        }
                    }
                }
                bLastWasSep = FALSE;
            }
            pszPtr ++;
        }
        /* skip empty lines */
        if (bLastWasSep && nCol == 0)
        {
            continue;
        }
        nDataLineNum ++;
        nCol ++;
        if (nCol < nMinTokens)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "At line %d, found %d tokens. Expected %d at least",
                      nLineNum, nCol, nMinTokens);
            VSIFCloseL(fp);
            return NULL;
        }

        if (nDataLineNum == 1)
        {
            dfFirstX = dfMinX = dfMaxX = dfX;
            dfMinY = dfMaxY = dfY;
        }
        else
        {
            if (dfX < dfMinX) dfMinX = dfX;
            if (dfX > dfMaxX) dfMaxX = dfX;
            if (dfY < dfMinY) dfMinY = dfY;
            if (dfY > dfMaxY) dfMaxY = dfY;
        }
        if (nDataLineNum == 2)
        {
            dfStepX = dfX - dfLastX;
            if (dfStepX <= 0)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Ungridded dataset: At line %d, X spacing was %f. Expected >0 value",
                         nLineNum, dfStepX);
                VSIFCloseL(fp);
                return NULL;
            }
        }
        else if (nDataLineNum > 2)
        {
            double dfNewStepX = dfX - dfLastX;
            double dfNewStepY = dfY - dfLastY;
            if (dfNewStepY != 0)
            {
                nYSize ++;
                if (dfStepY == 0)
                {
                    nXSize = nDataLineNum - 1;
                    double dfAdjustedStepX = (dfMaxX - dfMinX) / (nXSize - 1);
                    if (fabs(dfStepX - dfAdjustedStepX) > 1e-8)
                    {
                        CPLDebug("XYZ", "Adjusting stepx from %f to %f", dfStepX, dfAdjustedStepX);
                    }
                    dfStepX = dfAdjustedStepX;
                }
                if (dfStepY != 0 && fabs(dfX - dfFirstX) > 1e-8)
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Ungridded dataset: At line %d, X is %f, where as %f was expected",
                             nLineNum, dfX, dfFirstX);
                    VSIFCloseL(fp);
                    return NULL;
                }
                if (dfStepY != 0 && fabs(dfLastX - dfMaxX) > 1e-8)
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Ungridded dataset: At line %d, X is %f, where as %f was expected",
                             nLineNum - 1, dfLastX, dfMaxX);
                    VSIFCloseL(fp);
                    return NULL;
                }
                /*if (dfStepY != 0 && fabs(dfNewStepY - dfStepY) > 1e-8)
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Ungridded dataset: At line %d, Y spacing was %f, whereas it was %f before",
                             nLineNum, dfNewStepY, dfStepY);
                    VSIFCloseL(fp);
                    return NULL;
                }*/
                dfStepY = dfNewStepY;
            }
            else if (dfNewStepX != 0)
            {
                /*if (dfStepX != 0 && fabs(dfNewStepX - dfStepX) > 1e-8)
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "At line %d, X spacing was %f, whereas it was %f before",
                             nLineNum, dfNewStepX, dfStepX);
                    VSIFCloseL(fp);
                    return NULL;
                }*/
            }
        }
        dfLastX = dfX;
        dfLastY = dfY;
    }
    nYSize ++;

    if (dfStepX == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine X spacing");
        VSIFCloseL(fp);
        return NULL;
    }

    if (dfStepY == 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine Y spacing");
        VSIFCloseL(fp);
        return NULL;
    }

    double dfAdjustedStepY = ((dfStepY < 0) ? -1 : 1) * (dfMaxY - dfMinY) / (nYSize - 1);
    if (fabs(dfStepY - dfAdjustedStepY) > 1e-8)
    {
        CPLDebug("XYZ", "Adjusting stepy from %f to %f", dfStepY, dfAdjustedStepY);
    }
    dfStepY = dfAdjustedStepY;

    //CPLDebug("XYZ", "minx=%f maxx=%f stepx=%f", dfMinX, dfMaxX, dfStepX);
    //CPLDebug("XYZ", "miny=%f maxy=%f stepy=%f", dfMinY, dfMaxY, dfStepY);

    if (nDataLineNum != nXSize * nYSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Found %d lines. Expected %d",
                 nDataLineNum,nXSize * nYSize);
        VSIFCloseL(fp);
        return NULL;
    }
    
    if (poOpenInfo->eAccess == GA_Update)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The XYZ driver does not support update access to existing"
                  " datasets.\n" );
        VSIFCloseL(fp);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    XYZDataset         *poDS;

    poDS = new XYZDataset();
    poDS->fp = fp;
    poDS->bHasHeaderLine = bHasHeaderLine;
    poDS->nCommentLineCount = nCommentLineCount;
    poDS->nXIndex = nXIndex;
    poDS->nYIndex = nYIndex;
    poDS->nZIndex = nZIndex;
    poDS->nMinTokens = nMinTokens;
    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;
    poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2;
    poDS->adfGeoTransform[1] = dfStepX;
    poDS->adfGeoTransform[3] = (dfStepY < 0) ? dfMaxY - dfStepY / 2 :
                                               dfMinY - dfStepY / 2;
    poDS->adfGeoTransform[5] = dfStepY;

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

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    for( i = 0; i < poDS->nBands; i++ )
        poDS->SetBand( i+1, new XYZRasterBand( poDS, i+1, eDT ) );

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
Example #19
0
GDALDataset *SAGADataset::Create( const char * pszFilename,
				  int nXSize, int nYSize, int nBands,
				  GDALDataType eType,
				  char **papszParmList )

{
    if( nXSize <= 0 || nYSize <= 0 )
    {
        CPLError( CE_Failure, CPLE_IllegalArg,
                  "Unable to create grid, both X and Y size must be "
                  "non-negative.\n" );

        return NULL;
    }
    
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_IllegalArg,
                  "SAGA Binary Grid only supports 1 band" );
        return NULL;
    }

    if( eType != GDT_Byte && eType != GDT_UInt16 && eType != GDT_Int16
        && eType != GDT_UInt32 && eType != GDT_Int32 && eType != GDT_Float32
        && eType != GDT_Float64 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
		  "SAGA Binary Grid only supports Byte, UInt16, Int16, "
		  "UInt32, Int32, Float32 and Float64 datatypes.  Unable to "
		  "create with type %s.\n", GDALGetDataTypeName( eType ) );

        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }
    
    char abyNoData[8];
    double dfNoDataVal = 0.0;

    const char* pszNoDataValue = CSLFetchNameValue(papszParmList, "NODATA_VALUE");
    if (pszNoDataValue)
    {
        dfNoDataVal = CPLAtofM(pszNoDataValue);
    }
    else
    {
      switch (eType)	/* GDT_Byte, GDT_UInt16, GDT_Int16, GDT_UInt32  */
      {				/* GDT_Int32, GDT_Float32, GDT_Float64 */
        case (GDT_Byte):
        {
            dfNoDataVal = SG_NODATA_GDT_Byte;
            break;
        }
        case (GDT_UInt16):
        {
            dfNoDataVal = SG_NODATA_GDT_UInt16;
            break;
        }
        case (GDT_Int16):
        {
            dfNoDataVal = SG_NODATA_GDT_Int16;
            break;
        }
        case (GDT_UInt32):
        {
            dfNoDataVal = SG_NODATA_GDT_UInt32;
            break;
        }
        case (GDT_Int32):
        {
            dfNoDataVal = SG_NODATA_GDT_Int32;
            break;
        }
        default:
        case (GDT_Float32):
        {
            dfNoDataVal = SG_NODATA_GDT_Float32;
            break;
        }
        case (GDT_Float64):
        {
            dfNoDataVal = SG_NODATA_GDT_Float64;
            break;
        }
      }
    }

    GDALCopyWords(&dfNoDataVal, GDT_Float64, 0,
                  abyNoData, eType, 0, 1);

    CPLString osHdrFilename = CPLResetExtension( pszFilename, "sgrd" );
    CPLErr eErr = WriteHeader( osHdrFilename, eType,
                               nXSize, nYSize,
                               0.0, 0.0, 1.0,
                               dfNoDataVal, 1.0, false );

    if( eErr != CE_None )
    {
        VSIFCloseL( fp );
        return NULL;
    }

    if (CSLFetchBoolean( papszParmList , "FILL_NODATA", TRUE ))
    {
        int nDataTypeSize = GDALGetDataTypeSize(eType) / 8;
        GByte* pabyNoDataBuf = (GByte*) VSIMalloc2(nDataTypeSize, nXSize);
        if (pabyNoDataBuf == NULL)
        {
            VSIFCloseL( fp );
            return NULL;
        }
        
        for( int iCol = 0; iCol < nXSize; iCol++)
        {
            memcpy(pabyNoDataBuf + iCol * nDataTypeSize, abyNoData, nDataTypeSize);
        }

        for( int iRow = 0; iRow < nYSize; iRow++ )
        {
            if( VSIFWriteL( pabyNoDataBuf, nDataTypeSize, nXSize, fp ) != (unsigned)nXSize )
            {
                VSIFCloseL( fp );
                VSIFree(pabyNoDataBuf);
                CPLError( CE_Failure, CPLE_FileIO,
                          "Unable to write grid cell.  Disk full?\n" );
                return NULL;
            }
        }
        
        VSIFree(pabyNoDataBuf);
    }

    VSIFCloseL( fp );

    return (GDALDataset *)GDALOpen( pszFilename, GA_Update );
}
Example #20
0
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename,
                                     GDALDataset *poSrcDS, 
                                     int bStrict, char ** papszOptions, 
                                     GDALProgressFunc pfnProgress,
                                     void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support source dataset with zero band.\n");
        return NULL;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "HF2 driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get source dataset info                                         */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    double adfGeoTransform[6];
    poSrcDS->GetGeoTransform(adfGeoTransform);
    int bHasGeoTransform = !(adfGeoTransform[0] == 0 &&
                             adfGeoTransform[1] == 1 &&
                             adfGeoTransform[2] == 0 &&
                             adfGeoTransform[3] == 0 &&
                             adfGeoTransform[4] == 0 &&
                             adfGeoTransform[5] == 1);
    if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n");
        return NULL;
    }

    GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    GDALDataType eReqDT;
    float fVertPres = (float) 0.01;
    if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16)
    {
        fVertPres = 1;
        eReqDT = GDT_Int16;
    }
    else
        eReqDT = GDT_Float32;

/* -------------------------------------------------------------------- */
/*      Read creation options                                           */
/* -------------------------------------------------------------------- */
    const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS");
    int bCompress = FALSE;
    if (pszCompressed)
        bCompress = CSLTestBoolean(pszCompressed);
    
    const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION");
    if (pszVerticalPrecision)
    {
        fVertPres = (float) CPLAtofM(pszVerticalPrecision);
        if (fVertPres <= 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01");
            fVertPres = (float) 0.01;
        }
        if (eReqDT == GDT_Int16 && fVertPres > 1)
            eReqDT = GDT_Float32;
    }

    const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE");
    int nTileSize = 256;
    if (pszBlockSize)
    {
        nTileSize = atoi(pszBlockSize);
        if (nTileSize < 8 || nTileSize > 4096)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for BLOCKSIZE. Defaulting to 256");
            nTileSize = 256;
        }
    }

/* -------------------------------------------------------------------- */
/*      Parse source dataset georeferencing info                        */
/* -------------------------------------------------------------------- */

    int nExtendedHeaderLen = 0;
    if (bHasGeoTransform)
        nExtendedHeaderLen += 58;
    const char* pszProjectionRef = poSrcDS->GetProjectionRef();
    int nDatumCode = -2;
    int nUTMZone = 0;
    int bNorth = FALSE;
    int nEPSGCode = 0;
    int nExtentUnits = 1;
    if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0')
    {
        OGRSpatialReference oSRS;
        char* pszTemp = (char*) pszProjectionRef;
        if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE)
        {
            const char* pszValue = NULL;
            if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL
                && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") )
                nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" ));
            else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL)
            {
                if (strstr(pszValue, "WGS") && strstr(pszValue, "84"))
                    nDatumCode = 6326;
            }

            nUTMZone = oSRS.GetUTMZone(&bNorth);
        }
        if( oSRS.GetAuthorityName( "PROJCS" ) != NULL
            && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") )
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));

        if( oSRS.IsGeographic() )
        {
            nExtentUnits = 0;
        }
        else
        {
            double dfLinear = oSRS.GetLinearUnits();

            if( ABS(dfLinear - 0.3048) < 0.0000001 )
                nExtentUnits = 2;
            else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
                nExtentUnits = 3;
            else
                nExtentUnits = 1;
        }
    }
    if (nDatumCode != -2)
        nExtendedHeaderLen += 26;
    if (nUTMZone != 0)
        nExtendedHeaderLen += 26;
    if (nEPSGCode)
        nExtendedHeaderLen += 26;

/* -------------------------------------------------------------------- */
/*      Create target file                                              */
/* -------------------------------------------------------------------- */

    CPLString osFilename;
    if (bCompress)
    {
        osFilename = "/vsigzip/";
        osFilename += pszFilename;
    }
    else
        osFilename = pszFilename;
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Cannot create %s", pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write header                                                    */
/* -------------------------------------------------------------------- */

    VSIFWriteL("HF2\0", 4, 1, fp);
    WriteShort(fp, 0);
    WriteInt(fp, nXSize);
    WriteInt(fp, nYSize);
    WriteShort(fp, (GInt16) nTileSize);
    WriteFloat(fp, fVertPres);
    float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2);
    WriteFloat(fp, fHorizScale);
    WriteInt(fp, nExtendedHeaderLen);

/* -------------------------------------------------------------------- */
/*      Write extended header                                           */
/* -------------------------------------------------------------------- */

    char szBlockName[16 + 1];
    if (bHasGeoTransform)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-extents");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 34);
        WriteShort(fp, (GInt16) nExtentUnits);
        WriteDouble(fp, adfGeoTransform[0]);
        WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]);
        WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]);
        WriteDouble(fp, adfGeoTransform[3]);
    }
    if (nUTMZone != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-utm");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone));
    }
    if (nDatumCode != -2)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-datum");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nDatumCode);
    }
    if (nEPSGCode != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-epsg-prj");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nEPSGCode);
    }

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nTileSize - 1) / nTileSize;
    int nYBlocks = (nYSize + nTileSize - 1) / nTileSize;

    void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8));
    if (pTileBuffer == NULL)
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
        VSIFCloseL(fp);
        return NULL;
    }

    int i, j, k, l;
    CPLErr eErr = CE_None;
    for(j=0;j<nYBlocks && eErr == CE_None;j++)
    {
        for(i=0;i<nXBlocks && eErr == CE_None;i++)
        {
            int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize);
            int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize);
            eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read,
                                                i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize),
                                                nReqXSize, nReqYSize,
                                                pTileBuffer, nReqXSize, nReqYSize,
                                                eReqDT, 0, 0, NULL);
            if (eErr != CE_None)
                break;

            if (eReqDT == GDT_Int16)
            {
                WriteFloat(fp, 1); /* scale */
                WriteFloat(fp, 0); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }
            else
            {
                float fMinVal = ((float*)pTileBuffer)[0];
                float fMaxVal = fMinVal;
                for(k=1;k<nReqYSize*nReqXSize;k++)
                {
                    float fVal = ((float*)pTileBuffer)[k];
                    if (fVal < fMinVal) fMinVal = fVal;
                    if (fVal > fMaxVal) fMaxVal = fVal;
                }

                float fIntRange = (fMaxVal - fMinVal) / fVertPres;
                float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange;
                float fOffset = fMinVal;
                WriteFloat(fp, fScale); /* scale */
                WriteFloat(fp, fOffset); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    float fIntLastVal = (fLastVal - fOffset) / fScale;
                    CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f);
                    int nLastVal = (int)fIntLastVal;
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f);
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    fIntLastVal = (fLastVal - fOffset) / fScale;
                    nLastVal = (int)fIntLastVal;
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }

            if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) )
            {
                eErr = CE_Failure;
                break;
            }
        }
    }

    CPLFree(pTileBuffer);

    VSIFCloseL(fp);

    if (eErr != CE_None)
        return NULL;

    return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly);
}
Example #21
0
GDALDataset *SNODASDataset::Open( GDALOpenInfo * poOpenInfo )

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

    VSILFILE    *fp;

    fp = VSIFOpenL( poOpenInfo->pszFilename, "r" );

    if( fp == NULL )
    {
        return NULL;
    }

    const char *    pszLine;
    int             nRows = -1, nCols = -1;
    CPLString       osDataFilename;
    int             bIsInteger = FALSE, bIs2Bytes = FALSE;
    double          dfNoData = 0;
    int             bHasNoData = FALSE;
    double          dfMin = 0;
    int             bHasMin = FALSE;
    double          dfMax = 0;
    int             bHasMax = FALSE;
    double          dfMinX = 0.0, dfMinY = 0.0, dfMaxX = 0.0, dfMaxY = 0.0;
    int             bHasMinX = FALSE, bHasMinY = FALSE, bHasMaxX = FALSE, bHasMaxY = FALSE;
    int             bNotProjected = FALSE, bIsWGS84 = FALSE;
    CPLString       osDescription, osDataUnits;
    int             nStartYear = -1, nStartMonth = -1, nStartDay = -1,
                    nStartHour = -1, nStartMinute = -1, nStartSecond = -1;
    int             nStopYear = -1, nStopMonth = -1, nStopDay = -1,
                    nStopHour = -1, nStopMinute = -1, nStopSecond = -1;

    while( (pszLine = CPLReadLine2L( fp, 256, NULL )) != NULL )
    {
        char** papszTokens = CSLTokenizeStringComplex( pszLine, ":", TRUE, FALSE );
        if( CSLCount( papszTokens ) != 2 )
        {
            CSLDestroy( papszTokens );
            continue;
        }
        if( papszTokens[1][0] == ' ' )
            memmove(papszTokens[1], papszTokens[1] + 1, strlen(papszTokens[1] + 1) + 1);

        if( EQUAL(papszTokens[0],"Data file pathname") )
        {
            osDataFilename = papszTokens[1];
        }
        else if( EQUAL(papszTokens[0],"Description") )
        {
            osDescription = papszTokens[1];
        }
        else if( EQUAL(papszTokens[0],"Data units") )
        {
            osDataUnits= papszTokens[1];
        }

        else if( EQUAL(papszTokens[0],"Start year") )
            nStartYear = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Start month") )
            nStartMonth = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Start day") )
            nStartDay = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Start hour") )
            nStartHour = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Start minute") )
            nStartMinute = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Start second") )
            nStartSecond = atoi(papszTokens[1]);

        else if( EQUAL(papszTokens[0],"Stop year") )
            nStopYear = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Stop month") )
            nStopMonth = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Stop day") )
            nStopDay = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Stop hour") )
            nStopHour = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Stop minute") )
            nStopMinute = atoi(papszTokens[1]);
        else if( EQUAL(papszTokens[0],"Stop second") )
            nStopSecond = atoi(papszTokens[1]);

        else if( EQUAL(papszTokens[0],"Number of columns") )
        {
            nCols = atoi(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Number of rows") )
        {
            nRows = atoi(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Data type"))
        {
            bIsInteger = EQUAL(papszTokens[1],"integer");
        }
        else if( EQUAL(papszTokens[0],"Data bytes per pixel"))
        {
            bIs2Bytes = EQUAL(papszTokens[1],"2");
        }
        else if( EQUAL(papszTokens[0],"Projected"))
        {
            bNotProjected = EQUAL(papszTokens[1],"no");
        }
        else if( EQUAL(papszTokens[0],"Horizontal datum"))
        {
            bIsWGS84 = EQUAL(papszTokens[1],"WGS84");
        }
        else if( EQUAL(papszTokens[0],"No data value"))
        {
            bHasNoData = TRUE;
            dfNoData = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Minimum data value"))
        {
            bHasMin = TRUE;
            dfMin = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Maximum data value"))
        {
            bHasMax = TRUE;
            dfMax = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Minimum x-axis coordinate") )
        {
            bHasMinX = TRUE;
            dfMinX = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Minimum y-axis coordinate") )
        {
            bHasMinY = TRUE;
            dfMinY = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Maximum x-axis coordinate") )
        {
            bHasMaxX = TRUE;
            dfMaxX = CPLAtofM(papszTokens[1]);
        }
        else if( EQUAL(papszTokens[0],"Maximum y-axis coordinate") )
        {
            bHasMaxY = TRUE;
            dfMaxY = CPLAtofM(papszTokens[1]);
        }

        CSLDestroy( papszTokens );
    }

    VSIFCloseL( fp );

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows == -1 || nCols == -1 || !bIsInteger || !bIs2Bytes )
        return NULL;

    if( !bNotProjected || !bIsWGS84 )
        return NULL;

    if( osDataFilename.size() == 0 )
        return NULL;

    if (!GDALCheckDatasetDimensions(nCols, nRows))
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    const char* pszPath = CPLGetPath(poOpenInfo->pszFilename);
    osDataFilename = CPLFormFilename(pszPath, osDataFilename, NULL);

    VSILFILE* fpRaw = VSIFOpenL( osDataFilename, "rb" );

    if( fpRaw == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    SNODASDataset     *poDS;

    poDS = new SNODASDataset();

    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->osDataFilename = osDataFilename;
    poDS->bHasNoData = bHasNoData;
    poDS->dfNoData = dfNoData;
    poDS->bHasMin = bHasMin;
    poDS->dfMin = dfMin;
    poDS->bHasMax = bHasMax;
    poDS->dfMax = dfMax;
    if (bHasMinX && bHasMinY && bHasMaxX && bHasMaxY)
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfMinX;
        poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nCols;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfMaxY;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = - (dfMaxY - dfMinY) / nRows;
    }

    if (osDescription.size())
        poDS->SetMetadataItem("Description", osDescription);
    if (osDataUnits.size())
        poDS->SetMetadataItem("Data_Units", osDataUnits);
    if (nStartYear != -1 && nStartMonth != -1 && nStartDay != -1 &&
        nStartHour != -1 && nStartMinute != -1 && nStartSecond != -1)
        poDS->SetMetadataItem("Start_Date",
                              CPLSPrintf("%04d/%02d/%02d %02d:%02d:%02d",
                                        nStartYear, nStartMonth, nStartDay,
                                        nStartHour, nStartMinute, nStartSecond));
    if (nStopYear != -1 && nStopMonth != -1 && nStopDay != -1 &&
        nStopHour != -1 && nStopMinute != -1 && nStopSecond != -1)
        poDS->SetMetadataItem("Stop_Date",
                              CPLSPrintf("%04d/%02d/%02d %02d:%02d:%02d",
                                        nStopYear, nStopMonth, nStopDay,
                                        nStopHour, nStopMinute, nStopSecond));

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->SetBand( 1, new SNODASRasterBand( fpRaw, nCols, nRows) );

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
   
    return( poDS );
}
Example #22
0
GDALDataset *ZMapDataset::Open( GDALOpenInfo * poOpenInfo )

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

/* -------------------------------------------------------------------- */
/*      Find dataset characteristics                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (fp == NULL)
        return NULL;

    const char* pszLine;

    while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL)
    {
        if (*pszLine == '!')
        {
            continue;
        }
        else
            break;
    }
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    /* Parse first header line */
    char** papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 3)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nValuesPerLine = atoi(papszTokens[2]);
    if (nValuesPerLine <= 0)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    /* Parse second header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 5)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nFieldSize = atoi(papszTokens[0]);
    double dfNoDataValue = CPLAtofM(papszTokens[1]);
    int nDecimalCount = atoi(papszTokens[3]);
    int nColumnNumber = atoi(papszTokens[4]);

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    if (nFieldSize <= 0 || nFieldSize >= 40 ||
        nDecimalCount <= 0 || nDecimalCount >= nFieldSize ||
        nColumnNumber != 1)
    {
        CPLDebug("ZMap", "nFieldSize=%d, nDecimalCount=%d, nColumnNumber=%d",
                 nFieldSize, nDecimalCount, nColumnNumber);
        VSIFCloseL(fp);
        return NULL;
    }

    /* Parse third header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    papszTokens = CSLTokenizeString2( pszLine, ",", 0 );
    if (CSLCount(papszTokens) != 6)
    {
        CSLDestroy(papszTokens);
        VSIFCloseL(fp);
        return NULL;
    }

    int nRows = atoi(papszTokens[0]);
    int nCols = atoi(papszTokens[1]);
    double dfMinX = CPLAtofM(papszTokens[2]);
    double dfMaxX = CPLAtofM(papszTokens[3]);
    double dfMinY = CPLAtofM(papszTokens[4]);
    double dfMaxY = CPLAtofM(papszTokens[5]);

    CSLDestroy(papszTokens);
    papszTokens = NULL;

    if (!GDALCheckDatasetDimensions(nCols, nRows) ||
        nCols == 1 || nRows == 1)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    
    /* Ignore fourth header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    /* Check fifth header line */
    pszLine = CPLReadLine2L(fp, 100, NULL);
    if (pszLine == NULL || pszLine[0] != '@')
    {
        VSIFCloseL(fp);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ZMapDataset         *poDS;

    poDS = new ZMapDataset();
    poDS->fp = fp;
    poDS->nDataStartOff = VSIFTellL(fp);
    poDS->nValuesPerLine = nValuesPerLine;
    poDS->nFieldSize = nFieldSize;
    poDS->nDecimalCount = nDecimalCount;
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->dfNoDataValue = dfNoDataValue;

    if (CSLTestBoolean(CPLGetConfigOption("ZMAP_PIXEL_IS_POINT", "FALSE")))
    {
        double dfStepX = (dfMaxX - dfMinX) / (nCols - 1);
        double dfStepY = (dfMaxY - dfMinY) / (nRows - 1);

        poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2;
        poDS->adfGeoTransform[1] = dfStepX;
        poDS->adfGeoTransform[3] = dfMaxY + dfStepY / 2;
        poDS->adfGeoTransform[5] = -dfStepY;
    }
    else
    {
        double dfStepX = (dfMaxX - dfMinX) / nCols ;
        double dfStepY = (dfMaxY - dfMinY) / nRows;

        poDS->adfGeoTransform[0] = dfMinX;
        poDS->adfGeoTransform[1] = dfStepX;
        poDS->adfGeoTransform[3] = dfMaxY;
        poDS->adfGeoTransform[5] = -dfStepY;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    poDS->SetBand( 1, new ZMapRasterBand( poDS ) );

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
Example #23
0
CPLErr ParseAlgorithmAndOptions(const char *pszAlgoritm,
                                GDALGridAlgorithm *peAlgorithm,
                                void **ppOptions)
{
    char **papszParms = CSLTokenizeString2(pszAlgoritm, ":", FALSE);

    if (CSLCount(papszParms) < 1)
        return CE_Failure;

    if (EQUAL(papszParms[0], szAlgNameInvDist))
        *peAlgorithm = GGA_InverseDistanceToAPower;
    else if (EQUAL(papszParms[0], szAlgNameAverage))
        *peAlgorithm = GGA_MovingAverage;
    else if (EQUAL(papszParms[0], szAlgNameNearest))
        *peAlgorithm = GGA_NearestNeighbor;
    else if (EQUAL(papszParms[0], szAlgNameMinimum))
        *peAlgorithm = GGA_MetricMinimum;
    else if (EQUAL(papszParms[0], szAlgNameMaximum))
        *peAlgorithm = GGA_MetricMaximum;
    else if (EQUAL(papszParms[0], szAlgNameRange))
        *peAlgorithm = GGA_MetricRange;
    else if (EQUAL(papszParms[0], szAlgNameCount))
        *peAlgorithm = GGA_MetricCount;
    else if (EQUAL(papszParms[0], szAlgNameAverageDistance))
        *peAlgorithm = GGA_MetricAverageDistance;
    else if (EQUAL(papszParms[0], szAlgNameAverageDistancePts))
        *peAlgorithm = GGA_MetricAverageDistancePts;
    else
    {
        fprintf(stderr, "Unsupported gridding method \"%s\".\n",
                papszParms[0]);
        CSLDestroy(papszParms);
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Parse algorithm parameters and assign defaults.                 */
/* -------------------------------------------------------------------- */
    const char *pszValue;

    switch (*peAlgorithm)
    {
    case GGA_InverseDistanceToAPower:
    default:
        *ppOptions =
            CPLMalloc(sizeof(GDALGridInverseDistanceToAPowerOptions));

        pszValue = CSLFetchNameValue(papszParms, "power");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfPower = (pszValue) ? CPLAtofM(pszValue) : 2.0;

        pszValue = CSLFetchNameValue(papszParms, "smoothing");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfSmoothing = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "radius1");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "radius2");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "angle");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "max_points");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        nMaxPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0);

        pszValue = CSLFetchNameValue(papszParms, "min_points");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        nMinPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0);

        pszValue = CSLFetchNameValue(papszParms, "nodata");
        ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)->
        dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0;
        break;

    case GGA_MovingAverage:
        *ppOptions =
            CPLMalloc(sizeof(GDALGridMovingAverageOptions));

        pszValue = CSLFetchNameValue(papszParms, "radius1");
        ((GDALGridMovingAverageOptions*)*ppOptions)->
        dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "radius2");
        ((GDALGridMovingAverageOptions*)*ppOptions)->
        dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "angle");
        ((GDALGridMovingAverageOptions*)*ppOptions)->
        dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "min_points");
        ((GDALGridMovingAverageOptions*)*ppOptions)->
        nMinPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0);

        pszValue = CSLFetchNameValue(papszParms, "nodata");
        ((GDALGridMovingAverageOptions*)*ppOptions)->
        dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0;
        break;

    case GGA_NearestNeighbor:
        *ppOptions =
            CPLMalloc(sizeof(GDALGridNearestNeighborOptions));

        pszValue = CSLFetchNameValue(papszParms, "radius1");
        ((GDALGridNearestNeighborOptions*)*ppOptions)->
        dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "radius2");
        ((GDALGridNearestNeighborOptions*)*ppOptions)->
        dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "angle");
        ((GDALGridNearestNeighborOptions*)*ppOptions)->
        dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "nodata");
        ((GDALGridNearestNeighborOptions*)*ppOptions)->
        dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0;
        break;

    case GGA_MetricMinimum:
    case GGA_MetricMaximum:
    case GGA_MetricRange:
    case GGA_MetricCount:
    case GGA_MetricAverageDistance:
    case GGA_MetricAverageDistancePts:
        *ppOptions =
            CPLMalloc(sizeof(GDALGridDataMetricsOptions));

        pszValue = CSLFetchNameValue(papszParms, "radius1");
        ((GDALGridDataMetricsOptions*)*ppOptions)->
        dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "radius2");
        ((GDALGridDataMetricsOptions*)*ppOptions)->
        dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "angle");
        ((GDALGridDataMetricsOptions*)*ppOptions)->
        dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0;

        pszValue = CSLFetchNameValue(papszParms, "min_points");
        ((GDALGridDataMetricsOptions*)*ppOptions)->
        nMinPoints = (pszValue) ? atol(pszValue) : 0;

        pszValue = CSLFetchNameValue(papszParms, "nodata");
        ((GDALGridDataMetricsOptions*)*ppOptions)->
        dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0;
        break;
    }

    CSLDestroy(papszParms);
    return CE_None;
}
Example #24
0
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree,
                                   const char * /* pszUnused */ )
{
    PamInitialize();

/* -------------------------------------------------------------------- */
/*      Apply any dataset level metadata.                               */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    GDALMajorObject::SetDescription(
        CPLGetXMLValue( psTree, "Description", "" ) );

    if( CPLGetXMLValue( psTree, "NoDataValue", nullptr ) != nullptr )
    {
        const char *pszLEHex =
            CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", nullptr );
        if( pszLEHex != nullptr )
        {
            int nBytes;
            GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes );
            if( nBytes == 8 )
            {
                CPL_LSBPTR64( pabyBin );

                GDALPamRasterBand::SetNoDataValue( *reinterpret_cast<const double*>(pabyBin) );
            }
            else
            {
                GDALPamRasterBand::SetNoDataValue(
                    CPLAtof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
            }
            CPLFree( pabyBin );
        }
        else
        {
            GDALPamRasterBand::SetNoDataValue(
                CPLAtof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
        }
    }

    GDALPamRasterBand::SetOffset(
        CPLAtof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    GDALPamRasterBand::SetScale(
        CPLAtof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", nullptr));

    if( CPLGetXMLValue( psTree, "ColorInterp", nullptr ) != nullptr )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", nullptr );
        GDALPamRasterBand::SetColorInterpretation(
            GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != nullptr )
    {
        CPLStringList oCategoryNames;

        for( CPLXMLNode *psEntry =
                 CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != nullptr;
             psEntry = psEntry->psNext )
        {
            /* Don't skeep <Category> tag with empty content */
            if( psEntry->eType != CXT_Element
                || !EQUAL(psEntry->pszValue,"Category")
                || (psEntry->psChild != nullptr &&
                    psEntry->psChild->eType != CXT_Text) )
                continue;

            oCategoryNames.AddString(
                psEntry->psChild ? psEntry->psChild->pszValue : "" );
        }

        GDALPamRasterBand::SetCategoryNames( oCategoryNames.List() );
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != nullptr )
    {
        GDALColorTable oTable;
        int iEntry = 0;

        for( CPLXMLNode *psEntry =
                 CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != nullptr;
             psEntry = psEntry->psNext )
        {
            if( !(psEntry->eType == CXT_Element &&
                  EQUAL(psEntry->pszValue, "Entry")) )
            {
                continue;
            }

            GDALColorEntry sCEntry = {
                static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c1", "0" ))),
                static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c2", "0" ))),
                static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c3", "0" ))),
                static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c4", "255" )))
            };

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }

        GDALPamRasterBand::SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a complete set of stats?                             */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "Minimum" ) != nullptr
        && CPLGetXMLNode( psTree, "Maximum" ) != nullptr )
    {
        psPam->bHaveMinMax = TRUE;
        psPam->dfMin = CPLAtofM(CPLGetXMLValue(psTree, "Minimum","0"));
        psPam->dfMax = CPLAtofM(CPLGetXMLValue(psTree, "Maximum","0"));
    }

    if( CPLGetXMLNode( psTree, "Mean" ) != nullptr
        && CPLGetXMLNode( psTree, "StandardDeviation" ) != nullptr )
    {
        psPam->bHaveStats = TRUE;
        psPam->dfMean = CPLAtofM(CPLGetXMLValue(psTree, "Mean","0"));
        psPam->dfStdDev =
            CPLAtofM(CPLGetXMLValue(psTree, "StandardDeviation", "0"));
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != nullptr )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = nullptr;

        if( psPam->psSavedHistograms != nullptr )
        {
            CPLDestroyXMLNode (psPam->psSavedHistograms );
            psPam->psSavedHistograms = nullptr;
        }
        psPam->psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* -------------------------------------------------------------------- */
/*      Raster Attribute Table                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" );
    if( psRAT != nullptr )
    {
        if( psPam->poDefaultRAT != nullptr )
        {
            delete psPam->poDefaultRAT;
            psPam->poDefaultRAT = nullptr;
        }
        psPam->poDefaultRAT = new GDALDefaultRasterAttributeTable();
        psPam->poDefaultRAT->XMLInit( psRAT, "" );
    }

    return CE_None;
}
Example #25
0
int main( int nArgc, char ** papszArgv )
{
    // register drivers
    GDALAllRegister();

    if( nArgc < 2 )
        return EXIT_FAILURE;

    double dfaCornersX[5] = {0};
    double dfaCornersY[5] = {0};
    CPLString sFileName;

    // parse input values
    for( int iArg = 1; iArg < nArgc; iArg++ )
    {
        if( EQUAL(papszArgv[iArg],"-nw"))
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            const char* pszCoord = papszArgv[++iArg];
            dfaCornersY[1] = CPLAtofM(pszCoord);
            pszCoord = papszArgv[++iArg];
            dfaCornersX[1] = CPLAtofM(pszCoord);
        }
        else if( EQUAL(papszArgv[iArg],"-ne"))
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            const char* pszCoord = papszArgv[++iArg];
            dfaCornersY[2] = CPLAtofM(pszCoord);
            pszCoord = papszArgv[++iArg];
            dfaCornersX[2] = CPLAtofM(pszCoord);
        }
        else if( EQUAL(papszArgv[iArg],"-se"))
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            const char* pszCoord = papszArgv[++iArg];
            dfaCornersY[3] = CPLAtofM(pszCoord);
            pszCoord = papszArgv[++iArg];
            dfaCornersX[3] = CPLAtofM(pszCoord);
        }
        else if( EQUAL(papszArgv[iArg],"-sw"))
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            const char* pszCoord = papszArgv[++iArg];
            dfaCornersY[4] = CPLAtofM(pszCoord);
            pszCoord = papszArgv[++iArg];
            dfaCornersX[4] = CPLAtofM(pszCoord);
        }
        else if( EQUAL(papszArgv[iArg],"-c"))
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            const char* pszCoord = papszArgv[++iArg];
            dfaCornersY[0] = CPLAtofM(pszCoord);
            pszCoord = papszArgv[++iArg];
            dfaCornersX[0] = CPLAtofM(pszCoord);
        }
        else if(sFileName.empty())
            sFileName = papszArgv[iArg];
    }

    OGRSpatialReference oOGRSpatialReference(SRS_WKT_WGS84);
    int nZoneNo = ceil( (180.0 + dfaCornersX[0]) / 6.0 );
    OGRSpatialReference oDstSpatialReference(SRS_WKT_WGS84);
    oDstSpatialReference.SetUTM(nZoneNo, dfaCornersY[0] > 0);

    // transform coordinates from WGS84 to UTM
    OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( &oOGRSpatialReference, &oDstSpatialReference);
    if(!poCT)
    {
        Usage("get coordinate transformation failed");
        return EXIT_FAILURE;
    }

    int nResult = poCT->Transform(5, dfaCornersX, dfaCornersY, NULL);
    if(!nResult)
    {
        Usage("transformation failed");
        return EXIT_FAILURE;
    }

    // open input dataset
    GDALDataset *poSrcDataset = (GDALDataset *) GDALOpen( sFileName, GA_ReadOnly ); // GA_Update
    char* pszSpaRefDef = NULL;
    if( oDstSpatialReference.exportToWkt(&pszSpaRefDef) != OGRERR_NONE)
    {
        CPLFree( pszSpaRefDef );
        GDALClose( (GDALDatasetH) poSrcDataset );
        return EXIT_FAILURE;
    }

    // search point along image
    // add GCP to opened raster
    OGRPoint ptCenter(dfaCornersX[0], dfaCornersY[0]);
    OGRPoint pt1(dfaCornersX[1], dfaCornersY[1]); // NW Cormer
    OGRPoint pt2(dfaCornersX[2], dfaCornersY[2]); // NE Corner
    OGRPoint pt3(dfaCornersX[3], dfaCornersY[3]); // SE Corner
    OGRPoint pt4(dfaCornersX[4], dfaCornersY[4]); // SW Corner
    int nGCPCount = 0;
    OGREnvelope DstEnv;
    GDAL_GCP *paGSPs = PrepareGCP(sFileName, &pt1, &pt2, &pt3, &pt4, &ptCenter, oDstSpatialReference, poSrcDataset->GetRasterXSize(), poSrcDataset->GetRasterYSize(), nGCPCount, DstEnv);

    if(poSrcDataset->SetGCPs(nGCPCount, paGSPs, pszSpaRefDef) != CE_None)
    {
        Usage( "Set GCPs failed" );
        return EXIT_FAILURE;
    }

    // create warper
    char **papszTO = NULL;
    papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" );
    papszTO = CSLSetNameValue( papszTO, "NUM_THREADS", "4" );
    papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSpaRefDef );
    papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSpaRefDef );
    papszTO = CSLSetNameValue( papszTO, "INSERT_CENTER_LONG", "FALSE" );

    GDALDriver *poOutputDriver = (GDALDriver *) GDALGetDriverByName( "GTiff" );
    CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" );
    void* hTransformArg = GDALCreateGenImgProjTransformer2( poSrcDataset, NULL, papszTO );
    GDALTransformerInfo* psInfo = (GDALTransformerInfo*)hTransformArg;

    double adfThisGeoTransform[6];
    double adfExtent[4];
    int nThisPixels, nThisLines;

    // suggest the raster output size
    if( GDALSuggestedWarpOutput2( poSrcDataset, psInfo->pfnTransform, hTransformArg, adfThisGeoTransform, &nThisPixels, &nThisLines, adfExtent, 0 ) != CE_None )
    {
        Usage( "Suggest Output failed" );
        return EXIT_FAILURE;
    }

    adfThisGeoTransform[0] = DstEnv.MinX;
    adfThisGeoTransform[3] = DstEnv.MaxY;

    int nPixels = (int) ((DstEnv.MaxX - DstEnv.MinX) / adfThisGeoTransform[1] + 0.5);
    int nLines = (int) ((DstEnv.MaxY - DstEnv.MinY) / -adfThisGeoTransform[5] + 0.5);

    GDALSetGenImgProjTransformerDstGeoTransform( hTransformArg, adfThisGeoTransform);

    // create new raster
    CPLString sOutputRasterPath = CPLResetExtension(sFileName, "tif");
    GDALDataset  *poDstDataset = poOutputDriver->Create(sOutputRasterPath, nPixels, nLines, poSrcDataset->GetRasterCount(), GDT_Byte, NULL );
    if( NULL == poDstDataset )
    {
        Usage( "Create Output failed" );
        return EXIT_FAILURE;
    }
    poDstDataset->SetProjection( pszSpaRefDef );
    poDstDataset->SetGeoTransform( adfThisGeoTransform );

#ifdef APRROX_MAXERROR
    hTransformArg = GDALCreateApproxTransformer( GDALGenImgProjTransform,  hTransformArg, APRROX_MAXERROR);
    GDALTransformerFunc pfnTransformer = GDALApproxTransform;
    GDALApproxTransformerOwnsSubtransformer(hTransformArg, TRUE);
#else
    GDALTransformerFunc pfnTransformer = GDALGenImgProjTransform;
#endif // APRROX_MAXERROR

    // warp
    GDALWarpOptions *psWO = GDALCreateWarpOptions();

    psWO->eWorkingDataType = GDT_Byte;
    psWO->eResampleAlg = GRA_NearestNeighbour;

    psWO->hSrcDS = poSrcDataset;
    psWO->hDstDS = poDstDataset;

    psWO->pfnTransformer = pfnTransformer;
    psWO->pTransformerArg = hTransformArg;

    psWO->pfnProgress = GDALTermProgress;
    psWO->nBandCount = poSrcDataset->GetRasterCount();

    psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
    psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));

    for(int i = 0; i < psWO->nBandCount; ++i )
    {
        psWO->panSrcBands[i] = i+1;
        psWO->panDstBands[i] = i+1;
    }

    GDALWarpOperation oWO;
    if( oWO.Initialize( psWO ) == CE_None )
    {
#ifdef MULTI
        if( oWO.ChunkAndWarpMulti( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None)
#else //MULTI
        if( oWO.ChunkAndWarpImage( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None)
#endif //MULTI
        {
            const char* err = CPLGetLastErrorMsg();
            Usage( CPLSPrintf("Warp failed.%s", err) );
            return EXIT_FAILURE;
        }
    }

    // cleanup
    GDALDestroyWarpOptions( psWO );
    CSLDestroy( papszTO );

    CPLFree( pszSpaRefDef );
    GDALClose( (GDALDatasetH) poSrcDataset );
    GDALClose( (GDALDatasetH) poDstDataset );

    GDALDestroyDriverManager();

    return EXIT_SUCCESS;
}
Example #26
0
GDALDataset *ERSDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      We assume the user selects the .ers file.                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes > 15
        && EQUALN((const char *) poOpenInfo->pabyHeader,"Algorithm Begin",15) )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s appears to be an algorithm ERS file, which is not currently supported.", 
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      We assume the user selects the .ers file.                       */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 15 
        || !EQUALN((const char *) poOpenInfo->pabyHeader,"DatasetHeader ",14) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the .ers file, and read the first line.                    */
/* -------------------------------------------------------------------- */
    VSILFILE *fpERS = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    
    if( fpERS == NULL )
        return NULL;

    CPLReadLineL( fpERS );

/* -------------------------------------------------------------------- */
/*      Now ingest the rest of the file as a tree of header nodes.      */
/* -------------------------------------------------------------------- */
    ERSHdrNode *poHeader = new ERSHdrNode();

    if( !poHeader->ParseChildren( fpERS ) )
    {
        delete poHeader;
        VSIFCloseL( fpERS );
        return NULL;
    }

    VSIFCloseL( fpERS );

/* -------------------------------------------------------------------- */
/*      Do we have the minimum required information from this header?   */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.NrOfLines" ) == NULL 
        || poHeader->Find( "RasterInfo.NrOfCellsPerLine" ) == NULL 
        || poHeader->Find( "RasterInfo.NrOfBands" ) == NULL )
    {
        if( poHeader->FindNode( "Algorithm" ) != NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "%s appears to be an algorithm ERS file, which is not currently supported.", 
                      poOpenInfo->pszFilename );
        }
        delete poHeader;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ERSDataset     *poDS;

    poDS = new ERSDataset();
    poDS->poHeader = poHeader;
    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    int nBands = atoi(poHeader->Find( "RasterInfo.NrOfBands" ));
    poDS->nRasterXSize = atoi(poHeader->Find( "RasterInfo.NrOfCellsPerLine" ));
    poDS->nRasterYSize = atoi(poHeader->Find( "RasterInfo.NrOfLines" ));
    
    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBands, FALSE))
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*     Get the HeaderOffset if it exists in the header                  */
/* -------------------------------------------------------------------- */
    GIntBig nHeaderOffset = 0;
    if( poHeader->Find( "HeaderOffset" ) != NULL )
    {
        nHeaderOffset = atoi(poHeader->Find( "HeaderOffset" ));
    }

/* -------------------------------------------------------------------- */
/*      Establish the data type.                                        */
/* -------------------------------------------------------------------- */
    GDALDataType eType;
    CPLString osCellType = poHeader->Find( "RasterInfo.CellType", 
                                           "Unsigned8BitInteger" );
    if( EQUAL(osCellType,"Unsigned8BitInteger") )
        eType = GDT_Byte;
    else if( EQUAL(osCellType,"Signed8BitInteger") )
        eType = GDT_Byte;
    else if( EQUAL(osCellType,"Unsigned16BitInteger") )
        eType = GDT_UInt16;
    else if( EQUAL(osCellType,"Signed16BitInteger") )
        eType = GDT_Int16;
    else if( EQUAL(osCellType,"Unsigned32BitInteger") )
        eType = GDT_UInt32;
    else if( EQUAL(osCellType,"Signed32BitInteger") )
        eType = GDT_Int32;
    else if( EQUAL(osCellType,"IEEE4ByteReal") )
        eType = GDT_Float32;
    else if( EQUAL(osCellType,"IEEE8ByteReal") )
        eType = GDT_Float64;
    else
    {
        CPLDebug( "ERS", "Unknown CellType '%s'", osCellType.c_str() );
        eType = GDT_Byte;
    }

/* -------------------------------------------------------------------- */
/*      Pick up the word order.                                         */
/* -------------------------------------------------------------------- */
    int bNative;

#ifdef CPL_LSB
    bNative = EQUAL(poHeader->Find( "ByteOrder", "LSBFirst" ),
                    "LSBFirst");
#else
    bNative = EQUAL(poHeader->Find( "ByteOrder", "MSBFirst" ),
                    "MSBFirst");
#endif

/* -------------------------------------------------------------------- */
/*      Figure out the name of the target file.                         */
/* -------------------------------------------------------------------- */
    CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
    CPLString osDataFile = poHeader->Find( "DataFile", "" );
    CPLString osDataFilePath;

    if( osDataFile.length() == 0 ) // just strip off extension.
    {
        osDataFile = CPLGetFilename( poOpenInfo->pszFilename );
        osDataFile = osDataFile.substr( 0, osDataFile.find_last_of('.') );
    }
        
    osDataFilePath = CPLFormFilename( osPath, osDataFile, NULL );

/* -------------------------------------------------------------------- */
/*      DataSetType = Translated files are links to things like ecw     */
/*      files.                                                          */
/* -------------------------------------------------------------------- */
    if( EQUAL(poHeader->Find("DataSetType",""),"Translated") )
    {
        poDS->poDepFile = (GDALDataset *) 
            GDALOpenShared( osDataFilePath, poOpenInfo->eAccess );

        if( poDS->poDepFile != NULL 
            && poDS->poDepFile->GetRasterCount() >= nBands )
        {
            int iBand;

            for( iBand = 0; iBand < nBands; iBand++ )
            {
                // Assume pixel interleaved.
                poDS->SetBand( iBand+1, 
                               poDS->poDepFile->GetRasterBand( iBand+1 ) );
            }
        }
    }

/* ==================================================================== */
/*      While ERStorage indicates a raw file.                           */
/* ==================================================================== */
    else if( EQUAL(poHeader->Find("DataSetType",""),"ERStorage") )
    {
        // Open data file.
        if( poOpenInfo->eAccess == GA_Update )
            poDS->fpImage = VSIFOpenL( osDataFilePath, "r+" );
        else
            poDS->fpImage = VSIFOpenL( osDataFilePath, "r" );

        poDS->osRawFilename = osDataFilePath;

        if( poDS->fpImage != NULL )
        {
            int iWordSize = GDALGetDataTypeSize(eType) / 8;
            int iBand;

            for( iBand = 0; iBand < nBands; iBand++ )
            {
                // Assume pixel interleaved.
                poDS->SetBand( 
                    iBand+1, 
                    new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                       nHeaderOffset 
                                       + iWordSize * iBand * poDS->nRasterXSize,
                                       iWordSize,
                                       iWordSize * nBands * poDS->nRasterXSize,
                                       eType, bNative, TRUE ));
                if( EQUAL(osCellType,"Signed8BitInteger") )
                    poDS->GetRasterBand(iBand+1)->
                        SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", 
                                         "IMAGE_STRUCTURE" );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Otherwise we have an error!                                     */
/* -------------------------------------------------------------------- */
    if( poDS->nBands == 0 )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Look for band descriptions.                                     */
/* -------------------------------------------------------------------- */
    int iChild, iBand = 0;
    ERSHdrNode *poRI = poHeader->FindNode( "RasterInfo" );

    for( iChild = 0; 
         poRI != NULL && iChild < poRI->nItemCount && iBand < poDS->nBands; 
         iChild++ )
    {
        if( poRI->papoItemChild[iChild] != NULL
            && EQUAL(poRI->papszItemName[iChild],"BandId") )
        {
            const char *pszValue = 
                poRI->papoItemChild[iChild]->Find( "Value", NULL );

            iBand++;
            if( pszValue )
            {
                CPLPushErrorHandler( CPLQuietErrorHandler );
                poDS->GetRasterBand( iBand )->SetDescription( pszValue );
                CPLPopErrorHandler();
            }

            pszValue = poRI->papoItemChild[iChild]->Find( "Units", NULL );
            if ( pszValue )
            {
                CPLPushErrorHandler( CPLQuietErrorHandler );
                poDS->GetRasterBand( iBand )->SetUnitType( pszValue );
                CPLPopErrorHandler();
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Look for projection.                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;

    CPLString osProjection = poHeader->Find( "CoordinateSpace.Projection", 
                                             "RAW" );
    CPLString osDatum = poHeader->Find( "CoordinateSpace.Datum", "WGS84" );
    CPLString osUnits = poHeader->Find( "CoordinateSpace.Units", "METERS" );

    oSRS.importFromERM( osProjection, osDatum, osUnits );

    CPLFree( poDS->pszProjection );
    oSRS.exportToWkt( &(poDS->pszProjection) );

/* -------------------------------------------------------------------- */
/*      Look for the geotransform.                                      */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", NULL )
        && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = CPLAtof( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", "" ));
        poDS->adfGeoTransform[1] = CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" ));
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = CPLAtof( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Northings", "" ));
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" ));
    }
    else if( poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", NULL )
             && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = ERSDMS2Dec( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Longitude", "" ));
        poDS->adfGeoTransform[1] = CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" ));
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = ERSDMS2Dec( 
            poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", "" ));
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -CPLAtof( 
            poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" ));
    }

/* -------------------------------------------------------------------- */
/*      Adjust if we have a registration cell.                          */
/* -------------------------------------------------------------------- */
    int iCellX = atoi(poHeader->Find("RasterInfo.RegistrationCellX", "1"));
    int iCellY = atoi(poHeader->Find("RasterInfo.RegistrationCellY", "1"));

    if( poDS->bGotTransform )
    {
        poDS->adfGeoTransform[0] -=
            (iCellX-1) * poDS->adfGeoTransform[1]
            + (iCellY-1) * poDS->adfGeoTransform[2];
        poDS->adfGeoTransform[3] -= 
            (iCellX-1) * poDS->adfGeoTransform[4]
            + (iCellY-1) * poDS->adfGeoTransform[5];
    }

/* -------------------------------------------------------------------- */
/*      Check for null values.                                          */
/* -------------------------------------------------------------------- */
    if( poHeader->Find( "RasterInfo.NullCellValue", NULL ) )
    {
        CPLPushErrorHandler( CPLQuietErrorHandler );

        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
            poDS->GetRasterBand(iBand)->SetNoDataValue(
                CPLAtofM(poHeader->Find( "RasterInfo.NullCellValue" )) );
        
        CPLPopErrorHandler();
    }

/* -------------------------------------------------------------------- */
/*      Do we have an "All" region?                                     */
/* -------------------------------------------------------------------- */
    ERSHdrNode *poAll = NULL;

    for( iChild = 0; 
         poRI != NULL && iChild < poRI->nItemCount; 
         iChild++ )
    {
        if( poRI->papoItemChild[iChild] != NULL
            && EQUAL(poRI->papszItemName[iChild],"RegionInfo") )
        {
            if( EQUAL(poRI->papoItemChild[iChild]->Find("RegionName",""), 
                      "All") )
                poAll = poRI->papoItemChild[iChild];
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have statistics?                                          */
/* -------------------------------------------------------------------- */
    if( poAll && poAll->FindNode( "Stats" ) )
    {
        CPLPushErrorHandler( CPLQuietErrorHandler );

        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
        {
            const char *pszValue = 
                poAll->FindElem( "Stats.MinimumValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MINIMUM", pszValue );

            pszValue = poAll->FindElem( "Stats.MaximumValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MAXIMUM", pszValue );

            pszValue = poAll->FindElem( "Stats.MeanValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MEAN", pszValue );

            pszValue = poAll->FindElem( "Stats.MedianValue", iBand-1 );

            if( pszValue )
                poDS->GetRasterBand(iBand)->SetMetadataItem(
                    "STATISTICS_MEDIAN", pszValue );
        }
        
        CPLPopErrorHandler();
        
    }

/* -------------------------------------------------------------------- */
/*      Do we have GCPs.                                                */
/* -------------------------------------------------------------------- */
    if( poHeader->FindNode( "RasterInfo.WarpControl" ) )
        poDS->ReadGCPs();

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
    // if no SR in xml, try aux
    const char* pszPrj = poDS->GDALPamDataset::GetProjectionRef();
    if( !pszPrj || strlen(pszPrj) == 0 )
    {
        // try aux
        GDALDataset* poAuxDS = GDALFindAssociatedAuxFile( poOpenInfo->pszFilename, GA_ReadOnly, poDS );
        if( poAuxDS )
        {
            pszPrj = poAuxDS->GetProjectionRef();
            if( pszPrj && strlen(pszPrj) > 0 )
            {
                CPLFree( poDS->pszProjection );
                poDS->pszProjection = CPLStrdup(pszPrj);
            }

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

    return( poDS );
}
Example #27
0
CPLErr AAIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                   void *pImage )

{
    AAIGDataset *poODS = static_cast<AAIGDataset *>(poDS);

    if( nBlockYOff < 0 || nBlockYOff > poODS->nRasterYSize - 1 ||
        nBlockXOff != 0 || panLineOffset == nullptr || poODS->fp == nullptr )
        return CE_Failure;

    if( panLineOffset[nBlockYOff] == 0 )
    {
        for( int iPrevLine = 1; iPrevLine <= nBlockYOff; iPrevLine++ )
            if( panLineOffset[iPrevLine] == 0 )
                IReadBlock(nBlockXOff, iPrevLine - 1, nullptr);
    }

    if( panLineOffset[nBlockYOff] == 0 )
        return CE_Failure;

    if( poODS->Seek(panLineOffset[nBlockYOff]) != 0 )
    {
        CPLError(CE_Failure, CPLE_FileIO,
                 "Can't seek to offset %lu in input file to read data.",
                 static_cast<long unsigned int>(panLineOffset[nBlockYOff]));
        return CE_Failure;
    }

    for( int iPixel = 0; iPixel < poODS->nRasterXSize; )
    {
        // Suck up any pre-white space.
        char chNext = '\0';
        do {
            chNext = poODS->Getc();
        } while( isspace(static_cast<unsigned char>(chNext)) );

        char szToken[500] = { '\0' };
        int iTokenChar = 0;
        while( chNext != '\0' && !isspace((unsigned char)chNext) )
        {
            if( iTokenChar == sizeof(szToken) - 2 )
            {
                CPLError(CE_Failure, CPLE_FileIO,
                         "Token too long at scanline %d.", nBlockYOff);
                return CE_Failure;
            }

            szToken[iTokenChar++] = chNext;
            chNext = poODS->Getc();
        }

        if( chNext == '\0' &&
            (iPixel != poODS->nRasterXSize - 1 ||
            nBlockYOff != poODS->nRasterYSize - 1) )
        {
            CPLError(CE_Failure, CPLE_FileIO, "File short, can't read line %d.",
                     nBlockYOff);
            return CE_Failure;
        }

        szToken[iTokenChar] = '\0';

        if( pImage != nullptr )
        {
            if( eDataType == GDT_Float64 )
                reinterpret_cast<double *>(pImage)[iPixel] = CPLAtofM(szToken);
            else if( eDataType == GDT_Float32 )
                reinterpret_cast<float *>(pImage)[iPixel] =
                    DoubleToFloatClamp(CPLAtofM(szToken));
            else
                reinterpret_cast<GInt32 *>(pImage)[iPixel] =
                    static_cast<GInt32>(atoi(szToken));
        }

        iPixel++;
    }

    if( nBlockYOff < poODS->nRasterYSize - 1 )
        panLineOffset[nBlockYOff + 1] = poODS->Tell();

    return CE_None;
}
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
{
    /* -------------------------------------------------------------------- */
    /*      Does this look like a CUBE or an IMAGE Primary Data Object?     */
    /* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

    /* -------------------------------------------------------------------- */
    /*      Open the file using the large file API.                         */
    /* -------------------------------------------------------------------- */
    VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    ISIS2Dataset 	*poDS;

    poDS = new ISIS2Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }

    VSIFCloseL( fpQube );

    /* -------------------------------------------------------------------- */
    /*	We assume the user is pointing to the label (ie. .lab) file.  	*/
    /* -------------------------------------------------------------------- */
    // QUBE can be inline or detached and point to an image name
    // ^QUBE = 76
    // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
    // ^QUBE = "ui31s015.img" - which implies no label or skip value

    const char *pszQube = poDS->GetKeyword( "^QUBE" );
    GUIntBig nQube = 0;
    int bByteLocation = FALSE;
    CPLString osTargetFile = poOpenInfo->pszFilename;

    if( pszQube[0] == '"' )
    {
        CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = pszQube;
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL );
        poDS->osExternalCube = osTargetFile;
    }
    else if( pszQube[0] == '(' )
    {
        CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,"");
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL );
        poDS->osExternalCube = osTargetFile;

        nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1"));
        if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != NULL )
            bByteLocation = true;
    }
    else
    {
        nQube = atoi(pszQube);
        if( strstr(pszQube,"<BYTES>") != NULL )
            bByteLocation = true;
    }

    /* -------------------------------------------------------------------- */
    /*      Check if file an ISIS2 header file?  Read a few lines of text   */
    /*      searching for something starting with nrows or ncols.           */
    /* -------------------------------------------------------------------- */
    GDALDataType eDataType = GDT_Byte;
    OGRSpatialReference oSRS;

    //image parameters
    int	nRows, nCols, nBands = 1;
    GUIntBig nSkipBytes = 0;
    int itype;
    int  s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params.
    int record_bytes;
    int	bNoDataSet = FALSE;
    char chByteOrder = 'M';  //default to MSB

    //Georef parameters
    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double dfNoData = 0.0;
    double xulcenter = 0.0;
    double yulcenter = 0.0;

    //projection parameters
    int	bProjectionSet = TRUE;
    double semi_major = 0.0;
    double semi_minor = 0.0;
    double iflattening = 0.0;
    double center_lat = 0.0;
    double center_lon = 0.0;
    double first_std_parallel = 0.0;
    double second_std_parallel = 0.0;
    VSILFILE	*fp;

    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is valid ISIS2 cube                       */
    /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
    /* -------------------------------------------------------------------- */
    s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
    s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
    s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));

    if( s_ix != 0 || s_iy != 0 || s_iz != 0 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
                  "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
                  "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
        delete poDS;
        return NULL;
    }

    /**************** end SUFFIX_ITEM check ***********************/


    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********************************************************/
    const char *value;

    char szLayout[10] = "BSQ"; //default to band seq.
    value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
        strcpy(szLayout,"BSQ");
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
        strcpy(szLayout,"BIP");
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
    nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
    nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));

    /***********   Grab Qube record bytes  **********/
    record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));

    if (nQube > 0 && bByteLocation )
        nSkipBytes = (nQube - 1);
    else if( nQube > 0 )
        nSkipBytes = (nQube - 1) * record_bytes;
    else
        nSkipBytes = 0;

    /***********   Grab samples lines band ************/
    CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
    if( (EQUAL(osCoreItemType,"PC_INTEGER")) ||
            (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) ||
            (EQUAL(osCoreItemType,"PC_REAL")) ) {
        chByteOrder = 'I';
    }

    /********   Grab format type - isis2 only supports 8,16,32 *******/
    itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
    switch(itype) {
    case 1 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
        break;
    case 2 :
        if( strstr(osCoreItemType,"UNSIGNED") != NULL )
        {
            dfNoData = 0;
            eDataType = GDT_UInt16;
        }
        else
        {
            dfNoData = NULL2;
            eDataType = GDT_Int16;
        }
        bNoDataSet = TRUE;
        break;
    case 4 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
        break;
    case 8 :
        eDataType = GDT_Float64;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
        break;
    default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Itype of %d is not supported in ISIS 2.",
                  itype);
        delete poDS;
        return NULL;
    }

    /***********   Grab Cellsize ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
    if (strlen(value) > 0 ) {
        dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */
        dfYDim = (float) atof(value) * 1000.0 * -1;
    }

    /***********   Grab LINE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = (float) atof(value);
        yulcenter = ((yulcenter) * dfYDim);
        dfULYMap = yulcenter - (dfYDim/2);
    }

    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter = (float) atof(value);
        xulcenter = ((xulcenter) * dfXDim);
        dfULXMap = xulcenter - (dfXDim/2);
    }

    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");

    /***********   Grab MAP_PROJECTION_TYPE ************/
    CPLString map_proj_name =
        poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
    poDS->CleanString( map_proj_name );

    /***********   Grab SEMI-MAJOR ************/
    semi_major =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;

    /***********   Grab semi-minor ************/
    semi_minor =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    center_lat =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    center_lon =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));

    /***********   Grab 1st std parallel ************/
    first_std_parallel =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));

    /***********   Grab 2nd std parallel ************/
    second_std_parallel =
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));

    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    char bIsGeographic = TRUE;
    value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
    if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
        bIsGeographic = FALSE;

    CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );

    //Set oSRS projection and parameters
    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
            (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
            (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
               (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "") ) {
        /* no projection */
        bProjectionSet = FALSE;
    } else {
        CPLDebug( "ISIS2",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = FALSE;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword

        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        CPLString geog_name = "GCS_" + target_name;

        //The datum and sphere names will be the same basic name aas the planet
        CPLString datum_name = "D_" + target_name;
        CPLString sphere_name = target_name; // + "_IAU_IAG");  //Might not be IAU defined so don't add

        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        if ((semi_major - semi_minor) < 0.0000001)
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);

        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) ||
                (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))
        {
            if (bIsGeographic) {
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope...
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
            //isis uses the sphereical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0,
                            "Reference_Meridian", 0.0 );
        }
        else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
            //Calculate localRadius using ISIS3 simple elliptical method
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            double radLat, localRadius;
            if (center_lon == 0) { //No need to calculate local radius
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            } else {
                radLat = center_lat * PI / 180;  // in radians
                localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2)
                              + pow(semi_major*sin(radLat),2) );
                sphere_name += "_localRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                localRadius, 0.0,
                                "Reference_Meridian", 0.0 );
                CPLDebug( "ISIS2", "local radius: %f", localRadius);
            }
        }
        else {
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere. I hope...
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }


        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

    /* END ISIS2 Label Read */
    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

    /* -------------------------------------------------------------------- */
    /*      Did we get the required keywords?  If not we return with        */
    /*      this never having been considered to be a match. This isn't     */
    /*      an error!                                                       */
    /* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        delete poDS;
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Capture some information from the file that is of interest.     */
    /* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    /* -------------------------------------------------------------------- */
    /*      Open target binary file.                                        */
    /* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osTargetFile, "rb" );
    else
        poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open %s with write permission.\n%s",
                  osTargetFile.c_str(), VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

    /* -------------------------------------------------------------------- */
    /*      Compute the line offset.                                        */
    /* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int		nLineOffset, nPixelOffset, nBandOffset;

    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nItemSize;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nLineOffset * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        nLineOffset = nItemSize * nBands * nCols;
        nBandOffset = nItemSize * nCols;
    }

    /* -------------------------------------------------------------------- */
    /*      Create band information objects.                                */
    /* -------------------------------------------------------------------- */
    int i;

    poDS->nBands = nBands;;
    for( i = 0; i < poDS->nBands; i++ )
    {
        RawRasterBand	*poBand;

        poBand =
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + nBandOffset * i,
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif
                               TRUE );

        if( bNoDataSet )
            poBand->SetNoDataValue( dfNoData );

        poDS->SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
        poBand->SetScale(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
    }

    /* -------------------------------------------------------------------- */
    /*      Check for a .prj file. For isis2 I would like to keep this in   */
    /* -------------------------------------------------------------------- */
    CPLString osPath, osName;

    osPath = CPLGetPath( poOpenInfo->pszFilename );
    osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpenL( pszPrjFile, "r" );
    if( fp != NULL )
    {
        char	**papszLines;
        OGRSpatialReference oSRS;

        VSIFCloseL( fp );

        papszLines = CSLLoad( pszPrjFile );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = NULL;
            oSRS.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }


    if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw",
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld",
                               poDS->adfGeoTransform );

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

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

    return( poDS );
}
Example #29
0
int GRASSASCIIDataset::ParseHeader(const char *pszHeader,
                                   const char *pszDataType)
{
    char **papszTokens = CSLTokenizeString2(pszHeader, " \n\r\t:", 0);
    const int nTokens = CSLCount(papszTokens);
    int i = 0;
    if ( (i = CSLFindString(papszTokens, "cols")) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterXSize = atoi(papszTokens[i + 1]);
    if ( (i = CSLFindString( papszTokens, "rows" )) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterYSize = atoi(papszTokens[i + 1]);

    if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize))
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    // TODO(schwehr): Would be good to also factor the file size into the max.
    // TODO(schwehr): Allow the user to disable this check.
    // The driver allocates a panLineOffset array based on nRasterYSize
    constexpr int kMaxDimSize = 10000000;  // 1e7 cells.
    if (nRasterXSize > kMaxDimSize || nRasterYSize > kMaxDimSize)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    const int iNorth = CSLFindString(papszTokens, "north");
    const int iSouth = CSLFindString(papszTokens, "south");
    const int iEast = CSLFindString(papszTokens, "east");
    const int iWest = CSLFindString(papszTokens, "west");

    if (iNorth == -1 || iSouth == -1 || iEast == -1 || iWest == -1 ||
        std::max(std::max(iNorth, iSouth),
                 std::max(iEast, iWest)) + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    const double dfNorth = CPLAtofM(papszTokens[iNorth + 1]);
    const double dfSouth = CPLAtofM(papszTokens[iSouth + 1]);
    const double dfEast = CPLAtofM(papszTokens[iEast + 1]);
    const double dfWest = CPLAtofM(papszTokens[iWest + 1]);
    const double dfPixelXSize = (dfEast - dfWest) / nRasterXSize;
    const double dfPixelYSize = (dfNorth - dfSouth) / nRasterYSize;

    adfGeoTransform[0] = dfWest;
    adfGeoTransform[1] = dfPixelXSize;
    adfGeoTransform[2] = 0.0;
    adfGeoTransform[3] = dfNorth;
    adfGeoTransform[4] = 0.0;
    adfGeoTransform[5] = -dfPixelYSize;

    if( (i = CSLFindString(papszTokens, "null")) >= 0 &&
        i + 1 < nTokens)
    {
        const char *pszNoData = papszTokens[i + 1];

        bNoDataSet = true;
        dfNoDataValue = CPLAtofM(pszNoData);
        if( pszDataType == nullptr &&
            (strchr(pszNoData, '.') != nullptr ||
             strchr(pszNoData, ',') != nullptr ||
             std::numeric_limits<int>::min() > dfNoDataValue ||
             dfNoDataValue > std::numeric_limits<int>::max()) )
        {
            eDataType = GDT_Float32;
        }
        if( eDataType == GDT_Float32 )
        {
            dfNoDataValue = MapNoDataToFloat(dfNoDataValue);
        }
    }

    if( (i = CSLFindString(papszTokens, "type")) >= 0 &&
        i + 1 < nTokens)
    {
        const char *pszType = papszTokens[i + 1];
        if (EQUAL(pszType, "int"))
            eDataType = GDT_Int32;
        else if (EQUAL(pszType, "float"))
            eDataType = GDT_Float32;
        else if (EQUAL(pszType, "double"))
            eDataType = GDT_Float64;
        else
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Invalid value for type parameter : %s", pszType);
        }
    }

    CSLDestroy(papszTokens);

    return TRUE;
}
Example #30
0
int PDSDataset::ParseImage( CPLString osPrefix )
{
/* ------------------------------------------------------------------- */
/*	We assume the user is pointing to the label (ie. .lbl) file.  	   */
/* ------------------------------------------------------------------- */
    // IMAGE can be inline or detached and point to an image name
    // ^IMAGE = 3
    // ^IMAGE             = "GLOBAL_ALBEDO_8PPD.IMG"
    // ^IMAGE             = "MEGT90N000CB.IMG"
    // ^IMAGE		  = ("BLAH.IMG",1)	 -- start at record 1 (1 based)
    // ^IMAGE		  = ("BLAH.IMG")	 -- still start at record 1 (equiv of "BLAH.IMG")
    // ^IMAGE		  = ("BLAH.IMG", 5 <BYTES>) -- start at byte 5 (the fifth byte in the file)
    // ^IMAGE             = 10851 <BYTES>
    // ^SPECTRAL_QUBE = 5  for multi-band images

    CPLString osImageKeyword = osPrefix + "^IMAGE";
    CPLString osQube = GetKeyword( osImageKeyword, "" );
    CPLString osTargetFile = GetDescription();

    if (EQUAL(osQube,"")) {
        osImageKeyword = "^SPECTRAL_QUBE";
        osQube = GetKeyword( osImageKeyword );
    }

    int nQube = atoi(osQube);
    int nDetachedOffset = 0;
    int bDetachedOffsetInBytes = FALSE;

    if( osQube.size() && osQube[0] == '(' )
    {
        osQube = "\"";
        osQube += GetKeywordSub( osImageKeyword, 1 );
        osQube +=  "\"";
        nDetachedOffset = atoi(GetKeywordSub( osImageKeyword, 2, "1")) - 1;

        // If this is not explicitly in bytes, then it is assumed to be in
        // records, and we need to translate to bytes.
        if (strstr(GetKeywordSub(osImageKeyword,2),"<BYTES>") != NULL)
            bDetachedOffsetInBytes = TRUE;
    }

    if( osQube.size() && osQube[0] == '"' )
    {
        CPLString osTPath = CPLGetPath(GetDescription());
        CPLString osFilename = osQube;
        CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL );
        osExternalCube = osTargetFile;
    }

    GDALDataType eDataType = GDT_Byte;

    
    //image parameters
    int	nRows, nCols, nBands = 1;
    int nSkipBytes = 0;
    int itype;
    int record_bytes;
    char chByteOrder = 'M';  //default to MSB
    double dfNoData = 0.0;
 
    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is raw PDS image not compressed image     */
    /*      so ENCODING_TYPE either does not exist or it equals "N/A".      */
    /*      Compressed types will not be supported in this routine          */
    /* -------------------------------------------------------------------- */
    const char *value;

    CPLString osEncodingType = GetKeyword(osPrefix+"IMAGE.ENCODING_TYPE","N/A");
    CleanString(osEncodingType);
    if ( !EQUAL(osEncodingType.c_str(),"N/A") )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "*** PDS image file has an ENCODING_TYPE parameter:\n"
                  "*** gdal pds driver does not support compressed image types\n"
                  "found: (%s)\n\n", osEncodingType.c_str() );
        return FALSE;
    } 
    /**************** end ENCODING_TYPE check ***********************/
    
    
    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********   Grab samples lines band        **************/
    /** if AXIS_NAME = "" then Bands=1 and Sample and Lines   **/
    /** are there own keywords  "LINES" and "LINE_SAMPLES"    **/
    /** if not NULL then CORE_ITEMS keyword i.e. (234,322,2)  **/
    /***********************************************************/
    char szLayout[10] = "BSQ"; //default to band seq.
    value = GetKeyword( osPrefix+"IMAGE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) {
        strcpy(szLayout,"BSQ");
        nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1));
        nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2));
        nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3));
    }
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) {
        strcpy(szLayout,"BIP");
        nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1));
        nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2));
        nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3));
    }
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") ) {
        strcpy(szLayout,"BIL");
        nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1));
        nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2));
        nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3));
    }
    else if ( EQUAL(value,"") ) {
        strcpy(szLayout,"BSQ");
        nCols = atoi(GetKeyword(osPrefix+"IMAGE.LINE_SAMPLES",""));
        nRows = atoi(GetKeyword(osPrefix+"IMAGE.LINES",""));
        nBands = atoi(GetKeyword(osPrefix+"IMAGE.BANDS","1"));
    }
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout not supported. Abort\n\n", value);
        return FALSE;
    }
    
    /***********   Grab Qube record bytes  **********/
    record_bytes = atoi(GetKeyword(osPrefix+"IMAGE.RECORD_BYTES"));
    if (record_bytes == 0)
        record_bytes = atoi(GetKeyword(osPrefix+"RECORD_BYTES"));

    // this can happen with "record_type = undefined". 
    if( record_bytes == 0 )
        record_bytes = 1;

    if( nQube >0 && osQube.find("<BYTES>") != CPLString::npos )
        nSkipBytes = nQube - 1;
    else if (nQube > 0 )
        nSkipBytes = (nQube - 1) * record_bytes;
    else if( nDetachedOffset > 0 )
    {
        if (bDetachedOffsetInBytes)
            nSkipBytes = nDetachedOffset;
        else
            nSkipBytes = nDetachedOffset * record_bytes;
    }
    else
        nSkipBytes = 0;     

    nSkipBytes += atoi(GetKeyword(osPrefix+"IMAGE.LINE_PREFIX_BYTES",""));
    
    /***********   Grab SAMPLE_TYPE *****************/
    /** if keyword not found leave as "M" or "MSB" **/
    CPLString osST = GetKeyword( osPrefix+"IMAGE.SAMPLE_TYPE" );
    if( osST.size() >= 2 && osST[0] == '"' && osST[osST.size()-1] == '"' )
        osST = osST.substr( 1, osST.size() - 2 );

    if( (EQUAL(osST,"LSB_INTEGER")) || 
        (EQUAL(osST,"LSB")) || // just incase
        (EQUAL(osST,"LSB_UNSIGNED_INTEGER")) || 
        (EQUAL(osST,"LSB_SIGNED_INTEGER")) || 
        (EQUAL(osST,"UNSIGNED_INTEGER")) || 
        (EQUAL(osST,"VAX_REAL")) || 
        (EQUAL(osST,"VAX_INTEGER")) || 
        (EQUAL(osST,"PC_INTEGER")) ||  //just incase 
        (EQUAL(osST,"PC_REAL")) ) {
        chByteOrder = 'I';
    }

    /**** Grab format type - pds supports 1,2,4,8,16,32,64 (in theory) **/
    /**** I have only seen 8, 16, 32 (float) in released datasets      **/
    itype = atoi(GetKeyword(osPrefix+"IMAGE.SAMPLE_BITS",""));
    switch(itype) {
      case 8 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        break;
      case 16 :
        if( strstr(osST,"UNSIGNED") != NULL )
            eDataType = GDT_UInt16;
        else
            eDataType = GDT_Int16;
        dfNoData = NULL2;
        break;
      case 32 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        break;
      case 64 :
        eDataType = GDT_Float64;
        dfNoData = NULL3;
        break;
      default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Sample_bits of %d is not supported in this gdal PDS reader.",
                  itype); 
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Is there a specific nodata value in the file? Either the        */
/*      MISSING or MISSING_CONSTANT keywords are nodata.                */
/* -------------------------------------------------------------------- */
    if( GetKeyword( osPrefix+"IMAGE.MISSING", NULL ) != NULL )
        dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING", "" ) );

    if( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT", NULL ) != NULL )
        dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT",""));

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s appears to be a PDS file, but failed to find some required keywords.", 
                  GetDescription() );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    nRasterXSize = nCols;
    nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    
    if( eAccess == GA_ReadOnly )
    {
        fpImage = VSIFOpenL( osTargetFile, "rb" );
        if( fpImage == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed, 
                    "Failed to open %s.\n%s", 
                    osTargetFile.c_str(),
                    VSIStrerror( errno ) );
            return FALSE;
        }
    }
    else
    {
        fpImage = VSIFOpenL( osTargetFile, "r+b" );
        if( fpImage == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed, 
                    "Failed to open %s with write permission.\n%s", 
                    osTargetFile.c_str(),
                    VSIStrerror( errno ) );
            return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int     nLineOffset = record_bytes;
    int	    nPixelOffset, nBandOffset;

    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        nBandOffset = nItemSize;
        nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes)
            * record_bytes;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes)
            * record_bytes;
        nBandOffset = nLineOffset * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        nBandOffset = nItemSize * nCols;
        nLineOffset = ((nBandOffset * nCols + record_bytes - 1)/record_bytes)
            * record_bytes;
    }
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int i;

    for( i = 0; i < nBands; i++ )
    {
        RawRasterBand	*poBand;

        poBand = 
            new RawRasterBand( this, i+1, fpImage,
                               nSkipBytes + nBandOffset * i, 
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB                               
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif        
                               TRUE );

        if( nBands == 1 )
        {
            const char* pszMin = GetKeyword(osPrefix+"IMAGE.MINIMUM", NULL);
            const char* pszMax = GetKeyword(osPrefix+"IMAGE.MAXIMUM", NULL);
            const char* pszMean = GetKeyword(osPrefix+"IMAGE.MEAN", NULL);
            const char* pszStdDev= GetKeyword(osPrefix+"IMAGE.STANDARD_DEVIATION", NULL);
            if (pszMin != NULL && pszMax != NULL &&
                pszMean != NULL && pszStdDev != NULL)
            {
                poBand->SetStatistics( CPLAtofM(pszMin),
                                       CPLAtofM(pszMax),
                                       CPLAtofM(pszMean),
                                       CPLAtofM(pszStdDev));
            }
        }
        
        poBand->SetNoDataValue( dfNoData );

        SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset( 
            CPLAtofM(GetKeyword(osPrefix+"IMAGE.OFFSET","0.0")));
        poBand->SetScale( 
            CPLAtofM(GetKeyword(osPrefix+"IMAGE.SCALING_FACTOR","1.0")));
    }

    return TRUE;
}