CPLErr VRTSourcedRasterBand::AddFuncSource( VRTImageReadFunc pfnReadFunc, void *pCBData, double dfNoDataValue ) { /* -------------------------------------------------------------------- */ /* Create source. */ /* -------------------------------------------------------------------- */ VRTFuncSource *poFuncSource = new VRTFuncSource; poFuncSource->fNoDataValue = (float) dfNoDataValue; poFuncSource->pfnReadFunc = pfnReadFunc; poFuncSource->pCBData = pCBData; poFuncSource->eType = GetRasterDataType(); /* -------------------------------------------------------------------- */ /* add to list. */ /* -------------------------------------------------------------------- */ return AddSource( poFuncSource ); }
SDERasterBand::SDERasterBand( SDEDataset *poDS, int nBand, int nOverview, const SE_RASBANDINFO* band ) { // Carry some of the data we were given at construction. // If we were passed -1 for an overview at construction, reset it // to 0 to ensure we get the zero'th level from SDE. // The SE_RASBANDINFO* we were given is actually owned by the // dataset. We want it around for convenience. this->poDS = poDS; this->nBand = nBand; this->nOverview = nOverview; this->poBand = band; // Initialize our SDE opaque object pointers to NULL. // The nOverviews private data member will be updated when // GetOverviewCount is called and subsequently returned immediately in // later calls if it has been set to anything other than 0. this->hConstraint = NULL; this->hQuery = NULL; this->poColorTable = NULL; if (this->nOverview == -1 || this->nOverview == 0) this->nOverviews = GetOverviewCount(); else this->nOverviews = 0; if (nOverview == -1) { this->papoOverviews = (GDALRasterBand**) CPLMalloc( nOverviews * sizeof(GDALRasterBand*) ); } else { this->papoOverviews = NULL; } this->eDataType = GetRasterDataType(); // nSDERasterType is set by GetRasterDataType this->dfDepth = MorphESRIRasterDepth(nSDERasterType); InitializeBand(this->nOverview); }
CPLErr RawRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { CPLErr eErr = CE_None; CPLAssert( nBlockXOff == 0 ); if (pLineBuffer == NULL) return CE_Failure; /* -------------------------------------------------------------------- */ /* If the data for this band is completely contiguous we don't */ /* have to worry about pre-reading from disk. */ /* -------------------------------------------------------------------- */ if( ABS(nPixelOffset) > GDALGetDataTypeSize(eDataType) / 8 ) eErr = AccessLine( nBlockYOff ); /* -------------------------------------------------------------------- */ /* Copy data from user buffer into disk buffer. */ /* -------------------------------------------------------------------- */ GDALCopyWords( pImage, eDataType, GDALGetDataTypeSize(eDataType)/8, pLineStart, eDataType, nPixelOffset, nBlockXSize ); /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into disk order before writing. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } /* -------------------------------------------------------------------- */ /* Figure out where to start reading. */ /* -------------------------------------------------------------------- */ vsi_l_offset nWriteStart; if( nPixelOffset >= 0 ) nWriteStart = nImgOffset + (vsi_l_offset)nBlockYOff * nLineOffset; else { nWriteStart = nImgOffset + (vsi_l_offset)nBlockYOff * nLineOffset - ABS(nPixelOffset) * (nBlockXSize-1); } /* -------------------------------------------------------------------- */ /* Seek to correct location. */ /* -------------------------------------------------------------------- */ if( Seek( nWriteStart, SEEK_SET ) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to scanline %d @ %d to write to file.\n", nBlockYOff, (int) (nImgOffset + nBlockYOff * nLineOffset) ); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Write data buffer. */ /* -------------------------------------------------------------------- */ int nBytesToWrite; nBytesToWrite = ABS(nPixelOffset) * (nBlockXSize - 1) + GDALGetDataTypeSize(GetRasterDataType()) / 8; if( eErr == CE_None && Write( pLineBuffer, 1, nBytesToWrite ) < (size_t) nBytesToWrite ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write scanline %d to file.\n", nBlockYOff ); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } bDirty = TRUE; return eErr; }
CPLErr RawRasterBand::AccessLine( int iLine ) { if (pLineBuffer == NULL) return CE_Failure; if( nLoadedScanline == iLine ) return CE_None; /* -------------------------------------------------------------------- */ /* Figure out where to start reading. */ /* -------------------------------------------------------------------- */ vsi_l_offset nReadStart; if( nPixelOffset >= 0 ) nReadStart = nImgOffset + (vsi_l_offset)iLine * nLineOffset; else { nReadStart = nImgOffset + (vsi_l_offset)iLine * nLineOffset - ABS(nPixelOffset) * (nBlockXSize-1); } /* -------------------------------------------------------------------- */ /* Seek to the right line. */ /* -------------------------------------------------------------------- */ if( Seek(nReadStart, SEEK_SET) == -1 ) { if (poDS != NULL && poDS->GetAccess() == GA_ReadOnly) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to scanline %d @ %d.\n", iLine, (int) (nImgOffset + (vsi_l_offset)iLine * nLineOffset) ); return CE_Failure; } else { memset( pLineBuffer, 0, nPixelOffset * nBlockXSize ); nLoadedScanline = iLine; return CE_None; } } /* -------------------------------------------------------------------- */ /* Read the line. Take care not to request any more bytes than */ /* are needed, and not to lose a partially successful scanline */ /* read. */ /* -------------------------------------------------------------------- */ int nBytesToRead, nBytesActuallyRead; nBytesToRead = ABS(nPixelOffset) * (nBlockXSize - 1) + GDALGetDataTypeSize(GetRasterDataType()) / 8; nBytesActuallyRead = Read( pLineBuffer, 1, nBytesToRead ); if( nBytesActuallyRead < nBlockXSize ) { if (poDS != NULL && poDS->GetAccess() == GA_ReadOnly) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read scanline %d.\n", iLine); return CE_Failure; } else { memset( ((GByte *) pLineBuffer) + nBytesActuallyRead, 0, nBytesToRead - nBytesActuallyRead ); } } /* -------------------------------------------------------------------- */ /* Byte swap the interesting data, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } nLoadedScanline = iLine; return CE_None; }
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; }
bool OsmAnd::HeightmapTileProvider_P::obtainData( const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapTiledData>& outTiledData, const IQueryController* const queryController) { // Obtain raw data from DB QByteArray data; bool ok = _tileDb.obtainTileData(tileId, zoom, data); if (!ok || data.length() == 0) { // There was no data at all, to avoid further requests, mark this tile as empty outTiledData.reset(); return true; } // We have the data, use GDAL to decode this GeoTIFF const auto tileSize = getTileSize(); bool success = false; QString vmemFilename; vmemFilename.sprintf("/vsimem/heightmapTile@%p", data.data()); VSIFileFromMemBuffer(qPrintable(vmemFilename), reinterpret_cast<GByte*>(data.data()), data.length(), FALSE); auto dataset = reinterpret_cast<GDALDataset*>(GDALOpen(qPrintable(vmemFilename), GA_ReadOnly)); if (dataset != nullptr) { bool bad = false; bad = bad || dataset->GetRasterCount() != 1; bad = bad || dataset->GetRasterXSize() != tileSize; bad = bad || dataset->GetRasterYSize() != tileSize; if (bad) { if (dataset->GetRasterCount() != 1) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %d bands instead of 1", tileId.x, tileId.y, zoom, dataset->GetRasterCount()); if (dataset->GetRasterXSize() != tileSize || dataset->GetRasterYSize() != tileSize) { LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %dx%x size instead of %d", tileId.x, tileId.y, zoom, dataset->GetRasterXSize(), dataset->GetRasterYSize(), tileSize); } } else { auto band = dataset->GetRasterBand(1); bad = bad || band->GetColorTable() != nullptr; bad = bad || band->GetRasterDataType() != GDT_Int16; if (bad) { if (band->GetColorTable() != nullptr) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has color table", tileId.x, tileId.y, zoom); if (band->GetRasterDataType() != GDT_Int16) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %s data type in band 1", tileId.x, tileId.y, zoom, GDALGetDataTypeName(band->GetRasterDataType())); } else { auto buffer = new float[tileSize*tileSize]; auto res = dataset->RasterIO(GF_Read, 0, 0, tileSize, tileSize, buffer, tileSize, tileSize, GDT_Float32, 1, nullptr, 0, 0, 0); if (res != CE_None) { delete[] buffer; LogPrintf(LogSeverityLevel::Error, "Failed to decode height tile %dx%d@%d: %s", tileId.x, tileId.y, zoom, CPLGetLastErrorMsg()); } else { outTiledData.reset(new ElevationDataTile(buffer, sizeof(float)*tileSize, tileSize, tileId, zoom)); success = true; } } } GDALClose(dataset); } VSIUnlink(qPrintable(vmemFilename)); return success; }
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; }
CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" ); /* -------------------------------------------------------------------- */ /* Various kinds of metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; CPLSetXMLValue( psTree, "#dataType", GDALGetDataTypeName( GetRasterDataType() ) ); if( nBand > 0 ) CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) ); psMD = oMDMD.Serialize(); if( psMD != NULL ) CPLAddXMLChild( psTree, psMD ); if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( bNoDataValueSet ) { if (CPLIsNan(dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan"); else CPLSetXMLValue( psTree, "NoDataValue", CPLSPrintf( "%.14E", dfNoDataValue ) ); } if( bHideNoDataValue ) CPLSetXMLValue( psTree, "HideNoDataValue", CPLSPrintf( "%d", bHideNoDataValue ) ); if( pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", pszUnitType ); if( dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", CPLSPrintf( "%.16g", dfOffset ) ); if( dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", CPLSPrintf( "%.16g", dfScale ) ); if( eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( eColorInterp ) ); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ ) { CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category", papszCategoryNames[iEntry] ); if( psLastChild == NULL ) psCT_XML->psChild = psNode; else psLastChild->psNext = psNode; psLastChild = psNode; } } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element, "Entry" ); if( psLastChild == NULL ) psCT_XML->psChild = psEntry_XML; else psLastChild->psNext = psEntry_XML; psLastChild = psEntry_XML; poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) ); } } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ for( int iOvr = 0; iOvr < (int)apoOverviews.size(); iOvr ++ ) { CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element, "Overview" ); int bRelativeToVRT; const char *pszRelativePath; VSIStatBufL sStat; if( VSIStatExL( apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 ) { pszRelativePath = apoOverviews[iOvr].osFilename; bRelativeToVRT = FALSE; } else { pszRelativePath = CPLExtractRelativePath( pszVRTPath, apoOverviews[iOvr].osFilename, &bRelativeToVRT ); } CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath ); CPLCreateXMLNode( CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ), CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); CPLSetXMLValue( psOVR_XML, "SourceBand", CPLSPrintf("%d",apoOverviews[iOvr].nBand) ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ if( poMaskBand != NULL ) { CPLXMLNode *psBandTree = poMaskBand->SerializeToXML(pszVRTPath); if( psBandTree != NULL ) { CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element, "MaskBand" ); CPLAddXMLChild( psMaskBandElement, psBandTree ); } } return psTree; }
CPLErr USGSDEMRasterBand::IReadBlock( int nBlockXOff, 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. */ /* -------------------------------------------------------------------- */ VSIFSeek(poGDS->fp, poGDS->nDataStartOffset, 0); dfYMin = poGDS->adfGeoTransform[3] + (GetYSize()-0.5) * poGDS->adfGeoTransform[5]; /* -------------------------------------------------------------------- */ /* Read all the profiles into the image buffer. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < GetXSize(); i++) { int njunk, nCPoints, lygap; double djunk, dxStart, dyStart, dfElevOffset; fscanf(poGDS->fp, "%d", &njunk); fscanf(poGDS->fp, "%d", &njunk); fscanf(poGDS->fp, "%d", &nCPoints); fscanf(poGDS->fp, "%d", &njunk); dxStart = DConvert(poGDS->fp, 24); dyStart = DConvert(poGDS->fp, 24); dfElevOffset = DConvert(poGDS->fp, 24); djunk = DConvert(poGDS->fp, 24); djunk = DConvert(poGDS->fp, 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; fscanf(poGDS->fp, "%d", &nElev); 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; } } } } return CE_None; }
CPLErr VRTRawRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath ) { const CPLErr eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath ); if( eErr != CE_None ) return eErr; /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == NULL || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue, "VRTRasterBand") || !EQUAL(CPLGetXMLValue(psTree,"subClass",""), "VRTRawRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRawRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ const char *pszFilename = CPLGetXMLValue(psTree, "SourceFilename", NULL); if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in VRTRasterBand." ); return CE_Failure; } // TODO(schwehr): Should this be a bool? const int l_bRelativeToVRT = atoi(CPLGetXMLValue( psTree, "SourceFilename.relativeToVRT", "1" ) ); /* -------------------------------------------------------------------- */ /* Collect layout information. */ /* -------------------------------------------------------------------- */ int nWordDataSize = GDALGetDataTypeSizeBytes( GetRasterDataType() ); const char* pszImageOffset = CPLGetXMLValue( psTree, "ImageOffset", "0"); const vsi_l_offset nImageOffset = CPLScanUIntBig( pszImageOffset, static_cast<int>(strlen(pszImageOffset)) ); int nPixelOffset = nWordDataSize; if( CPLGetXMLValue( psTree, "PixelOffset", NULL ) != NULL ) { nPixelOffset = atoi(CPLGetXMLValue( psTree, "PixelOffset", "0") ); } if (nPixelOffset <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid value for <PixelOffset> element : %d", nPixelOffset ); return CE_Failure; } int nLineOffset = 0; if( CPLGetXMLValue( psTree, "LineOffset", NULL ) == NULL ) nLineOffset = nWordDataSize * GetXSize(); else nLineOffset = atoi(CPLGetXMLValue( psTree, "LineOffset", "0") ); const char *pszByteOrder = CPLGetXMLValue( psTree, "ByteOrder", NULL ); /* -------------------------------------------------------------------- */ /* Open the file, and setup the raw layer access to the data. */ /* -------------------------------------------------------------------- */ return SetRawLink( pszFilename, pszVRTPath, l_bRelativeToVRT, nImageOffset, nPixelOffset, nLineOffset, pszByteOrder ); }
CPLErr VRTRawRasterBand::SetRawLink( const char *pszFilename, const char *pszVRTPath, int bRelativeToVRTIn, vsi_l_offset nImageOffset, int nPixelOffset, int nLineOffset, const char *pszByteOrder ) { ClearRawLink(); reinterpret_cast<VRTDataset *>( poDS )->SetNeedsFlush(); /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in VRTRasterBand." ); return CE_Failure; } char *pszExpandedFilename = NULL; if( pszVRTPath != NULL && bRelativeToVRTIn ) { pszExpandedFilename = CPLStrdup( CPLProjectRelativeFilename( pszVRTPath, pszFilename ) ); } else { pszExpandedFilename = CPLStrdup( pszFilename ); } /* -------------------------------------------------------------------- */ /* Try and open the file. We always use the large file API. */ /* -------------------------------------------------------------------- */ FILE *fp = CPLOpenShared( pszExpandedFilename, "rb+", TRUE ); if( fp == NULL ) fp = CPLOpenShared( pszExpandedFilename, "rb", TRUE ); if( fp == NULL && reinterpret_cast<VRTDataset *>( poDS )->GetAccess() == GA_Update ) { fp = CPLOpenShared( pszExpandedFilename, "wb+", TRUE ); } if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open %s.%s", pszExpandedFilename, VSIStrerror( errno ) ); CPLFree( pszExpandedFilename ); return CE_Failure; } CPLFree( pszExpandedFilename ); m_pszSourceFilename = CPLStrdup(pszFilename); m_bRelativeToVRT = bRelativeToVRTIn; /* -------------------------------------------------------------------- */ /* Work out if we are in native mode or not. */ /* -------------------------------------------------------------------- */ bool bNative = true; if( pszByteOrder != NULL ) { if( EQUAL(pszByteOrder,"LSB") ) bNative = CPL_TO_BOOL(CPL_IS_LSB); else if( EQUAL(pszByteOrder,"MSB") ) bNative = !CPL_IS_LSB; else { CPLError( CE_Failure, CPLE_AppDefined, "Illegal ByteOrder value '%s', should be LSB or MSB.", pszByteOrder ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Create a corresponding RawRasterBand. */ /* -------------------------------------------------------------------- */ m_poRawRaster = new RawRasterBand( fp, nImageOffset, nPixelOffset, nLineOffset, GetRasterDataType(), bNative, GetXSize(), GetYSize(), TRUE ); /* -------------------------------------------------------------------- */ /* Reset block size to match the raw raster. */ /* -------------------------------------------------------------------- */ m_poRawRaster->GetBlockSize( &nBlockXSize, &nBlockYSize ); return CE_None; }
CPLErr VRTRawRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath, void* pUniqueHandle, std::map<CPLString, GDALDataset*>& oMapSharedSources ) { const CPLErr eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath, pUniqueHandle, oMapSharedSources ); if( eErr != CE_None ) return eErr; /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == nullptr || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue, "VRTRasterBand") || !EQUAL(CPLGetXMLValue(psTree,"subClass",""), "VRTRawRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRawRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ const char *pszFilename = CPLGetXMLValue(psTree, "SourceFilename", nullptr); if( pszFilename == nullptr ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in VRTRasterBand." ); return CE_Failure; } const bool l_bRelativeToVRT = CPLTestBool( CPLGetXMLValue( psTree, "SourceFilename.relativeToVRT", "1" )); /* -------------------------------------------------------------------- */ /* Collect layout information. */ /* -------------------------------------------------------------------- */ int nWordDataSize = GDALGetDataTypeSizeBytes( GetRasterDataType() ); const char* pszImageOffset = CPLGetXMLValue( psTree, "ImageOffset", "0"); const vsi_l_offset nImageOffset = CPLScanUIntBig( pszImageOffset, static_cast<int>(strlen(pszImageOffset)) ); int nPixelOffset = nWordDataSize; const char* pszPixelOffset = CPLGetXMLValue( psTree, "PixelOffset", nullptr ); if( pszPixelOffset != nullptr ) { nPixelOffset = atoi(pszPixelOffset); } if (nPixelOffset <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid value for <PixelOffset> element : %d", nPixelOffset ); return CE_Failure; } int nLineOffset = 0; const char* pszLineOffset = CPLGetXMLValue( psTree, "LineOffset", nullptr ); if( pszLineOffset == nullptr ) { if( nPixelOffset > INT_MAX / GetXSize() ) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow"); return CE_Failure; } nLineOffset = nPixelOffset * GetXSize(); } else nLineOffset = atoi(pszLineOffset); const char *pszByteOrder = CPLGetXMLValue( psTree, "ByteOrder", nullptr ); /* -------------------------------------------------------------------- */ /* Open the file, and setup the raw layer access to the data. */ /* -------------------------------------------------------------------- */ return SetRawLink( pszFilename, pszVRTPath, l_bRelativeToVRT, nImageOffset, nPixelOffset, nLineOffset, pszByteOrder ); }