Пример #1
0
CPLErr USGSDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
                                      CPL_UNUSED int nBlockYOff,
                                      void * pImage )

{
    /* int bad = FALSE; */
    USGSDEMDataset *poGDS = reinterpret_cast<USGSDEMDataset *>( poDS );

/* -------------------------------------------------------------------- */
/*      Initialize image buffer to nodata value.                        */
/* -------------------------------------------------------------------- */
    for( int k = GetXSize() * GetYSize() - 1; k >= 0; k-- )
    {
        if( GetRasterDataType() == GDT_Int16 )
            reinterpret_cast<GInt16 *>( pImage )[k] = USGSDEM_NODATA;
        else
            reinterpret_cast<float *>( pImage )[k] = USGSDEM_NODATA;
    }

/* -------------------------------------------------------------------- */
/*      Seek to data.                                                   */
/* -------------------------------------------------------------------- */
    CPL_IGNORE_RET_VAL(VSIFSeekL(poGDS->fp, poGDS->nDataStartOffset, 0));

    double dfYMin = poGDS->adfGeoTransform[3]
        + (GetYSize()-0.5) * poGDS->adfGeoTransform[5];

/* -------------------------------------------------------------------- */
/*      Read all the profiles into the image buffer.                    */
/* -------------------------------------------------------------------- */

    Buffer sBuffer;
    sBuffer.max_size = 32768;
    sBuffer.buffer
        = reinterpret_cast<char *>( CPLMalloc( sBuffer.max_size + 1 ) );
    sBuffer.fp = poGDS->fp;
    sBuffer.buffer_size = 0;
    sBuffer.cur_index = 0;

    for( int i = 0; i < GetXSize(); i++)
    {
        int bSuccess;
        const int nRowNumber = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess);
        if( nRowNumber != 1 )
            CPLDebug("USGSDEM", "i = %d, nRowNumber = %d", i, nRowNumber);
        if( bSuccess )
        {
            const int nColNumber = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess);
            if( nColNumber != i + 1 )
            {
                CPLDebug("USGSDEM", "i = %d, nColNumber = %d", i, nColNumber);
            }
        }
        const int nCPoints = (bSuccess) ? USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess) : 0;
#ifdef DEBUG_VERBOSE
        CPLDebug("USGSDEM", "i = %d, nCPoints = %d", i, nCPoints);
#endif

        if( bSuccess )
        {
            const int nNumberOfCols = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess);
            if( nNumberOfCols != 1 )
            {
                CPLDebug("USGSDEM", "i = %d, nNumberOfCols = %d", i, nNumberOfCols);
            }
        }

        // x-start
        if( bSuccess )
        /* dxStart = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess);

        double dyStart = (bSuccess) ? USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess) : 0;
        const double dfElevOffset = (bSuccess) ? USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess) : 0;

        // min z value
        if( bSuccess )
        /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess);

        // max z value
        if( bSuccess )
        /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess);
        if( !bSuccess )
        {
            CPLFree(sBuffer.buffer);
            return CE_Failure;
        }

        if( STARTS_WITH_CI(poGDS->pszProjection, "GEOGCS") )
            dyStart = dyStart / 3600.0;

        double dygap = (dfYMin - dyStart)/poGDS->adfGeoTransform[5]+ 0.5;
        if( dygap <= INT_MIN || dygap >= INT_MAX || !CPLIsFinite(dygap) )
        {
            CPLFree(sBuffer.buffer);
            return CE_Failure;
        }
        int lygap = static_cast<int>(dygap);
        if( nCPoints <= 0 )
            continue;
        if( lygap > INT_MAX - nCPoints )
            lygap = INT_MAX - nCPoints;

        for (int j=lygap; j < (nCPoints + lygap); j++)
        {
            const int iY = GetYSize() - j - 1;

            const int nElev = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess);
#ifdef DEBUG_VERBOSE
            CPLDebug("USGSDEM", "  j - lygap = %d, nElev = %d", j - lygap, nElev);
#endif

            if( !bSuccess )
            {
                CPLFree(sBuffer.buffer);
                return CE_Failure;
            }

            if (iY < 0 || iY >= GetYSize() ) {
                /* bad = TRUE; */
            } else if( nElev == USGSDEM_NODATA )
                /* leave in output buffer as nodata */;
            else
            {
                const float fComputedElev =
                    static_cast<float>(nElev * poGDS->fVRes + dfElevOffset);

                if( GetRasterDataType() == GDT_Int16 )
                {
                    GUInt16 nVal = ( fComputedElev < -32768 ) ? -32768 :
                                   ( fComputedElev > 32767 ) ? 32767 :
                                   static_cast<GInt16>( fComputedElev );
                    reinterpret_cast<GInt16 *>( pImage )[i + iY*GetXSize()]
                        = nVal;
                }
                else
                {
                    reinterpret_cast<float *>( pImage )[i + iY*GetXSize()]
                        = fComputedElev;
                }
            }
        }

        if( poGDS->nDataStartOffset == 1024 )
        {
            // Seek to the next 1024 byte boundary.
            // Some files have 'junk' profile values after the valid/declared ones
            vsi_l_offset nCurPos = USGSDEMGetCurrentFilePos(&sBuffer);
            vsi_l_offset nNewPos = (nCurPos + 1023) / 1024 * 1024;
            if( nNewPos > nCurPos )
            {
                USGSDEMSetCurrentFilePos(&sBuffer, nNewPos);
            }
        }
    }
    CPLFree(sBuffer.buffer);

    return CE_None;
}
Пример #2
0
CPLErr USGSDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
                                      CPL_UNUSED int nBlockYOff,
                                      void * pImage )

{
    double	dfYMin;
    /* int		bad = FALSE; */
    USGSDEMDataset *poGDS = (USGSDEMDataset *) poDS;

/* -------------------------------------------------------------------- */
/*      Initialize image buffer to nodata value.                        */
/* -------------------------------------------------------------------- */
    for( int k = GetXSize() * GetYSize() - 1; k >= 0; k-- )
    {
        if( GetRasterDataType() == GDT_Int16 )
            ((GInt16 *) pImage)[k] = USGSDEM_NODATA;
        else
            ((float *) pImage)[k] = USGSDEM_NODATA;
    }

/* -------------------------------------------------------------------- */
/*      Seek to data.                                                   */
/* -------------------------------------------------------------------- */
    VSIFSeekL(poGDS->fp, poGDS->nDataStartOffset, 0);

    dfYMin = poGDS->adfGeoTransform[3] 
        + (GetYSize()-0.5) * poGDS->adfGeoTransform[5];

/* -------------------------------------------------------------------- */
/*      Read all the profiles into the image buffer.                    */
/* -------------------------------------------------------------------- */

    Buffer sBuffer;
    sBuffer.max_size = 32768;
    sBuffer.buffer = (char*) CPLMalloc(sBuffer.max_size + 1);
    sBuffer.fp = poGDS->fp;
    sBuffer.buffer_size = 0;
    sBuffer.cur_index = 0;

    for( int i = 0; i < GetXSize(); i++)
    {
        int	/* njunk, */ nCPoints, lygap;
        double	/* djunk, dxStart, */ dyStart, dfElevOffset;

        /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer);
        /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer);
        nCPoints = USGSDEMReadIntFromBuffer(&sBuffer);
        /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer);

        /* dxStart = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24);
        dyStart = USGSDEMReadDoubleFromBuffer(&sBuffer, 24);
        dfElevOffset = USGSDEMReadDoubleFromBuffer(&sBuffer, 24);
        /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24);
        /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24);

        if( EQUALN(poGDS->pszProjection,"GEOGCS",6) )
            dyStart = dyStart / 3600.0;

        lygap = (int)((dfYMin - dyStart)/poGDS->adfGeoTransform[5]+ 0.5);

        for (int j=lygap; j < (nCPoints+(int)lygap); j++)
        {
            int		iY = GetYSize() - j - 1;
            int         nElev;
            int     bSuccess;

            nElev = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess);
            if( !bSuccess )
            {
                CPLFree(sBuffer.buffer);
                return CE_Failure;
            }

            if (iY < 0 || iY >= GetYSize() ) {
                /* bad = TRUE; */
            } else if( nElev == USGSDEM_NODATA )
                /* leave in output buffer as nodata */;
            else
            {
                float fComputedElev =
                    (float)(nElev * poGDS->fVRes + dfElevOffset);

                if( GetRasterDataType() == GDT_Int16 )
                {
                    ((GInt16 *) pImage)[i + iY*GetXSize()] =
                        (GInt16) fComputedElev;
                }
                else
                {
                    ((float *) pImage)[i + iY*GetXSize()] = fComputedElev;
                }
            }
        }
    }
    CPLFree(sBuffer.buffer);

    return CE_None;
}