Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: MiraMonRaster driver
4 : * Purpose: Implements MMRRel: provides access to the REL file, which
5 : * holds all the necessary metadata to correctly interpret and
6 : * access the associated raw data.
7 : * Author: Abel Pau
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2025, Xavier Pons
11 : *
12 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #ifndef MMR_REL_H_INCLUDED
16 : #define MMR_REL_H_INCLUDED
17 :
18 : #include "cpl_string.h"
19 : #include "gdal_priv.h"
20 : #include "miramon_band.h" // For MMRBand
21 :
22 : #include "../miramon_common/mm_gdal_driver_structs.h" // For SECTION_VERSIO
23 :
24 : constexpr auto pszExtRaster = ".img";
25 : constexpr auto pszExtRasterREL = "I.rel";
26 : constexpr auto pszExtREL = ".rel";
27 :
28 : class MMRBand;
29 :
30 : /************************************************************************/
31 : /* MMRRel */
32 : /************************************************************************/
33 :
34 : enum class MMRNomFitxerState
35 : {
36 : NOMFITXER_NOT_FOUND, // There is no NomFitxer key
37 : NOMFITXER_VALUE_EXPECTED, // The NomFitxer value is the expected
38 : NOMFITXER_VALUE_EMPTY, // The NomFitxer value is empty
39 : NOMFITXER_VALUE_UNEXPECTED // The NomFitxer value is unexpected
40 : };
41 :
42 : using ExcludedEntry = std::pair<CPLString, CPLString>;
43 :
44 : class MMRRel
45 : {
46 : public:
47 : MMRRel(const CPLString &, bool);
48 : MMRRel(const MMRRel &) =
49 : delete; // I don't want to construct a MMRDataset from another MMRDataset (effc++)
50 : MMRRel &operator=(const MMRRel &) =
51 : delete; // I don't want to assign a MMRDataset to another MMRDataset (effc++)
52 : ~MMRRel();
53 :
54 : static CPLString
55 : GetValueFromSectionKeyPriorToREL(const CPLString &osPriorRelName,
56 : const CPLString &osSection,
57 : const CPLString &osKey);
58 : CPLString GetValueFromSectionKeyFromREL(const CPLString &osSection,
59 : const CPLString &osKey);
60 : static CPLString GetValueFromSectionKey(VSILFILE *pf,
61 : const CPLString &osSection,
62 : const CPLString &osKey);
63 : bool GetMetadataValue(const CPLString &osMainSection,
64 : const CPLString &osSubSection,
65 : const CPLString &osSubSubSection,
66 : const CPLString &osKey, CPLString &osValue);
67 : bool GetMetadataValue(const CPLString &osMainSection,
68 : const CPLString &osSubSection, const CPLString &osKey,
69 : CPLString &osValue);
70 : bool GetMetadataValue(const CPLString &osSection, const CPLString &osKey,
71 : CPLString &osValue);
72 : bool GetAndExcludeMetadataValueDirectly(const CPLString &osRELFile,
73 : const CPLString &osSection,
74 : const CPLString &osKey,
75 : CPLString &osValue);
76 : static bool GetMetadataValueDirectly(const CPLString &osRELFile,
77 : const CPLString &osSection,
78 : const CPLString &osKey,
79 : CPLString &osValue);
80 : void RELToGDALMetadata(GDALDataset *poDS);
81 :
82 : static CPLString MMRGetFileNameWithOutI(const CPLString &osRELFile);
83 : static CPLString MMRGetFileNameFromRelName(const CPLString &osRELFile,
84 : const CPLString osExtension);
85 : int GetColumnsNumberFromREL();
86 : int GetRowsNumberFromREL();
87 : static int IdentifySubdataSetFile(const CPLString &osFileName);
88 : static int IdentifyFile(const GDALOpenInfo *poOpenInfo);
89 : CPLString GetColor_TractamentVariable(int nIBand);
90 : CPLString GetColor_Paleta(int nIBand);
91 : CPLErr UpdateGDALColorEntryFromBand(CPLString m_osBandSection,
92 : GDALColorEntry &m_sConstantColorRGB);
93 :
94 243 : bool IsValid() const
95 : {
96 243 : return m_bIsValid;
97 : }
98 :
99 : void SetIsValid(bool bIsValidIn)
100 : {
101 : m_bIsValid = bIsValidIn;
102 : }
103 :
104 10098 : VSILFILE *GetRELFile() const
105 : {
106 10098 : return m_pRELFile;
107 : }
108 :
109 81 : bool OpenRELFile(const char *pszAccess)
110 : {
111 81 : if (m_osRelFileName.empty())
112 0 : return false;
113 :
114 81 : m_pRELFile = VSIFOpenL(m_osRelFileName, pszAccess);
115 81 : if (m_pRELFile)
116 81 : return true;
117 0 : return false;
118 : }
119 :
120 : bool OpenRELFile()
121 : {
122 : if (m_osRelFileName.empty())
123 : return false;
124 :
125 : m_pRELFile = VSIFOpenL(m_osRelFileName, "rb");
126 : if (m_pRELFile)
127 : return true;
128 : return false;
129 : }
130 :
131 247 : void CloseRELFile()
132 : {
133 247 : if (!m_pRELFile)
134 166 : return;
135 :
136 81 : VSIFCloseL(m_pRELFile);
137 81 : m_pRELFile = nullptr;
138 : }
139 :
140 106 : const char *GetRELNameChar() const
141 : {
142 106 : return m_osRelFileName.c_str();
143 : }
144 :
145 98 : CPLString GetRELName() const
146 : {
147 98 : return m_osRelFileName;
148 : }
149 :
150 1537 : int GetNBands() const
151 : {
152 1537 : return m_nBands;
153 : }
154 :
155 1335 : MMRBand *GetBand(int nIBand)
156 : {
157 1335 : if (nIBand < 0 || nIBand >= m_nBands)
158 0 : return nullptr;
159 :
160 1335 : return &m_oBands[nIBand];
161 : }
162 :
163 3567 : int isAMiraMonFile() const
164 : {
165 3567 : return m_bIsAMiraMonFile;
166 : }
167 :
168 5236 : void addExcludedSectionKey(const CPLString §ion, const CPLString &key)
169 : {
170 5236 : m_ExcludedSectionKey.emplace(section, key);
171 5236 : }
172 :
173 12340 : std::set<ExcludedEntry> GetExcludedMetadata() const
174 : {
175 12340 : return m_ExcludedSectionKey;
176 : }
177 :
178 : private:
179 : static CPLErr CheckBandInRel(const CPLString &osRELFileName,
180 : const CPLString &osIMGFile);
181 : static CPLString MMRGetSimpleMetadataName(const CPLString &osLayerName);
182 : static bool SameFile(const CPLString &osFile1, const CPLString &osFile2);
183 : MMRNomFitxerState MMRStateOfNomFitxerInSection(const CPLString &osLayerName,
184 : const CPLString &osSection,
185 : const CPLString &osRELFile,
186 : bool bNomFitxerMustExist);
187 : CPLString MMRGetAReferenceToIMGFile(const CPLString &osLayerName,
188 : const CPLString &osRELFile);
189 :
190 : CPLString GetAssociatedMetadataFileName(const CPLString &osFileName);
191 :
192 : void UpdateRELNameChar(const CPLString &osRelFileNameIn);
193 : CPLErr ParseBandInfo();
194 :
195 : CPLString m_osRelFileName = "";
196 : VSILFILE *m_pRELFile = nullptr;
197 : static CPLString m_szImprobableRELChain;
198 :
199 : bool m_bIsValid =
200 : false; // Determines if the created object is valid or not.
201 : bool m_bIsAMiraMonFile = false;
202 :
203 : // List of rawBandNames in a subdataset
204 : std::vector<CPLString> m_papoSDSBands{};
205 :
206 : int m_nBands = 0;
207 : std::vector<MMRBand> m_oBands{};
208 :
209 : // Preserving metadata
210 :
211 : // Domain
212 : static constexpr const char *m_kMetadataDomain = "MIRAMON";
213 :
214 : // Used to join Section and Key in a single
215 : // name for SetMetadataItem(Name, Value)
216 : static constexpr const char *m_SecKeySeparator = "[$$$]";
217 :
218 : // List of excluded pairs {Section, Key} to be added to metadata
219 : // Empty Key means all section
220 : std::set<ExcludedEntry> m_ExcludedSectionKey = {};
221 : };
222 :
223 : #endif /* ndef MMR_REL_H_INCLUDED */
|