462 lines
16 KiB
C++
462 lines
16 KiB
C++
/******************************************************************************
|
|
* $Id$
|
|
*
|
|
* Project: GDAL Core
|
|
* Purpose: Declaration for Peristable Auxiliary Metadata classes.
|
|
* Author: Frank Warmerdam, warmerdam@pobox.com
|
|
*
|
|
******************************************************************************
|
|
* Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
****************************************************************************/
|
|
|
|
#ifndef GDAL_PAM_H_INCLUDED
|
|
#define GDAL_PAM_H_INCLUDED
|
|
|
|
//! @cond Doxygen_Suppress
|
|
|
|
#include "cpl_minixml.h"
|
|
#include "gdal_priv.h"
|
|
#include <array>
|
|
#include <limits>
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
class GDALPamRasterBand;
|
|
|
|
/* Clone Info Flags */
|
|
|
|
#define GCIF_GEOTRANSFORM 0x01
|
|
#define GCIF_PROJECTION 0x02
|
|
#define GCIF_METADATA 0x04
|
|
#define GCIF_GCPS 0x08
|
|
|
|
#define GCIF_NODATA 0x001000
|
|
#define GCIF_CATEGORYNAMES 0x002000
|
|
#define GCIF_MINMAX 0x004000
|
|
#define GCIF_SCALEOFFSET 0x008000
|
|
#define GCIF_UNITTYPE 0x010000
|
|
#define GCIF_COLORTABLE 0x020000
|
|
/* Same value as GCIF_COLORTABLE */
|
|
#define GCIF_COLORINTERP 0x020000
|
|
#define GCIF_BAND_METADATA 0x040000
|
|
#define GCIF_RAT 0x080000
|
|
#define GCIF_MASK 0x100000
|
|
#define GCIF_BAND_DESCRIPTION 0x200000
|
|
|
|
#define GCIF_ONLY_IF_MISSING 0x10000000
|
|
#define GCIF_PROCESS_BANDS 0x20000000
|
|
|
|
#define GCIF_PAM_DEFAULT \
|
|
(GCIF_GEOTRANSFORM | GCIF_PROJECTION | GCIF_METADATA | GCIF_GCPS | \
|
|
GCIF_NODATA | GCIF_CATEGORYNAMES | GCIF_MINMAX | GCIF_SCALEOFFSET | \
|
|
GCIF_UNITTYPE | GCIF_COLORTABLE | GCIF_BAND_METADATA | GCIF_RAT | \
|
|
GCIF_MASK | GCIF_ONLY_IF_MISSING | GCIF_PROCESS_BANDS | \
|
|
GCIF_BAND_DESCRIPTION)
|
|
|
|
/* GDAL PAM Flags */
|
|
/* ERO 2011/04/13 : GPF_AUXMODE seems to be unimplemented */
|
|
#define GPF_DIRTY 0x01 // .pam file needs to be written on close
|
|
#define GPF_TRIED_READ_FAILED 0x02 // no need to keep trying to read .pam.
|
|
#define GPF_DISABLED 0x04 // do not try any PAM stuff.
|
|
#define GPF_AUXMODE 0x08 // store info in .aux (HFA) file.
|
|
#define GPF_NOSAVE 0x10 // do not try to save pam info.
|
|
|
|
/* ==================================================================== */
|
|
/* GDALDatasetPamInfo */
|
|
/* */
|
|
/* We make these things a separate structure of information */
|
|
/* primarily so we can modify it without altering the size of */
|
|
/* the GDALPamDataset. It is an effort to reduce ABI churn for */
|
|
/* driver plugins. */
|
|
/* ==================================================================== */
|
|
class GDALDatasetPamInfo
|
|
{
|
|
public:
|
|
char *pszPamFilename = nullptr;
|
|
|
|
std::vector<CPLXMLTreeCloser> m_apoOtherNodes{};
|
|
|
|
OGRSpatialReference *poSRS = nullptr;
|
|
|
|
int bHaveGeoTransform = false;
|
|
std::array<double, 6> adfGeoTransform{};
|
|
|
|
std::vector<gdal::GCP> asGCPs{};
|
|
OGRSpatialReference *poGCP_SRS = nullptr;
|
|
|
|
CPLString osPhysicalFilename{};
|
|
CPLString osSubdatasetName{};
|
|
CPLString osDerivedDatasetName{};
|
|
CPLString osAuxFilename{};
|
|
|
|
int bHasMetadata = false;
|
|
};
|
|
|
|
//! @endcond
|
|
|
|
/* ******************************************************************** */
|
|
/* GDALPamDataset */
|
|
/* ******************************************************************** */
|
|
|
|
/** PAM dataset */
|
|
class CPL_DLL GDALPamDataset : public GDALDataset
|
|
{
|
|
friend class GDALPamRasterBand;
|
|
|
|
private:
|
|
int IsPamFilenameAPotentialSiblingFile();
|
|
|
|
protected:
|
|
GDALPamDataset(void);
|
|
//! @cond Doxygen_Suppress
|
|
int nPamFlags = 0;
|
|
GDALDatasetPamInfo *psPam = nullptr;
|
|
|
|
virtual CPLXMLNode *SerializeToXML(const char *);
|
|
virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
|
|
|
|
virtual CPLErr TryLoadXML(CSLConstList papszSiblingFiles = nullptr);
|
|
virtual CPLErr TrySaveXML();
|
|
|
|
CPLErr TryLoadAux(CSLConstList papszSiblingFiles = nullptr);
|
|
CPLErr TrySaveAux();
|
|
|
|
virtual const char *BuildPamFilename();
|
|
|
|
void PamInitialize();
|
|
void PamClear();
|
|
|
|
void SetPhysicalFilename(const char *);
|
|
const char *GetPhysicalFilename();
|
|
void SetSubdatasetName(const char *);
|
|
const char *GetSubdatasetName();
|
|
void SetDerivedDatasetName(const char *);
|
|
//! @endcond
|
|
|
|
public:
|
|
~GDALPamDataset() override;
|
|
|
|
CPLErr FlushCache(bool bAtClosing) override;
|
|
|
|
const OGRSpatialReference *GetSpatialRef() const override;
|
|
CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
|
|
|
|
CPLErr GetGeoTransform(double *) override;
|
|
CPLErr SetGeoTransform(double *) override;
|
|
void DeleteGeoTransform();
|
|
|
|
int GetGCPCount() override;
|
|
const OGRSpatialReference *GetGCPSpatialRef() const override;
|
|
const GDAL_GCP *GetGCPs() override;
|
|
using GDALDataset::SetGCPs;
|
|
CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
|
|
const OGRSpatialReference *poSRS) override;
|
|
|
|
CPLErr SetMetadata(char **papszMetadata,
|
|
const char *pszDomain = "") override;
|
|
CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
|
|
const char *pszDomain = "") override;
|
|
char **GetMetadata(const char *pszDomain = "") override;
|
|
const char *GetMetadataItem(const char *pszName,
|
|
const char *pszDomain = "") override;
|
|
|
|
char **GetFileList(void) override;
|
|
|
|
void ClearStatistics() override;
|
|
|
|
//! @cond Doxygen_Suppress
|
|
virtual CPLErr CloneInfo(GDALDataset *poSrcDS, int nCloneInfoFlags);
|
|
|
|
CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
|
|
const int *panOverviewList, int nListBands,
|
|
const int *panBandList, GDALProgressFunc pfnProgress,
|
|
void *pProgressData,
|
|
CSLConstList papszOptions) override;
|
|
|
|
// "semi private" methods.
|
|
void MarkPamDirty();
|
|
|
|
GDALDatasetPamInfo *GetPamInfo()
|
|
{
|
|
return psPam;
|
|
}
|
|
|
|
int GetPamFlags()
|
|
{
|
|
return nPamFlags;
|
|
}
|
|
|
|
void SetPamFlags(int nValue)
|
|
{
|
|
nPamFlags = nValue;
|
|
}
|
|
|
|
//! @endcond
|
|
|
|
private:
|
|
CPL_DISALLOW_COPY_ASSIGN(GDALPamDataset)
|
|
};
|
|
|
|
//! @cond Doxygen_Suppress
|
|
|
|
constexpr double GDAL_PAM_DEFAULT_NODATA_VALUE = 0;
|
|
// Parenthesis for external code around std::numeric_limits<>::min/max,
|
|
// for external Windows code that might have includes <windows.h> before
|
|
// without defining NOMINMAX
|
|
constexpr int64_t GDAL_PAM_DEFAULT_NODATA_VALUE_INT64 =
|
|
(std::numeric_limits<int64_t>::min)();
|
|
constexpr uint64_t GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64 =
|
|
(std::numeric_limits<uint64_t>::max)();
|
|
|
|
/* ==================================================================== */
|
|
/* GDALRasterBandPamInfo */
|
|
/* */
|
|
/* We make these things a separate structure of information */
|
|
/* primarily so we can modify it without altering the size of */
|
|
/* the GDALPamDataset. It is an effort to reduce ABI churn for */
|
|
/* driver plugins. */
|
|
/* ==================================================================== */
|
|
struct GDALRasterBandPamInfo
|
|
{
|
|
GDALPamDataset *poParentDS = nullptr;
|
|
|
|
bool bNoDataValueSet = false;
|
|
bool bNoDataValueSetAsInt64 = false;
|
|
bool bNoDataValueSetAsUInt64 = false;
|
|
|
|
double dfNoDataValue = GDAL_PAM_DEFAULT_NODATA_VALUE;
|
|
int64_t nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64;
|
|
uint64_t nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64;
|
|
|
|
GDALColorTable *poColorTable = nullptr;
|
|
|
|
GDALColorInterp eColorInterp = GCI_Undefined;
|
|
|
|
char *pszUnitType = nullptr;
|
|
char **papszCategoryNames = nullptr;
|
|
|
|
double dfOffset = 0.0;
|
|
double dfScale = 1.0;
|
|
|
|
int bHaveMinMax = FALSE;
|
|
double dfMin = 0;
|
|
double dfMax = 0;
|
|
|
|
int bHaveStats = FALSE;
|
|
double dfMean = 0;
|
|
double dfStdDev = 0;
|
|
|
|
CPLXMLNode *psSavedHistograms = nullptr;
|
|
|
|
GDALRasterAttributeTable *poDefaultRAT = nullptr;
|
|
|
|
bool bOffsetSet = false;
|
|
bool bScaleSet = false;
|
|
|
|
void CopyFrom(const GDALRasterBandPamInfo &sOther);
|
|
};
|
|
|
|
//! @endcond
|
|
/* ******************************************************************** */
|
|
/* GDALPamRasterBand */
|
|
/* ******************************************************************** */
|
|
|
|
/** PAM raster band */
|
|
class CPL_DLL GDALPamRasterBand : public GDALRasterBand
|
|
{
|
|
friend class GDALPamDataset;
|
|
|
|
protected:
|
|
//! @cond Doxygen_Suppress
|
|
virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath);
|
|
virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
|
|
|
|
void PamInitialize();
|
|
void PamClear();
|
|
void PamInitializeNoParent();
|
|
void MarkPamDirty();
|
|
|
|
GDALRasterBandPamInfo *psPam = nullptr;
|
|
//! @endcond
|
|
|
|
public:
|
|
GDALPamRasterBand();
|
|
//! @cond Doxygen_Suppress
|
|
explicit GDALPamRasterBand(int bForceCachedIO);
|
|
//! @endcond
|
|
~GDALPamRasterBand() override;
|
|
|
|
void SetDescription(const char *) override;
|
|
|
|
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;
|
|
|
|
CPLErr SetColorTable(GDALColorTable *) override;
|
|
GDALColorTable *GetColorTable() override;
|
|
|
|
CPLErr SetColorInterpretation(GDALColorInterp) override;
|
|
GDALColorInterp GetColorInterpretation() override;
|
|
|
|
const char *GetUnitType() override;
|
|
CPLErr SetUnitType(const char *) override;
|
|
|
|
char **GetCategoryNames() override;
|
|
CPLErr SetCategoryNames(char **) override;
|
|
|
|
double GetOffset(int *pbSuccess = nullptr) override;
|
|
CPLErr SetOffset(double) override;
|
|
double GetScale(int *pbSuccess = nullptr) override;
|
|
CPLErr SetScale(double) override;
|
|
|
|
CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
|
|
GUIntBig *panHistogram, int bIncludeOutOfRange,
|
|
int bApproxOK, GDALProgressFunc,
|
|
void *pProgressData) override;
|
|
|
|
CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets,
|
|
GUIntBig **ppanHistogram, int bForce,
|
|
GDALProgressFunc, void *pProgressData) override;
|
|
|
|
CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
|
|
GUIntBig *panHistogram) override;
|
|
|
|
CPLErr SetMetadata(char **papszMetadata,
|
|
const char *pszDomain = "") override;
|
|
CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
|
|
const char *pszDomain = "") override;
|
|
|
|
GDALRasterAttributeTable *GetDefaultRAT() override;
|
|
CPLErr SetDefaultRAT(const GDALRasterAttributeTable *) override;
|
|
|
|
//! @cond Doxygen_Suppress
|
|
// new in GDALPamRasterBand.
|
|
virtual CPLErr CloneInfo(GDALRasterBand *poSrcBand, int nCloneInfoFlags);
|
|
|
|
// "semi private" methods.
|
|
GDALRasterBandPamInfo *GetPamInfo()
|
|
{
|
|
return psPam;
|
|
}
|
|
|
|
//! @endcond
|
|
private:
|
|
CPL_DISALLOW_COPY_ASSIGN(GDALPamRasterBand)
|
|
|
|
void ResetNoDataValues();
|
|
};
|
|
|
|
//! @cond Doxygen_Suppress
|
|
|
|
/* ******************************************************************** */
|
|
/* GDALPamMultiDim */
|
|
/* ******************************************************************** */
|
|
|
|
/** Class that serializes/deserializes metadata on multidimensional objects.
|
|
* Currently SRS on GDALMDArray.
|
|
*/
|
|
class CPL_DLL GDALPamMultiDim
|
|
{
|
|
struct Private;
|
|
std::unique_ptr<Private> d;
|
|
|
|
void Load();
|
|
void Save();
|
|
|
|
public:
|
|
explicit GDALPamMultiDim(const std::string &osFilename);
|
|
virtual ~GDALPamMultiDim();
|
|
|
|
std::shared_ptr<OGRSpatialReference>
|
|
GetSpatialRef(const std::string &osArrayFullName,
|
|
const std::string &osContext);
|
|
|
|
void SetSpatialRef(const std::string &osArrayFullName,
|
|
const std::string &osContext,
|
|
const OGRSpatialReference *poSRS);
|
|
|
|
CPLErr GetStatistics(const std::string &osArrayFullName,
|
|
const std::string &osContext, bool bApproxOK,
|
|
double *pdfMin, double *pdfMax, double *pdfMean,
|
|
double *pdfStdDev, GUInt64 *pnValidCount);
|
|
|
|
void SetStatistics(const std::string &osArrayFullName,
|
|
const std::string &osContext, bool bApproxStats,
|
|
double dfMin, double dfMax, double dfMean,
|
|
double dfStdDev, GUInt64 nValidCount);
|
|
|
|
void ClearStatistics();
|
|
|
|
void ClearStatistics(const std::string &osArrayFullName,
|
|
const std::string &osContext);
|
|
|
|
static std::shared_ptr<GDALPamMultiDim>
|
|
GetPAM(const std::shared_ptr<GDALMDArray> &poParent);
|
|
};
|
|
|
|
/* ******************************************************************** */
|
|
/* GDALPamMDArray */
|
|
/* ******************************************************************** */
|
|
|
|
/** Class that relies on GDALPamMultiDim to serializes/deserializes metadata. */
|
|
class CPL_DLL GDALPamMDArray : public GDALMDArray
|
|
{
|
|
std::shared_ptr<GDALPamMultiDim> m_poPam;
|
|
|
|
protected:
|
|
GDALPamMDArray(const std::string &osParentName, const std::string &osName,
|
|
const std::shared_ptr<GDALPamMultiDim> &poPam,
|
|
const std::string &osContext = std::string());
|
|
|
|
bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
|
|
double dfMean, double dfStdDev, GUInt64 nValidCount,
|
|
CSLConstList papszOptions) override;
|
|
|
|
public:
|
|
const std::shared_ptr<GDALPamMultiDim> &GetPAM() const
|
|
{
|
|
return m_poPam;
|
|
}
|
|
|
|
CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
|
|
double *pdfMax, double *pdfMean, double *padfStdDev,
|
|
GUInt64 *pnValidCount, GDALProgressFunc pfnProgress,
|
|
void *pProgressData) override;
|
|
|
|
void ClearStatistics() override;
|
|
|
|
bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
|
|
|
|
std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override;
|
|
};
|
|
|
|
// These are mainly helper functions for internal use.
|
|
int CPL_DLL PamParseHistogram(CPLXMLNode *psHistItem, double *pdfMin,
|
|
double *pdfMax, int *pnBuckets,
|
|
GUIntBig **ppanHistogram,
|
|
int *pbIncludeOutOfRange, int *pbApproxOK);
|
|
CPLXMLNode CPL_DLL *PamFindMatchingHistogram(CPLXMLNode *psSavedHistograms,
|
|
double dfMin, double dfMax,
|
|
int nBuckets,
|
|
int bIncludeOutOfRange,
|
|
int bApproxOK);
|
|
CPLXMLNode CPL_DLL *PamHistogramToXMLTree(double dfMin, double dfMax,
|
|
int nBuckets, GUIntBig *panHistogram,
|
|
int bIncludeOutOfRange, int bApprox);
|
|
|
|
// For managing the proxy file database.
|
|
const char CPL_DLL *PamGetProxy(const char *);
|
|
const char CPL_DLL *PamAllocateProxy(const char *);
|
|
const char CPL_DLL *PamDeallocateProxy(const char *);
|
|
void CPL_DLL PamCleanProxyDB(void);
|
|
|
|
//! @endcond
|
|
|
|
#endif /* ndef GDAL_PAM_H_INCLUDED */
|