/****************************************************************************** * $Id$ * * Project: Virtual GDAL Datasets * Purpose: Declaration of virtual gdal dataset classes. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007-2013, Even Rouault * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #ifndef VIRTUALDATASET_H_INCLUDED #define VIRTUALDATASET_H_INCLUDED #ifndef DOXYGEN_SKIP #include "cpl_hash_set.h" #include "cpl_minixml.h" #include "gdal_pam.h" #include "gdal_priv.h" #include "gdal_rat.h" #include "gdal_vrt.h" #include "gdal_rat.h" #include #include #include #include int VRTApplyMetadata(CPLXMLNode *, GDALMajorObject *); CPLXMLNode *VRTSerializeMetadata(GDALMajorObject *); CPLErr GDALRegisterDefaultPixelFunc(); CPLString VRTSerializeNoData(double dfVal, GDALDataType eDataType, int nPrecision); #if 0 int VRTWarpedOverviewTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ); void* VRTDeserializeWarpedOverviewTransformer( CPLXMLNode *psTree ); #endif /************************************************************************/ /* VRTOverviewInfo() */ /************************************************************************/ class VRTOverviewInfo { CPL_DISALLOW_COPY_ASSIGN(VRTOverviewInfo) public: CPLString osFilename{}; int nBand = 0; GDALRasterBand *poBand = nullptr; int bTriedToOpen = FALSE; VRTOverviewInfo() = default; VRTOverviewInfo(VRTOverviewInfo &&oOther) noexcept : osFilename(std::move(oOther.osFilename)), nBand(oOther.nBand), poBand(oOther.poBand), bTriedToOpen(oOther.bTriedToOpen) { oOther.poBand = nullptr; } ~VRTOverviewInfo() { CloseDataset(); } bool CloseDataset() { if (poBand == nullptr) return false; GDALDataset *poDS = poBand->GetDataset(); // Nullify now, to prevent recursion in some cases ! poBand = nullptr; if (poDS->GetShared()) GDALClose(/* (GDALDatasetH) */ poDS); else poDS->Dereference(); return true; } }; /************************************************************************/ /* VRTSource */ /************************************************************************/ class CPL_DLL VRTSource { public: virtual ~VRTSource(); virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) = 0; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) = 0; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) = 0; virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) = 0; virtual CPLErr XMLInit(CPLXMLNode *psTree, const char *, std::map &) = 0; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) = 0; virtual void GetFileList(char ***ppapszFileList, int *pnSize, int *pnMaxSize, CPLHashSet *hSetFiles); virtual int IsSimpleSource() { return FALSE; } virtual CPLErr FlushCache(bool /*bAtClosing*/) { return CE_None; } }; typedef VRTSource *(*VRTSourceParser)( CPLXMLNode *, const char *, std::map &oMapSharedSources); VRTSource * VRTParseCoreSources(CPLXMLNode *psTree, const char *, std::map &oMapSharedSources); VRTSource * VRTParseFilterSources(CPLXMLNode *psTree, const char *, std::map &oMapSharedSources); /************************************************************************/ /* VRTDataset */ /************************************************************************/ class VRTRasterBand; template struct VRTFlushCacheStruct { static void FlushCache(T &obj, bool bAtClosing); }; class VRTWarpedDataset; class VRTPansharpenedDataset; class VRTGroup; class CPL_DLL VRTDataset CPL_NON_FINAL : public GDALDataset { friend class VRTRasterBand; friend struct VRTFlushCacheStruct; friend struct VRTFlushCacheStruct; friend struct VRTFlushCacheStruct; friend class VRTSourcedRasterBand; friend VRTDatasetH CPL_STDCALL VRTCreate(int nXSize, int nYSize); OGRSpatialReference *m_poSRS = nullptr; int m_bGeoTransformSet = false; double m_adfGeoTransform[6]; int m_nGCPCount = 0; GDAL_GCP *m_pasGCPList = nullptr; OGRSpatialReference *m_poGCP_SRS = nullptr; bool m_bNeedsFlush = false; bool m_bWritable = true; bool m_bCanTakeRef = true; char *m_pszVRTPath = nullptr; VRTRasterBand *m_poMaskBand = nullptr; int m_bCompatibleForDatasetIO = -1; int CheckCompatibleForDatasetIO(); // Virtual (ie not materialized) overviews, created either implicitly // when it is cheap to do it, or explicitly. std::vector m_apoOverviews{}; std::vector m_apoOverviewsBak{}; CPLString m_osOverviewResampling{}; std::vector m_anOverviewFactors{}; char **m_papszXMLVRTMetadata = nullptr; std::map m_oMapSharedSources{}; std::shared_ptr m_poRootGroup{}; VRTRasterBand *InitBand(const char *pszSubclass, int nBand, bool bAllowPansharpened); static GDALDataset *OpenVRTProtocol(const char *pszSpec); bool AddVirtualOverview(int nOvFactor, const char *pszResampling); CPL_DISALLOW_COPY_ASSIGN(VRTDataset) protected: virtual int CloseDependentDatasets() override; public: VRTDataset(int nXSize, int nYSize); virtual ~VRTDataset(); void SetNeedsFlush() { m_bNeedsFlush = true; } virtual void FlushCache(bool bAtClosing) override; void SetWritable(int bWritableIn) { m_bWritable = CPL_TO_BOOL(bWritableIn); } virtual CPLErr CreateMaskBand(int nFlags) override; void SetMaskBand(VRTRasterBand *poMaskBand); const OGRSpatialReference *GetSpatialRef() const override { return m_poSRS; } CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override; virtual CPLErr GetGeoTransform(double *) override; virtual CPLErr SetGeoTransform(double *) override; virtual CPLErr SetMetadata(char **papszMetadata, const char *pszDomain = "") override; virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; virtual char **GetMetadata(const char *pszDomain = "") override; virtual int GetGCPCount() override; const OGRSpatialReference *GetGCPSpatialRef() const override { return m_poGCP_SRS; } virtual const GDAL_GCP *GetGCPs() override; using GDALDataset::SetGCPs; CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList, const OGRSpatialReference *poSRS) override; virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr) override; virtual char **GetFileList() override; virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize, GDALDataType eDT, int nBandCount, int *panBandList, char **papszOptions) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath); virtual CPLErr XMLInit(CPLXMLNode *, const char *); virtual CPLErr IBuildOverviews(const char *, int, const int *, int, const int *, GDALProgressFunc, void *, CSLConstList papszOptions) override; std::shared_ptr GetRootGroup() const override; /* Used by PDF driver for example */ GDALDataset *GetSingleSimpleSource(); void BuildVirtualOverviews(); void UnsetPreservedRelativeFilenames(); static int Identify(GDALOpenInfo *); static GDALDataset *Open(GDALOpenInfo *); static GDALDataset *OpenXML(const char *, const char * = nullptr, GDALAccess eAccess = GA_ReadOnly); static GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions); static GDALDataset * CreateMultiDimensional(const char *pszFilename, CSLConstList papszRootGroupOptions, CSLConstList papszOptions); static CPLErr Delete(const char *pszFilename); }; /************************************************************************/ /* VRTWarpedDataset */ /************************************************************************/ class GDALWarpOperation; class VRTWarpedRasterBand; class CPL_DLL VRTWarpedDataset final : public VRTDataset { int m_nBlockXSize; int m_nBlockYSize; GDALWarpOperation *m_poWarper; int m_nOverviewCount; VRTWarpedDataset **m_papoOverviews; int m_nSrcOvrLevel; void CreateImplicitOverviews(); friend class VRTWarpedRasterBand; CPL_DISALLOW_COPY_ASSIGN(VRTWarpedDataset) protected: virtual int CloseDependentDatasets() override; public: VRTWarpedDataset(int nXSize, int nYSize); virtual ~VRTWarpedDataset(); virtual void FlushCache(bool bAtClosing) override; CPLErr Initialize(/* GDALWarpOptions */ void *); virtual CPLErr IBuildOverviews(const char *, int, const int *, int, const int *, GDALProgressFunc, void *, CSLConstList papszOptions) override; virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr XMLInit(CPLXMLNode *, const char *) override; virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr) override; virtual char **GetFileList() override; CPLErr ProcessBlock(int iBlockX, int iBlockY); void GetBlockSize(int *, int *) const; }; /************************************************************************/ /* VRTPansharpenedDataset */ /************************************************************************/ class GDALPansharpenOperation; typedef enum { GTAdjust_Union, GTAdjust_Intersection, GTAdjust_None, GTAdjust_NoneWithoutWarning } GTAdjustment; class VRTPansharpenedDataset final : public VRTDataset { friend class VRTPansharpenedRasterBand; int m_nBlockXSize; int m_nBlockYSize; GDALPansharpenOperation *m_poPansharpener; VRTPansharpenedDataset *m_poMainDataset; std::vector m_apoOverviewDatasets{}; // Map from absolute to relative. std::map m_oMapToRelativeFilenames{}; int m_bLoadingOtherBands; GByte *m_pabyLastBufferBandRasterIO; int m_nLastBandRasterIOXOff; int m_nLastBandRasterIOYOff; int m_nLastBandRasterIOXSize; int m_nLastBandRasterIOYSize; GDALDataType m_eLastBandRasterIODataType; GTAdjustment m_eGTAdjustment; int m_bNoDataDisabled; std::vector m_apoDatasetsToClose{}; CPL_DISALLOW_COPY_ASSIGN(VRTPansharpenedDataset) protected: virtual int CloseDependentDatasets() override; public: VRTPansharpenedDataset(int nXSize, int nYSize); virtual ~VRTPansharpenedDataset(); virtual void FlushCache(bool bAtClosing) override; virtual CPLErr XMLInit(CPLXMLNode *, const char *) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; CPLErr XMLInit(CPLXMLNode *psTree, const char *pszVRTPath, GDALRasterBandH hPanchroBandIn, int nInputSpectralBandsIn, GDALRasterBandH *pahInputSpectralBandsIn); virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr) override; virtual char **GetFileList() override; virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, GDALRasterIOExtraArg *psExtraArg) override; void GetBlockSize(int *, int *) const; GDALPansharpenOperation *GetPansharpener() { return m_poPansharpener; } }; /************************************************************************/ /* VRTRasterBand */ /* */ /* Provides support for all the various kinds of metadata but */ /* no raster access. That is handled by derived classes. */ /************************************************************************/ constexpr double VRT_DEFAULT_NODATA_VALUE = -10000.0; class CPL_DLL VRTRasterBand CPL_NON_FINAL : public GDALRasterBand { private: void ResetNoDataValues(); protected: friend class VRTDataset; int m_bIsMaskBand = FALSE; int m_bNoDataValueSet = FALSE; // If set to true, will not report the existence of nodata. int m_bHideNoDataValue = FALSE; double m_dfNoDataValue = VRT_DEFAULT_NODATA_VALUE; bool m_bNoDataSetAsInt64 = false; int64_t m_nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64; bool m_bNoDataSetAsUInt64 = false; uint64_t m_nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64; std::unique_ptr m_poColorTable{}; GDALColorInterp m_eColorInterp = GCI_Undefined; char *m_pszUnitType = nullptr; char **m_papszCategoryNames = nullptr; double m_dfOffset = 0.0; double m_dfScale = 1.0; CPLXMLNode *m_psSavedHistograms = nullptr; void Initialize(int nXSize, int nYSize); std::vector m_aoOverviewInfos{}; VRTRasterBand *m_poMaskBand = nullptr; std::unique_ptr m_poRAT{}; CPL_DISALLOW_COPY_ASSIGN(VRTRasterBand) bool IsNoDataValueInDataTypeRange() const; public: VRTRasterBand(); virtual ~VRTRasterBand(); virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &); virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath); CPLErr SetNoDataValue(double) override; CPLErr SetNoDataValueAsInt64(int64_t nNoData) override; CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override; double GetNoDataValue(int *pbSuccess = nullptr) override; int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override; uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override; CPLErr DeleteNoDataValue() override; virtual CPLErr SetColorTable(GDALColorTable *) override; virtual GDALColorTable *GetColorTable() override; virtual GDALRasterAttributeTable *GetDefaultRAT() override; virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT) override; virtual CPLErr SetColorInterpretation(GDALColorInterp) override; virtual GDALColorInterp GetColorInterpretation() override; virtual const char *GetUnitType() override; CPLErr SetUnitType(const char *) override; virtual char **GetCategoryNames() override; virtual CPLErr SetCategoryNames(char **) override; virtual CPLErr SetMetadata(char **papszMD, const char *pszDomain = "") override; virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; virtual double GetOffset(int *pbSuccess = nullptr) override; CPLErr SetOffset(double) override; virtual double GetScale(int *pbSuccess = nullptr) override; CPLErr SetScale(double) override; virtual int GetOverviewCount() override; virtual GDALRasterBand *GetOverview(int) override; virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc, void *pProgressData) override; virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets, GUIntBig **ppanHistogram, int bForce, GDALProgressFunc, void *pProgressData) override; virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram) override; CPLErr CopyCommonInfoFrom(GDALRasterBand *); virtual void GetFileList(char ***ppapszFileList, int *pnSize, int *pnMaxSize, CPLHashSet *hSetFiles); virtual void SetDescription(const char *) override; virtual GDALRasterBand *GetMaskBand() override; virtual int GetMaskFlags() override; virtual CPLErr CreateMaskBand(int nFlagsIn) override; void SetMaskBand(VRTRasterBand *poMaskBand); void SetIsMaskBand(); virtual bool IsMaskBand() const override; CPLErr UnsetNoDataValue(); virtual int CloseDependentDatasets(); virtual int IsSourcedRasterBand() { return FALSE; } virtual int IsPansharpenRasterBand() { return FALSE; } }; /************************************************************************/ /* VRTSourcedRasterBand */ /************************************************************************/ class VRTSimpleSource; class CPL_DLL VRTSourcedRasterBand CPL_NON_FINAL : public VRTRasterBand { private: CPLString m_osLastLocationInfo{}; char **m_papszSourceList = nullptr; int m_nSkipBufferInitialization = -1; bool CanUseSourcesMinMaxImplementations(); bool IsMosaicOfNonOverlappingSimpleSourcesOfFullRasterNoResAndTypeChange( bool bAllowMaxValAdjustment) const; CPL_DISALLOW_COPY_ASSIGN(VRTSourcedRasterBand) protected: bool SkipBufferInitialization(); public: int nSources = 0; VRTSource **papoSources = nullptr; VRTSourcedRasterBand(GDALDataset *poDS, int nBand); VRTSourcedRasterBand(GDALDataType eType, int nXSize, int nYSize); VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType, int nXSize, int nYSize); VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType, int nXSize, int nYSize, int nBlockXSizeIn, int nBlockYSizeIn); virtual ~VRTSourcedRasterBand(); virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize, int nMaskFlagStop, double *pdfDataPct) override; virtual char **GetMetadataDomainList() override; virtual const char *GetMetadataItem(const char *pszName, const char *pszDomain = "") override; virtual char **GetMetadata(const char *pszDomain = "") override; virtual CPLErr SetMetadata(char **papszMetadata, const char *pszDomain = "") override; virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual double GetMinimum(int *pbSuccess = nullptr) override; virtual double GetMaximum(int *pbSuccess = nullptr) override; virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax) override; virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax, double *pdfMean, double *pdfStdDev, GDALProgressFunc pfnProgress, void *pProgressData) override; virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; CPLErr AddSource(VRTSource *); CPLErr AddSimpleSource(const char *pszFilename, int nBand, double dfSrcXOff = -1, double dfSrcYOff = -1, double dfSrcXSize = -1, double dfSrcYSize = -1, double dfDstXOff = -1, double dfDstYOff = -1, double dfDstXSize = -1, double dfDstYSize = -1, const char *pszResampling = "near", double dfNoDataValue = VRT_NODATA_UNSET); CPLErr AddSimpleSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1, double dfSrcYOff = -1, double dfSrcXSize = -1, double dfSrcYSize = -1, double dfDstXOff = -1, double dfDstYOff = -1, double dfDstXSize = -1, double dfDstYSize = -1, const char *pszResampling = "near", double dfNoDataValue = VRT_NODATA_UNSET); CPLErr AddComplexSource(const char *pszFilename, int nBand, double dfSrcXOff = -1, double dfSrcYOff = -1, double dfSrcXSize = -1, double dfSrcYSize = -1, double dfDstXOff = -1, double dfDstYOff = -1, double dfDstXSize = -1, double dfDstYSize = -1, double dfScaleOff = 0.0, double dfScaleRatio = 1.0, double dfNoDataValue = VRT_NODATA_UNSET, int nColorTableComponent = 0); CPLErr AddComplexSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1, double dfSrcYOff = -1, double dfSrcXSize = -1, double dfSrcYSize = -1, double dfDstXOff = -1, double dfDstYOff = -1, double dfDstXSize = -1, double dfDstYSize = -1, double dfScaleOff = 0.0, double dfScaleRatio = 1.0, double dfNoDataValue = VRT_NODATA_UNSET, int nColorTableComponent = 0); CPLErr AddMaskBandSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1, double dfSrcYOff = -1, double dfSrcXSize = -1, double dfSrcYSize = -1, double dfDstXOff = -1, double dfDstYOff = -1, double dfDstXSize = -1, double dfDstYSize = -1); CPLErr AddFuncSource(VRTImageReadFunc pfnReadFunc, void *hCBData, double dfNoDataValue = VRT_NODATA_UNSET); void ConfigureSource(VRTSimpleSource *poSimpleSource, GDALRasterBand *poSrcBand, int bAddAsMaskBand, double dfSrcXOff, double dfSrcYOff, double dfSrcXSize, double dfSrcYSize, double dfDstXOff, double dfDstYOff, double dfDstXSize, double dfDstYSize); void RemoveCoveredSources(CSLConstList papszOptions = nullptr); virtual CPLErr IReadBlock(int, int, void *) override; virtual void GetFileList(char ***ppapszFileList, int *pnSize, int *pnMaxSize, CPLHashSet *hSetFiles) override; virtual int CloseDependentDatasets() override; virtual int IsSourcedRasterBand() override { return TRUE; } virtual CPLErr FlushCache(bool bAtClosing) override; }; /************************************************************************/ /* VRTWarpedRasterBand */ /************************************************************************/ class CPL_DLL VRTWarpedRasterBand final : public VRTRasterBand { public: VRTWarpedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType = GDT_Unknown); virtual ~VRTWarpedRasterBand(); virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr IReadBlock(int, int, void *) override; virtual CPLErr IWriteBlock(int, int, void *) override; virtual int GetOverviewCount() override; virtual GDALRasterBand *GetOverview(int) override; }; /************************************************************************/ /* VRTPansharpenedRasterBand */ /************************************************************************/ class VRTPansharpenedRasterBand final : public VRTRasterBand { int m_nIndexAsPansharpenedBand; public: VRTPansharpenedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eDataType = GDT_Unknown); virtual ~VRTPansharpenedRasterBand(); virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr IReadBlock(int, int, void *) override; virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual int GetOverviewCount() override; virtual GDALRasterBand *GetOverview(int) override; virtual int IsPansharpenRasterBand() override { return TRUE; } void SetIndexAsPansharpenedBand(int nIdx) { m_nIndexAsPansharpenedBand = nIdx; } int GetIndexAsPansharpenedBand() const { return m_nIndexAsPansharpenedBand; } }; /************************************************************************/ /* VRTDerivedRasterBand */ /************************************************************************/ class VRTDerivedRasterBandPrivateData; class CPL_DLL VRTDerivedRasterBand CPL_NON_FINAL : public VRTSourcedRasterBand { VRTDerivedRasterBandPrivateData *m_poPrivate; bool InitializePython(); CPLErr GetPixelFunctionArguments(const CPLString &, std::vector> &); CPL_DISALLOW_COPY_ASSIGN(VRTDerivedRasterBand) public: char *pszFuncName; GDALDataType eSourceTransferType; using PixelFunc = std::function; VRTDerivedRasterBand(GDALDataset *poDS, int nBand); VRTDerivedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType, int nXSize, int nYSize); virtual ~VRTDerivedRasterBand(); virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize, int nMaskFlagStop, double *pdfDataPct) override; static CPLErr AddPixelFunction(const char *pszFuncNameIn, GDALDerivedPixelFunc pfnPixelFunc); static CPLErr AddPixelFunction(const char *pszFuncNameIn, GDALDerivedPixelFuncWithArgs pfnPixelFunc, const char *pszMetadata); static std::pair * GetPixelFunction(const char *pszFuncNameIn); void SetPixelFunctionName(const char *pszFuncNameIn); void SetSourceTransferType(GDALDataType eDataType); void SetPixelFunctionLanguage(const char *pszLanguage); virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual double GetMinimum(int *pbSuccess = nullptr) override; virtual double GetMaximum(int *pbSuccess = nullptr) override; virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax) override; virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax, double *pdfMean, double *pdfStdDev, GDALProgressFunc pfnProgress, void *pProgressData) override; virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; static void Cleanup(); }; /************************************************************************/ /* VRTRawRasterBand */ /************************************************************************/ class RawRasterBand; class CPL_DLL VRTRawRasterBand CPL_NON_FINAL : public VRTRasterBand { RawRasterBand *m_poRawRaster; char *m_pszSourceFilename; int m_bRelativeToVRT; CPL_DISALLOW_COPY_ASSIGN(VRTRawRasterBand) public: VRTRawRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType = GDT_Unknown); virtual ~VRTRawRasterBand(); virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual CPLErr IReadBlock(int, int, void *) override; virtual CPLErr IWriteBlock(int, int, void *) override; CPLErr SetRawLink(const char *pszFilename, const char *pszVRTPath, int bRelativeToVRT, vsi_l_offset nImageOffset, int nPixelOffset, int nLineOffset, const char *pszByteOrder); void ClearRawLink(); CPLVirtualMem *GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace, GIntBig *pnLineSpace, char **papszOptions) override; virtual void GetFileList(char ***ppapszFileList, int *pnSize, int *pnMaxSize, CPLHashSet *hSetFiles) override; }; /************************************************************************/ /* VRTDriver */ /************************************************************************/ class VRTDriver final : public GDALDriver { CPL_DISALLOW_COPY_ASSIGN(VRTDriver) std::map m_oMapSourceParser{}; public: VRTDriver(); virtual ~VRTDriver(); char **papszSourceParsers; virtual char **GetMetadataDomainList() override; virtual char **GetMetadata(const char *pszDomain = "") override; virtual CPLErr SetMetadata(char **papszMetadata, const char *pszDomain = "") override; VRTSource * ParseSource(CPLXMLNode *psSrc, const char *pszVRTPath, std::map &oMapSharedSources); void AddSourceParser(const char *pszElementName, VRTSourceParser pfnParser); }; /************************************************************************/ /* VRTSimpleSource */ /************************************************************************/ class CPL_DLL VRTSimpleSource CPL_NON_FINAL : public VRTSource { CPL_DISALLOW_COPY_ASSIGN(VRTSimpleSource) private: // Owned by the VRTDataset std::map *m_poMapSharedSources = nullptr; mutable GDALRasterBand *m_poRasterBand = nullptr; // When poRasterBand is a mask band, poMaskBandMainBand is the band // from which the mask band is taken. mutable GDALRasterBand *m_poMaskBandMainBand = nullptr; CPLStringList m_aosOpenOptions{}; void OpenSource() const; protected: friend class VRTSourcedRasterBand; friend class VRTDataset; int m_nBand = 0; bool m_bGetMaskBand = false; double m_dfSrcXOff = 0; double m_dfSrcYOff = 0; double m_dfSrcXSize = 0; double m_dfSrcYSize = 0; double m_dfDstXOff = 0; double m_dfDstYOff = 0; double m_dfDstXSize = 0; double m_dfDstYSize = 0; CPLString m_osResampling{}; int m_nMaxValue = 0; int m_bRelativeToVRTOri = -1; CPLString m_osSourceFileNameOri{}; int m_nExplicitSharedStatus = -1; // -1 unknown, 0 = unshared, 1 = shared CPLString m_osSrcDSName{}; bool m_bDropRefOnSrcBand = true; int NeedMaxValAdjustment() const; GDALRasterBand *GetRasterBandNoOpen() const { return m_poRasterBand; } virtual bool ValidateOpenedBand(GDALRasterBand * /*poBand*/) const { return true; } public: VRTSimpleSource(); VRTSimpleSource(const VRTSimpleSource *poSrcSource, double dfXDstRatio, double dfYDstRatio); virtual ~VRTSimpleSource(); virtual CPLErr XMLInit(CPLXMLNode *psTree, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; void SetSrcBand(const char *pszFilename, int nBand); void SetSrcBand(GDALRasterBand *); void SetSrcMaskBand(GDALRasterBand *); void SetSrcWindow(double, double, double, double); void SetDstWindow(double, double, double, double); const CPLString &GetResampling() const { return m_osResampling; } void SetResampling(const char *pszResampling); int GetSrcDstWindow(double, double, double, double, int, int, double *pdfReqXOff, double *pdfReqYOff, double *pdfReqXSize, double *pdfReqYSize, int *, int *, int *, int *, int *, int *, int *, int *, bool &bErrorOut); virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArgIn) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; void DstToSrc(double dfX, double dfY, double &dfXOut, double &dfYOut) const; void SrcToDst(double dfX, double dfY, double &dfXOut, double &dfYOut) const; virtual void GetFileList(char ***ppapszFileList, int *pnSize, int *pnMaxSize, CPLHashSet *hSetFiles) override; virtual int IsSimpleSource() override { return TRUE; } virtual const char *GetType() { return "SimpleSource"; } virtual CPLErr FlushCache(bool bAtClosing) override; GDALRasterBand *GetRasterBand() const; GDALRasterBand *GetMaskBandMainBand(); int IsSameExceptBandNumber(VRTSimpleSource *poOtherSource); CPLErr DatasetRasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, GDALRasterIOExtraArg *psExtraArg); void UnsetPreservedRelativeFilenames(); void SetMaxValue(int nVal) { m_nMaxValue = nVal; } }; /************************************************************************/ /* VRTAveragedSource */ /************************************************************************/ class VRTAveragedSource final : public VRTSimpleSource { CPL_DISALLOW_COPY_ASSIGN(VRTAveragedSource) int m_bNoDataSet = false; double m_dfNoDataValue = VRT_NODATA_UNSET; public: VRTAveragedSource(); virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArgIn) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; void SetNoDataValue(double dfNoDataValue); virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual const char *GetType() override { return "AveragedSource"; } }; /************************************************************************/ /* VRTComplexSource */ /************************************************************************/ typedef enum { VRT_SCALING_NONE, VRT_SCALING_LINEAR, VRT_SCALING_EXPONENTIAL, } VRTComplexSourceScaling; class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource { CPL_DISALLOW_COPY_ASSIGN(VRTComplexSource) protected: int m_bNoDataSet = false; // adjusted value should be read with GetAdjustedNoDataValue() double m_dfNoDataValue = VRT_NODATA_UNSET; std::string m_osNoDataValueOri{}; // string value read in XML deserialization VRTComplexSourceScaling m_eScalingType = VRT_SCALING_NONE; double m_dfScaleOff = 0; // For linear scaling. double m_dfScaleRatio = 1; // For linear scaling. // For non-linear scaling with a power function. int m_bSrcMinMaxDefined = FALSE; double m_dfSrcMin = 0; double m_dfSrcMax = 0; double m_dfDstMin = 0; double m_dfDstMax = 0; double m_dfExponent = 1; int m_nColorTableComponent = 0; bool m_bUseMaskBand = false; double *m_padfLUTInputs = nullptr; double *m_padfLUTOutputs = nullptr; int m_nLUTItemCount = 0; double GetAdjustedNoDataValue() const; template CPLErr RasterIOInternal(int nReqXOff, int nReqYOff, int nReqXSize, int nReqYSize, void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, GDALDataType eWrkDataType); public: VRTComplexSource(); VRTComplexSource(const VRTComplexSource *poSrcSource, double dfXDstRatio, double dfYDstRatio); virtual ~VRTComplexSource(); virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArgIn) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &) override; virtual const char *GetType() override { return "ComplexSource"; } bool AreValuesUnchanged() const; double LookupValue(double dfInput); void SetNoDataValue(double dfNoDataValue); void SetUseMaskBand(bool bUseMaskBand) { m_bUseMaskBand = bUseMaskBand; } void SetLinearScaling(double dfOffset, double dfScale); void SetPowerScaling(double dfExponent, double dfSrcMin, double dfSrcMax, double dfDstMin, double dfDstMax); void SetColorTableComponent(int nComponent); }; /************************************************************************/ /* VRTFilteredSource */ /************************************************************************/ class VRTFilteredSource CPL_NON_FINAL : public VRTComplexSource { private: int IsTypeSupported(GDALDataType eTestType) const; CPL_DISALLOW_COPY_ASSIGN(VRTFilteredSource) protected: int m_nSupportedTypesCount; GDALDataType m_aeSupportedTypes[20]; int m_nExtraEdgePixels; public: VRTFilteredSource(); virtual ~VRTFilteredSource(); void SetExtraEdgePixels(int); void SetFilteringDataTypesSupported(int, GDALDataType *); virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType, GByte *pabySrcData, GByte *pabyDstData) = 0; virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; }; /************************************************************************/ /* VRTKernelFilteredSource */ /************************************************************************/ class VRTKernelFilteredSource CPL_NON_FINAL : public VRTFilteredSource { CPL_DISALLOW_COPY_ASSIGN(VRTKernelFilteredSource) protected: int m_nKernelSize; bool m_bSeparable; double *m_padfKernelCoefs; int m_bNormalized; public: VRTKernelFilteredSource(); virtual ~VRTKernelFilteredSource(); virtual CPLErr XMLInit(CPLXMLNode *psTree, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType, GByte *pabySrcData, GByte *pabyDstData) override; CPLErr SetKernel(int nKernelSize, bool bSeparable, double *padfCoefs); void SetNormalized(int); }; /************************************************************************/ /* VRTAverageFilteredSource */ /************************************************************************/ class VRTAverageFilteredSource final : public VRTKernelFilteredSource { CPL_DISALLOW_COPY_ASSIGN(VRTAverageFilteredSource) public: explicit VRTAverageFilteredSource(int nKernelSize); virtual ~VRTAverageFilteredSource(); virtual CPLErr XMLInit(CPLXMLNode *psTree, const char *, std::map &) override; virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; }; /************************************************************************/ /* VRTFuncSource */ /************************************************************************/ class VRTFuncSource final : public VRTSource { CPL_DISALLOW_COPY_ASSIGN(VRTFuncSource) public: VRTFuncSource(); virtual ~VRTFuncSource(); virtual CPLErr XMLInit(CPLXMLNode *, const char *, std::map &) override { return CE_Failure; } virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override; virtual CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData) override; VRTImageReadFunc pfnReadFunc; void *pCBData; GDALDataType eType; float fNoDataValue; }; /************************************************************************/ /* VRTGroup */ /************************************************************************/ #ifdef TMPEXPORT #define TMP_CPL_DLL CPL_DLL #else #define TMP_CPL_DLL #endif class VRTMDArray; class VRTAttribute; class VRTDimension; class VRTGroup final : public GDALGroup { public: struct Ref { VRTGroup *m_ptr; explicit Ref(VRTGroup *ptr) : m_ptr(ptr) { } Ref(const Ref &) = delete; Ref &operator=(const Ref &) = delete; }; private: std::shared_ptr m_poSharedRefRootGroup{}; std::weak_ptr m_poWeakRefRootGroup{}; std::shared_ptr m_poRefSelf{}; std::string m_osFilename{}; mutable bool m_bDirty = false; std::string m_osVRTPath{}; std::map> m_oMapGroups{}; std::map> m_oMapMDArrays{}; std::map> m_oMapAttributes{}; std::map> m_oMapDimensions{}; std::shared_ptr OpenGroupInternal(const std::string &osName) const; void SetRootGroupRef(const std::weak_ptr &rgRef); std::weak_ptr GetRootGroupRef() const; public: VRTGroup(const std::string &osParentName, const std::string &osName); ~VRTGroup(); bool XMLInit(const std::shared_ptr &poRoot, const std::shared_ptr &poThisGroup, const CPLXMLNode *psNode, const char *pszVRTPath); std::vector GetMDArrayNames(CSLConstList papszOptions) const override; std::shared_ptr OpenMDArray(const std::string &osName, CSLConstList papszOptions = nullptr) const override; std::vector GetGroupNames(CSLConstList papszOptions) const override; std::shared_ptr OpenGroup(const std::string &osName, CSLConstList) const override { return OpenGroupInternal(osName); } std::vector> GetDimensions(CSLConstList) const override; std::vector> GetAttributes(CSLConstList) const override; std::shared_ptr GetDimension(const std::string &name) const { auto oIter = m_oMapDimensions.find(name); return oIter == m_oMapDimensions.end() ? nullptr : oIter->second; } std::shared_ptr GetDimensionFromFullName(const std::string &name, bool bEmitError) const; std::shared_ptr CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr) override; std::shared_ptr CreateDimension(const std::string &osName, const std::string &osType, const std::string &osDirection, GUInt64 nSize, CSLConstList papszOptions = nullptr) override; std::shared_ptr CreateAttribute(const std::string &osName, const std::vector &anDimensions, const GDALExtendedDataType &oDataType, CSLConstList papszOptions = nullptr) override; std::shared_ptr CreateMDArray( const std::string &osName, const std::vector> &aoDimensions, const GDALExtendedDataType &oDataType, CSLConstList papszOptions) override; void SetIsRootGroup(); const std::shared_ptr &GetRef() const { return m_poRefSelf; } VRTGroup *GetRootGroup() const; const std::string &GetVRTPath() const { return m_osVRTPath; } void SetDirty(); void SetFilename(const std::string &osFilename) { m_osFilename = osFilename; } const std::string &GetFilename() const { return m_osFilename; } void Serialize() const; CPLXMLNode *SerializeToXML(const char *pszVRTPathIn) const; void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const; }; /************************************************************************/ /* VRTDimension */ /************************************************************************/ class VRTDimension final : public GDALDimension { std::weak_ptr m_poGroupRef; std::string m_osIndexingVariableName; public: VRTDimension(const std::shared_ptr &poGroupRef, const std::string &osParentName, const std::string &osName, const std::string &osType, const std::string &osDirection, GUInt64 nSize, const std::string &osIndexingVariableName) : GDALDimension(osParentName, osName, osType, osDirection, nSize), m_poGroupRef(poGroupRef), m_osIndexingVariableName(osIndexingVariableName) { } VRTGroup *GetGroup() const; static std::shared_ptr Create(const std::shared_ptr &poThisGroup, const std::string &osParentName, const CPLXMLNode *psNode); std::shared_ptr GetIndexingVariable() const override; bool SetIndexingVariable( std::shared_ptr poIndexingVariable) override; void Serialize(CPLXMLNode *psParent) const; }; /************************************************************************/ /* VRTAttribute */ /************************************************************************/ class VRTAttribute final : public GDALAttribute { GDALExtendedDataType m_dt; std::vector m_aosList{}; std::vector> m_dims{}; protected: bool IRead(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const override; bool IWrite(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer) override; public: VRTAttribute(const std::string &osParentName, const std::string &osName, const GDALExtendedDataType &dt, std::vector &&aosList) : GDALAbstractMDArray(osParentName, osName), GDALAttribute(osParentName, osName), m_dt(dt), m_aosList(std::move(aosList)) { if (m_aosList.size() > 1) { m_dims.emplace_back(std::make_shared( std::string(), "dim", std::string(), std::string(), m_aosList.size())); } } VRTAttribute(const std::string &osParentName, const std::string &osName, GUInt64 nDim, const GDALExtendedDataType &dt) : GDALAbstractMDArray(osParentName, osName), GDALAttribute(osParentName, osName), m_dt(dt) { if (nDim != 0) { m_dims.emplace_back(std::make_shared( std::string(), "dim", std::string(), std::string(), nDim)); } } static bool CreationCommonChecks( const std::string &osName, const std::vector &anDimensions, const std::map> &oMapAttributes); static std::shared_ptr Create(const std::string &osParentName, const CPLXMLNode *psNode); const std::vector> & GetDimensions() const override { return m_dims; } const GDALExtendedDataType &GetDataType() const override { return m_dt; } void Serialize(CPLXMLNode *psParent) const; }; /************************************************************************/ /* VRTMDArraySource */ /************************************************************************/ class VRTMDArraySource { public: virtual ~VRTMDArraySource() = default; virtual bool Read(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const = 0; virtual void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const = 0; }; /************************************************************************/ /* VRTMDArray */ /************************************************************************/ class VRTMDArray final : public GDALMDArray { protected: friend class VRTGroup; // for access to SetSelf() std::weak_ptr m_poGroupRef; std::string m_osVRTPath{}; GDALExtendedDataType m_dt; std::vector> m_dims; std::map> m_oMapAttributes{}; std::vector> m_sources{}; std::shared_ptr m_poSRS{}; std::vector m_abyNoData{}; std::string m_osUnit{}; double m_dfScale = 1.0; double m_dfOffset = 0.0; bool m_bHasScale = false; bool m_bHasOffset = false; std::string m_osFilename{}; bool IRead(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const override; void SetDirty(); public: VRTMDArray( const std::shared_ptr &poGroupRef, const std::string &osParentName, const std::string &osName, const GDALExtendedDataType &dt, std::vector> &&dims, std::map> &&oMapAttributes) : GDALAbstractMDArray(osParentName, osName), GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef), m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt), m_dims(std::move(dims)), m_oMapAttributes(std::move(oMapAttributes)), m_osFilename(poGroupRef->m_ptr->GetFilename()) { } VRTMDArray(const std::shared_ptr &poGroupRef, const std::string &osParentName, const std::string &osName, const std::vector> &dims, const GDALExtendedDataType &dt) : GDALAbstractMDArray(osParentName, osName), GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef), m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt), m_dims(dims), m_osFilename(poGroupRef->m_ptr->GetFilename()) { } bool IsWritable() const override { return false; } const std::string &GetFilename() const override { return m_osFilename; } static std::shared_ptr Create(const std::shared_ptr &poThisGroup, const std::string &osParentName, const CPLXMLNode *psNode); const std::vector> & GetDimensions() const override { return m_dims; } std::vector> GetAttributes(CSLConstList) const override; const GDALExtendedDataType &GetDataType() const override { return m_dt; } bool SetSpatialRef(const OGRSpatialReference *poSRS) override; std::shared_ptr GetSpatialRef() const override { return m_poSRS; } const void *GetRawNoDataValue() const override; bool SetRawNoDataValue(const void *pRawNoData) override; const std::string &GetUnit() const override { return m_osUnit; } bool SetUnit(const std::string &osUnit) override { m_osUnit = osUnit; return true; } double GetOffset(bool *pbHasOffset, GDALDataType *peStorageType) const override { if (pbHasOffset) *pbHasOffset = m_bHasOffset; if (peStorageType) *peStorageType = GDT_Unknown; return m_dfOffset; } double GetScale(bool *pbHasScale, GDALDataType *peStorageType) const override { if (pbHasScale) *pbHasScale = m_bHasScale; if (peStorageType) *peStorageType = GDT_Unknown; return m_dfScale; } bool SetOffset(double dfOffset, GDALDataType /* eStorageType */ = GDT_Unknown) override { SetDirty(); m_bHasOffset = true; m_dfOffset = dfOffset; return true; } bool SetScale(double dfScale, GDALDataType /* eStorageType */ = GDT_Unknown) override { SetDirty(); m_bHasScale = true; m_dfScale = dfScale; return true; } void AddSource(std::unique_ptr &&poSource); std::shared_ptr CreateAttribute(const std::string &osName, const std::vector &anDimensions, const GDALExtendedDataType &oDataType, CSLConstList papszOptions = nullptr) override; bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray, bool bStrict, GUInt64 &nCurCost, const GUInt64 nTotalCost, GDALProgressFunc pfnProgress, void *pProgressData) override; void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const; VRTGroup *GetGroup() const; const std::string &GetVRTPath() const { return m_osVRTPath; } }; /************************************************************************/ /* VRTMDArraySourceInlinedValues */ /************************************************************************/ class VRTMDArraySourceInlinedValues final : public VRTMDArraySource { const VRTMDArray *m_poDstArray = nullptr; bool m_bIsConstantValue; std::vector m_anOffset{}; std::vector m_anCount{}; std::vector m_abyValues{}; std::vector m_anInlinedArrayStrideInBytes{}; GDALExtendedDataType m_dt; VRTMDArraySourceInlinedValues(const VRTMDArraySourceInlinedValues &) = delete; VRTMDArraySourceInlinedValues & operator=(const VRTMDArraySourceInlinedValues &) = delete; public: VRTMDArraySourceInlinedValues(const VRTMDArray *poDstArray, bool bIsConstantValue, std::vector &&anOffset, std::vector &&anCount, std::vector &&abyValues) : m_poDstArray(poDstArray), m_bIsConstantValue(bIsConstantValue), m_anOffset(std::move(anOffset)), m_anCount(std::move(anCount)), m_abyValues(std::move(abyValues)), m_dt(poDstArray->GetDataType()) { const auto nDims(poDstArray->GetDimensionCount()); m_anInlinedArrayStrideInBytes.resize(nDims); if (!bIsConstantValue && nDims > 0) { m_anInlinedArrayStrideInBytes.back() = poDstArray->GetDataType().GetSize(); for (size_t i = nDims - 1; i > 0;) { --i; m_anInlinedArrayStrideInBytes[i] = m_anInlinedArrayStrideInBytes[i + 1] * m_anCount[i + 1]; } } } ~VRTMDArraySourceInlinedValues(); static std::unique_ptr Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode); bool Read(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const override; void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override; }; /************************************************************************/ /* VRTMDArraySourceRegularlySpaced */ /************************************************************************/ class VRTMDArraySourceRegularlySpaced final : public VRTMDArraySource { double m_dfStart; double m_dfIncrement; public: VRTMDArraySourceRegularlySpaced(double dfStart, double dfIncrement) : m_dfStart(dfStart), m_dfIncrement(dfIncrement) { } bool Read(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const override; void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override; }; /************************************************************************/ /* VRTMDArraySourceFromArray */ /************************************************************************/ class VRTMDArraySourceFromArray final : public VRTMDArraySource { const VRTMDArray *m_poDstArray = nullptr; bool m_bRelativeToVRTSet = false; bool m_bRelativeToVRT = false; std::string m_osFilename{}; std::string m_osArray{}; std::string m_osBand{}; std::vector m_anTransposedAxis{}; std::string m_osViewExpr{}; std::vector m_anSrcOffset{}; mutable std::vector m_anCount{}; std::vector m_anStep{}; std::vector m_anDstOffset{}; VRTMDArraySourceFromArray(const VRTMDArraySourceFromArray &) = delete; VRTMDArraySourceFromArray & operator=(const VRTMDArraySourceFromArray &) = delete; public: VRTMDArraySourceFromArray( const VRTMDArray *poDstArray, bool bRelativeToVRTSet, bool bRelativeToVRT, const std::string &osFilename, const std::string &osArray, const std::string &osBand, std::vector &&anTransposedAxis, const std::string &osViewExpr, std::vector &&anSrcOffset, std::vector &&anCount, std::vector &&anStep, std::vector &&anDstOffset) : m_poDstArray(poDstArray), m_bRelativeToVRTSet(bRelativeToVRTSet), m_bRelativeToVRT(bRelativeToVRT), m_osFilename(osFilename), m_osArray(osArray), m_osBand(osBand), m_anTransposedAxis(std::move(anTransposedAxis)), m_osViewExpr(osViewExpr), m_anSrcOffset(std::move(anSrcOffset)), m_anCount(std::move(anCount)), m_anStep(std::move(anStep)), m_anDstOffset(std::move(anDstOffset)) { } ~VRTMDArraySourceFromArray() override; static std::unique_ptr Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode); bool Read(const GUInt64 *arrayStartIdx, const size_t *count, const GInt64 *arrayStep, const GPtrDiff_t *bufferStride, const GDALExtendedDataType &bufferDataType, void *pDstBuffer) const override; void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override; }; #endif /* #ifndef DOXYGEN_SKIP */ #endif /* ndef VIRTUALDATASET_H_INCLUDED */