/src/bag/api/bag_georefmetadatalayerdescriptor.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | #include "bag_dataset.h" |
3 | | #include "bag_georefmetadatalayerdescriptor.h" |
4 | | #include "bag_metadataprofiles.h" |
5 | | #include "bag_hdfhelper.h" |
6 | | #include "bag_private.h" |
7 | | #include "bag_valuetable.h" |
8 | | |
9 | | #include <iostream> |
10 | | #include <array> |
11 | | #include <H5Cpp.h> |
12 | | |
13 | | |
14 | | namespace BAG { |
15 | | |
16 | | //! Constructor. |
17 | | /*! |
18 | | \param dataset |
19 | | The BAG Dataset this layer belongs to. |
20 | | \param name |
21 | | The name of the simple layer this layer has metadata for. |
22 | | \param keyType |
23 | | The type of the key. |
24 | | Must be DT_UINT8, DT_UINT16, DT_UINT32, or DT_UINT64. |
25 | | \param definition |
26 | | The list of fields describing a record/value. |
27 | | \param chunkSize |
28 | | The chunk size the HDF5 DataSet will use. |
29 | | \param compressionLevel |
30 | | The compression level the HDF5 DataSet will use. |
31 | | */ |
32 | | GeorefMetadataLayerDescriptor::GeorefMetadataLayerDescriptor( |
33 | | Dataset& dataset, |
34 | | const std::string& name, |
35 | | GeorefMetadataProfile profile, |
36 | | DataType keyType, |
37 | | RecordDefinition definition, |
38 | | uint64_t chunkSize, |
39 | | int compressionLevel) |
40 | 63 | : LayerDescriptor(dataset.getNextId(), GEOREF_METADATA_PATH + name, name, |
41 | 63 | Georef_Metadata, chunkSize, compressionLevel) |
42 | 63 | , m_pBagDataset(dataset.shared_from_this()) |
43 | 63 | , m_profile(profile) |
44 | 63 | , m_keyType(keyType) |
45 | 63 | , m_elementSize(Layer::getElementSize(keyType)) |
46 | 63 | , m_definition(std::move(definition)) |
47 | 63 | { |
48 | 63 | } |
49 | | |
50 | | //! Create a georeferenced metadata layer descriptor. |
51 | | /*! |
52 | | \param dataset |
53 | | The BAG Dataset this layer belongs to. |
54 | | \param name |
55 | | The name of the simple layer this layer has metadata for. |
56 | | \param keyType |
57 | | The type of the key. |
58 | | Must be DT_UINT8, DT_UINT16, DT_UINT32, or DT_UINT64. |
59 | | \param definition |
60 | | The list of fields describing a record/value this layer contains for each node. |
61 | | \param chunkSize |
62 | | The chunk size the HDF5 DataSet will use. |
63 | | \param compressionLevel |
64 | | The compression level the HDF5 DataSet will use. |
65 | | |
66 | | \return |
67 | | The new georeferenced metadata layer descriptor. |
68 | | */ |
69 | | std::shared_ptr<GeorefMetadataLayerDescriptor> GeorefMetadataLayerDescriptor::create( |
70 | | Dataset& dataset, |
71 | | const std::string& name, |
72 | | GeorefMetadataProfile profile, |
73 | | DataType keyType, |
74 | | RecordDefinition definition, |
75 | | uint64_t chunkSize, |
76 | | int compressionLevel) |
77 | 0 | { |
78 | 0 | return std::shared_ptr<GeorefMetadataLayerDescriptor>( |
79 | 0 | new GeorefMetadataLayerDescriptor{dataset, name, profile, keyType, |
80 | 0 | std::move(definition), chunkSize, compressionLevel}); |
81 | 0 | } |
82 | | |
83 | | //! Open an existing georeferenced metadata layer descriptor. |
84 | | /*! |
85 | | \param dataset |
86 | | The BAG Dataset this layer belongs to. |
87 | | \param name |
88 | | The name of the simple layer this layer has metadata for. |
89 | | |
90 | | \return |
91 | | The existing georeferenced metadata layer descriptor. |
92 | | */ |
93 | | std::shared_ptr<GeorefMetadataLayerDescriptor> GeorefMetadataLayerDescriptor::open( |
94 | | Dataset& dataset, |
95 | | const std::string& name) |
96 | 82 | { |
97 | 82 | const auto& h5file = dataset.getH5file(); |
98 | | |
99 | 82 | const std::string internalPath{GEOREF_METADATA_PATH + name + COMPOUND_KEYS}; |
100 | 82 | const auto h5dataSet = ::H5::DataSet{h5file.openDataSet(internalPath)}; |
101 | | |
102 | | // Determine keyType. |
103 | 82 | const auto fileDataType = h5dataSet.getDataType(); |
104 | | |
105 | 82 | DataType keyType = DT_UNKNOWN_DATA_TYPE; |
106 | 82 | switch(fileDataType.getSize()) |
107 | 82 | { |
108 | 0 | case 1: |
109 | 0 | keyType = DT_UINT8; |
110 | 0 | break; |
111 | 76 | case 2: |
112 | 76 | keyType = DT_UINT16; |
113 | 76 | break; |
114 | 0 | case 4: |
115 | 0 | keyType = DT_UINT32; |
116 | 0 | break; |
117 | 0 | case 8: |
118 | 0 | keyType = DT_UINT64; |
119 | 0 | break; |
120 | 2 | default: |
121 | 2 | throw InvalidKeyType{}; |
122 | 82 | } |
123 | | |
124 | | // Determine Record Definition. |
125 | 76 | const auto attribute = h5dataSet.openAttribute(COMPOUND_RECORD_DEFINITION); |
126 | | |
127 | 76 | const auto fileDataSpace = attribute.getSpace(); |
128 | | |
129 | 76 | const auto numDims = fileDataSpace.getSimpleExtentNdims(); |
130 | 76 | if (numDims != 1) |
131 | 0 | throw InvalidValueSize{}; |
132 | | |
133 | 76 | hsize_t numFields = 0; |
134 | 76 | fileDataSpace.getSimpleExtentDims(&numFields, nullptr); |
135 | | |
136 | 76 | RecordDefinition definition(numFields); |
137 | | |
138 | 76 | attribute.read(attribute.getDataType(), definition.data()); |
139 | | |
140 | | // Determine chunk size and compression level. |
141 | 76 | const auto chunkSize = BAG::getChunkSize(h5file, internalPath); |
142 | 76 | const auto compressionLevel = BAG::getCompressionLevel(h5file, internalPath); |
143 | | |
144 | | // Read metadata profile as string from HDF5 file attribute and convert to GeorefMetadataProfile enum value. |
145 | 76 | std::string profileString; |
146 | 76 | if (h5dataSet.attrExists(METADATA_PROFILE_TYPE)) { |
147 | 57 | const auto metadataProfileAtt = h5dataSet.openAttribute(METADATA_PROFILE_TYPE); |
148 | 57 | metadataProfileAtt.read(metadataProfileAtt.getDataType(), profileString); |
149 | 57 | } else { |
150 | 19 | std::cerr << "Unable to find georeferenced metadata layer attribute '" << METADATA_PROFILE_TYPE << |
151 | 19 | "' for simple layer '" << name << "', setting profile to '" << UNKOWN_METADATA_PROFILE_NAME << |
152 | 19 | "'." << std::endl; |
153 | 19 | profileString = UNKOWN_METADATA_PROFILE_NAME; |
154 | 19 | } |
155 | | |
156 | 76 | GeorefMetadataProfile profile; |
157 | 76 | auto search = BAG::kStringMapGeorefMetadataProfile.find(profileString); |
158 | 76 | if (search != BAG::kStringMapGeorefMetadataProfile.end()) { |
159 | | // This is a recognized metadata profile (either a specific known profile or the unknown profile) |
160 | 13 | profile = search->second; |
161 | 63 | } else { |
162 | 63 | std::cerr << "WARNING: Unrecognized georeferenced metadata layer metadata profile '" << profileString << |
163 | 63 | "' for simple layer '" << name << "', assuming value was '" << UNKOWN_METADATA_PROFILE_NAME << |
164 | 63 | "'." << std::endl; |
165 | 63 | profile = UNKNOWN_METADATA_PROFILE; |
166 | 63 | } |
167 | | |
168 | 76 | return std::shared_ptr<GeorefMetadataLayerDescriptor>( |
169 | 76 | new GeorefMetadataLayerDescriptor{dataset, name, profile, keyType, definition, |
170 | 76 | chunkSize, compressionLevel}); |
171 | 76 | } |
172 | | |
173 | | |
174 | | //! \copydoc LayerDescriptor::getDataType |
175 | | DataType GeorefMetadataLayerDescriptor::getDataTypeProxy() const noexcept |
176 | 8 | { |
177 | 8 | return m_keyType; |
178 | 8 | } |
179 | | |
180 | | //! Retrieve the BAG Dataset this layer belongs to. |
181 | | /*! |
182 | | \return |
183 | | The BAG Dataset. |
184 | | */ |
185 | | std::weak_ptr<Dataset> GeorefMetadataLayerDescriptor::getDataset() const & |
186 | 0 | { |
187 | 0 | return m_pBagDataset; |
188 | 0 | } |
189 | | |
190 | | //! \copydoc LayerDescriptor::getElementSize |
191 | | uint8_t GeorefMetadataLayerDescriptor::getElementSizeProxy() const noexcept |
192 | 8 | { |
193 | 8 | return m_elementSize; |
194 | 8 | } |
195 | | |
196 | | //! Retrieve the definition of a record/value. |
197 | | /*! |
198 | | \return |
199 | | The definition of a record/value. |
200 | | */ |
201 | | const RecordDefinition& |
202 | | GeorefMetadataLayerDescriptor::getDefinition() const & noexcept |
203 | 53 | { |
204 | 53 | return m_definition; |
205 | 53 | } |
206 | | |
207 | | //! Retrieve the metadata profile type. |
208 | | /*! |
209 | | \return |
210 | | The metadata profile type. |
211 | | */ |
212 | 0 | GeorefMetadataProfile GeorefMetadataLayerDescriptor::getProfile() { |
213 | 0 | return m_profile; |
214 | 0 | } |
215 | | |
216 | | } // namespace BAG |
217 | | |