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 : constexpr auto pszExtRaster = ".img"; 23 : constexpr auto pszExtRasterREL = "I.rel"; 24 : constexpr auto pszExtREL = ".rel"; 25 : 26 : class MMRBand; 27 : 28 : /************************************************************************/ 29 : /* MMRRel */ 30 : /************************************************************************/ 31 : 32 : enum class MMRNomFitxerState 33 : { 34 : NOMFITXER_NOT_FOUND, // There is no NomFitxer key 35 : NOMFITXER_VALUE_EXPECTED, // The NomFitxer value is the expected 36 : NOMFITXER_VALUE_EMPTY, // The NomFitxer value is empty 37 : NOMFITXER_VALUE_UNEXPECTED // The NomFitxer value is unexpected 38 : }; 39 : 40 : using ExcludedEntry = std::pair<CPLString, CPLString>; 41 : 42 : class MMRRel 43 : { 44 : public: 45 : MMRRel(const CPLString &, bool); 46 : MMRRel(const MMRRel &) = 47 : delete; // I don't want to construct a MMRDataset from another MMRDataset (effc++) 48 : MMRRel &operator=(const MMRRel &) = 49 : delete; // I don't want to assign a MMRDataset to another MMRDataset (effc++) 50 : ~MMRRel(); 51 : 52 : static CPLString 53 : GetValueFromSectionKeyPriorToREL(const CPLString &osPriorRelName, 54 : const CPLString &osSection, 55 : const CPLString &osKey); 56 : CPLString GetValueFromSectionKeyFromREL(const CPLString &osSection, 57 : const CPLString &osKey); 58 : static CPLString GetValueFromSectionKey(VSILFILE *pf, 59 : const CPLString &osSection, 60 : const CPLString &osKey); 61 : bool GetMetadataValue(const CPLString &osMainSection, 62 : const CPLString &osSubSection, 63 : const CPLString &osSubSubSection, 64 : const CPLString &osKey, CPLString &osValue); 65 : bool GetMetadataValue(const CPLString &osMainSection, 66 : const CPLString &osSubSection, const CPLString &osKey, 67 : CPLString &osValue); 68 : bool GetMetadataValue(const CPLString &osSection, const CPLString &osKey, 69 : CPLString &osValue); 70 : bool GetAndExcludeMetadataValueDirectly(const CPLString &osRELFile, 71 : const CPLString &osSection, 72 : const CPLString &osKey, 73 : CPLString &osValue); 74 : static bool GetMetadataValueDirectly(const CPLString &osRELFile, 75 : const CPLString &osSection, 76 : const CPLString &osKey, 77 : CPLString &osValue); 78 : void RELToGDALMetadata(GDALDataset *poDS); 79 : 80 : static CPLString MMRGetFileNameFromRelName(const CPLString &osRELFile); 81 : int GetColumnsNumberFromREL(); 82 : int GetRowsNumberFromREL(); 83 : static int IdentifySubdataSetFile(const CPLString &osFileName); 84 : static int IdentifyFile(const GDALOpenInfo *poOpenInfo); 85 : 86 242 : bool IsValid() const 87 : { 88 242 : return m_bIsValid; 89 : } 90 : 91 : void SetIsValid(bool bIsValidIn) 92 : { 93 : m_bIsValid = bIsValidIn; 94 : } 95 : 96 7134 : VSILFILE *GetRELFile() const 97 : { 98 7134 : return m_pRELFile; 99 : } 100 : 101 82 : bool OpenRELFile() 102 : { 103 82 : if (m_osRelFileName.empty()) 104 0 : return false; 105 : 106 82 : m_pRELFile = VSIFOpenL(m_osRelFileName, "rb"); 107 82 : if (m_pRELFile) 108 82 : return true; 109 0 : return false; 110 : } 111 : 112 246 : void CloseRELFile() 113 : { 114 246 : if (!m_pRELFile) 115 164 : return; 116 : 117 82 : VSIFCloseL(m_pRELFile); 118 82 : m_pRELFile = nullptr; 119 : } 120 : 121 89 : const char *GetRELNameChar() const 122 : { 123 89 : return m_osRelFileName.c_str(); 124 : } 125 : 126 76 : CPLString GetRELName() const 127 : { 128 76 : return m_osRelFileName; 129 : } 130 : 131 630 : int GetNBands() const 132 : { 133 630 : return m_nBands; 134 : } 135 : 136 646 : MMRBand *GetBand(int nIBand) const 137 : { 138 646 : if (nIBand < 0 || nIBand >= m_nBands) 139 0 : return nullptr; 140 : 141 646 : return m_oBands[nIBand].get(); 142 : } 143 : 144 2627 : int isAMiraMonFile() const 145 : { 146 2627 : return m_bIsAMiraMonFile; 147 : } 148 : 149 3754 : void addExcludedSectionKey(const CPLString §ion, const CPLString &key) 150 : { 151 3754 : m_ExcludedSectionKey.emplace(section, key); 152 3754 : } 153 : 154 13152 : std::set<ExcludedEntry> GetExcludedMetadata() const 155 : { 156 13152 : return m_ExcludedSectionKey; 157 : } 158 : 159 : private: 160 : static CPLErr CheckBandInRel(const CPLString &osRELFileName, 161 : const CPLString &osIMGFile); 162 : static CPLString MMRGetSimpleMetadataName(const CPLString &osLayerName); 163 : static bool SameFile(const CPLString &osFile1, const CPLString &osFile2); 164 : MMRNomFitxerState MMRStateOfNomFitxerInSection(const CPLString &osLayerName, 165 : const CPLString &osSection, 166 : const CPLString &osRELFile, 167 : bool bNomFitxerMustExist); 168 : CPLString MMRGetAReferenceToIMGFile(const CPLString &osLayerName, 169 : const CPLString &osRELFile); 170 : 171 : CPLString GetAssociatedMetadataFileName(const CPLString &osFileName); 172 : 173 : void UpdateRELNameChar(const CPLString &osRelFileNameIn); 174 : CPLErr ParseBandInfo(); 175 : 176 : CPLString m_osRelFileName = ""; 177 : VSILFILE *m_pRELFile = nullptr; 178 : static CPLString m_szImprobableRELChain; 179 : 180 : bool m_bIsValid = 181 : false; // Determines if the created object is valid or not. 182 : bool m_bIsAMiraMonFile = false; 183 : 184 : // List of rawBandNames in a subdataset 185 : std::vector<CPLString> m_papoSDSBands{}; 186 : 187 : int m_nBands = 0; 188 : std::vector<std::unique_ptr<MMRBand>> m_oBands{}; 189 : 190 : // Preserving metadata 191 : 192 : // Domain 193 : static constexpr const char *m_kMetadataDomain = "MIRAMON"; 194 : 195 : // Used to join Section and Key in a single 196 : // name for SetMetadataItem(Name, Value) 197 : static constexpr const char *m_SecKeySeparator = "[$$$]"; 198 : 199 : // List of excluded pairs {Section, Key} to be added to metadata 200 : // Empty Key means all section 201 : std::set<ExcludedEntry> m_ExcludedSectionKey = {}; 202 : }; 203 : 204 : #endif /* ndef MMR_REL_H_INCLUDED */