/src/gdal/frmts/pds/pds4dataset.h
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: PDS 4 Driver; Planetary Data System Format |
4 | | * Purpose: Implementation of PDS4Dataset |
5 | | * Author: Even Rouault, even.rouault at spatialys.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2019, Hobu Inc |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #pragma once |
14 | | |
15 | | #include "cpl_string.h" |
16 | | #include "gdal_priv.h" |
17 | | #include "gdal_proxy.h" |
18 | | #include "ogreditablelayer.h" |
19 | | #include "rawdataset.h" |
20 | | #include "ogr_spatialref.h" |
21 | | |
22 | | #include <array> |
23 | | #include <vector> |
24 | | |
25 | | class PDS4Dataset; |
26 | | |
27 | | /************************************************************************/ |
28 | | /* ==================================================================== */ |
29 | | /* PDS4TableBaseLayer */ |
30 | | /* ==================================================================== */ |
31 | | /************************************************************************/ |
32 | | |
33 | | class PDS4TableBaseLayer CPL_NON_FINAL : public OGRLayer |
34 | | { |
35 | | protected: |
36 | | PDS4Dataset *m_poDS = nullptr; |
37 | | OGRFeatureDefn *m_poRawFeatureDefn = nullptr; |
38 | | OGRFeatureDefn *m_poFeatureDefn = nullptr; |
39 | | CPLString m_osFilename{}; |
40 | | int m_iLatField = -1; |
41 | | int m_iLongField = -1; |
42 | | int m_iAltField = -1; |
43 | | int m_iWKT = -1; |
44 | | bool m_bKeepGeomColmuns = false; |
45 | | bool m_bDirtyHeader = false; |
46 | | VSILFILE *m_fp = nullptr; |
47 | | GIntBig m_nFeatureCount = -1; |
48 | | GIntBig m_nFID = 1; |
49 | | vsi_l_offset m_nOffset = 0; |
50 | | CPLStringList m_aosLCO{}; |
51 | | std::string m_osLineEnding{}; |
52 | | |
53 | | void SetupGeomField(); |
54 | | OGRFeature *AddGeometryFromFields(OGRFeature *poFeature); |
55 | | OGRFeature *AddFieldsFromGeometry(OGRFeature *poFeature); |
56 | | void MarkHeaderDirty(); |
57 | | CPLXMLNode *RefreshFileAreaObservationalBeginningCommon( |
58 | | CPLXMLNode *psFAO, const CPLString &osPrefix, |
59 | | const char *pszTableEltName, CPLString &osDescription); |
60 | | void ParseLineEndingOption(CSLConstList papszOptions); |
61 | | |
62 | | CPL_DISALLOW_COPY_ASSIGN(PDS4TableBaseLayer) |
63 | | |
64 | | public: |
65 | | PDS4TableBaseLayer(PDS4Dataset *poDS, const char *pszName, |
66 | | const char *pszFilename); |
67 | | ~PDS4TableBaseLayer() override; |
68 | | |
69 | | using OGRLayer::GetLayerDefn; |
70 | | |
71 | | const OGRFeatureDefn *GetLayerDefn() const override |
72 | 1.74M | { |
73 | 1.74M | return m_poFeatureDefn; |
74 | 1.74M | } |
75 | | |
76 | | GIntBig GetFeatureCount(int bForce) override; |
77 | | |
78 | | const char *GetFileName() const |
79 | 5.46k | { |
80 | 5.46k | return m_osFilename.c_str(); |
81 | 5.46k | } |
82 | | |
83 | | bool IsDirtyHeader() const |
84 | 2.78k | { |
85 | 2.78k | return m_bDirtyHeader; |
86 | 2.78k | } |
87 | | |
88 | | int GetRawFieldCount() const |
89 | 2.78k | { |
90 | 2.78k | return m_poRawFeatureDefn->GetFieldCount(); |
91 | 2.78k | } |
92 | | |
93 | | bool RenameFileTo(const char *pszNewName); |
94 | | virtual char **GetFileList() const; |
95 | | |
96 | | virtual void RefreshFileAreaObservational(CPLXMLNode *psFAO) = 0; |
97 | | |
98 | | GDALDataset *GetDataset() override; |
99 | | }; |
100 | | |
101 | | /************************************************************************/ |
102 | | /* ==================================================================== */ |
103 | | /* PDS4FixedWidthTable */ |
104 | | /* ==================================================================== */ |
105 | | /************************************************************************/ |
106 | | |
107 | | template <class T> class PDS4EditableSynchronizer; |
108 | | |
109 | | class PDS4FixedWidthTable CPL_NON_FINAL : public PDS4TableBaseLayer |
110 | | { |
111 | | friend class PDS4EditableSynchronizer<PDS4FixedWidthTable>; |
112 | | |
113 | | protected: |
114 | | int m_nRecordSize = 0; |
115 | | CPLString m_osBuffer{}; |
116 | | |
117 | | struct Field |
118 | | { |
119 | | int m_nOffset = 0; // in XML 1-based, here 0-based |
120 | | int m_nLength = 0; |
121 | | CPLString m_osDataType{}; |
122 | | CPLString m_osUnit{}; |
123 | | CPLString m_osDescription{}; |
124 | | CPLString m_osSpecialConstantsXML{}; |
125 | | }; |
126 | | |
127 | | std::vector<Field> m_aoFields{}; |
128 | | |
129 | | virtual CPLString GetSubType() const = 0; |
130 | | |
131 | | virtual bool CreateFieldInternal(OGRFieldType eType, |
132 | | OGRFieldSubType eSubType, int nWidth, |
133 | | Field &f) = 0; |
134 | | |
135 | | bool ReadFields(const CPLXMLNode *psParent, int nBaseOffset, |
136 | | const CPLString &osSuffixFieldName); |
137 | | |
138 | | public: |
139 | | PDS4FixedWidthTable(PDS4Dataset *poDS, const char *pszName, |
140 | | const char *pszFilename); |
141 | | |
142 | | void ResetReading() override; |
143 | | OGRFeature *GetFeature(GIntBig nFID) override; |
144 | | OGRFeature *GetNextFeature() override; |
145 | | int TestCapability(const char *) const override; |
146 | | OGRErr ISetFeature(OGRFeature *poFeature) override; |
147 | | OGRErr ICreateFeature(OGRFeature *poFeature) override; |
148 | | OGRErr CreateField(const OGRFieldDefn *poFieldIn, int) override; |
149 | | |
150 | | bool ReadTableDef(const CPLXMLNode *psTable); |
151 | | |
152 | | bool InitializeNewLayer(const OGRSpatialReference *poSRS, |
153 | | bool bForceGeographic, OGRwkbGeometryType eGType, |
154 | | const char *const *papszOptions); |
155 | | |
156 | | virtual PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS, |
157 | | const char *pszName, |
158 | | const char *pszFilename) = 0; |
159 | | |
160 | | void RefreshFileAreaObservational(CPLXMLNode *psFAO) override; |
161 | | }; |
162 | | |
163 | | /************************************************************************/ |
164 | | /* ==================================================================== */ |
165 | | /* PDS4TableCharacter */ |
166 | | /* ==================================================================== */ |
167 | | /************************************************************************/ |
168 | | |
169 | | class PDS4TableCharacter final : public PDS4FixedWidthTable |
170 | | { |
171 | | CPLString GetSubType() const override |
172 | 0 | { |
173 | 0 | return "Character"; |
174 | 0 | } |
175 | | |
176 | | bool CreateFieldInternal(OGRFieldType eType, OGRFieldSubType eSubType, |
177 | | int nWidth, Field &f) override; |
178 | | |
179 | | public: |
180 | | PDS4TableCharacter(PDS4Dataset *poDS, const char *pszName, |
181 | | const char *pszFilename); |
182 | | |
183 | | PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS, const char *pszName, |
184 | | const char *pszFilename) override |
185 | 0 | { |
186 | 0 | return new PDS4TableCharacter(poDS, pszName, pszFilename); |
187 | 0 | } |
188 | | }; |
189 | | |
190 | | /************************************************************************/ |
191 | | /* ==================================================================== */ |
192 | | /* PDS4TableBinary */ |
193 | | /* ==================================================================== */ |
194 | | /************************************************************************/ |
195 | | |
196 | | class PDS4TableBinary final : public PDS4FixedWidthTable |
197 | | { |
198 | | CPLString GetSubType() const override |
199 | 0 | { |
200 | 0 | return "Binary"; |
201 | 0 | } |
202 | | |
203 | | bool CreateFieldInternal(OGRFieldType eType, OGRFieldSubType eSubType, |
204 | | int nWidth, Field &f) override; |
205 | | |
206 | | public: |
207 | | PDS4TableBinary(PDS4Dataset *poDS, const char *pszName, |
208 | | const char *pszFilename); |
209 | | |
210 | | PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS, const char *pszName, |
211 | | const char *pszFilename) override |
212 | 0 | { |
213 | 0 | return new PDS4TableBinary(poDS, pszName, pszFilename); |
214 | 0 | } |
215 | | }; |
216 | | |
217 | | /************************************************************************/ |
218 | | /* ==================================================================== */ |
219 | | /* PDS4DelimitedTable */ |
220 | | /* ==================================================================== */ |
221 | | /************************************************************************/ |
222 | | |
223 | | class PDS4DelimitedTable CPL_NON_FINAL : public PDS4TableBaseLayer |
224 | | { |
225 | | friend class PDS4EditableSynchronizer<PDS4DelimitedTable>; |
226 | | |
227 | | protected: |
228 | | bool m_bCreation = false; |
229 | | char m_chFieldDelimiter = ','; |
230 | | bool m_bAddWKTColumnPending = false; |
231 | | |
232 | | struct Field |
233 | | { |
234 | | CPLString m_osDataType{}; |
235 | | CPLString m_osUnit{}; |
236 | | CPLString m_osDescription{}; |
237 | | CPLString m_osSpecialConstantsXML{}; |
238 | | CPLString m_osMissingConstant{}; // included in above potentially |
239 | | }; |
240 | | |
241 | | std::vector<Field> m_aoFields{}; |
242 | | |
243 | | OGRFeature *GetNextFeatureRaw(); |
244 | | CPLString QuoteIfNeeded(const char *pszVal); |
245 | | void GenerateVRT(); |
246 | | |
247 | | bool ReadFields(const CPLXMLNode *psParent, |
248 | | const CPLString &osSuffixFieldName); |
249 | | |
250 | | public: |
251 | | PDS4DelimitedTable(PDS4Dataset *poDS, const char *pszName, |
252 | | const char *pszFilename); |
253 | | ~PDS4DelimitedTable() override; |
254 | | |
255 | | void ResetReading() override; |
256 | | OGRFeature *GetNextFeature() override; |
257 | | int TestCapability(const char *) const override; |
258 | | OGRErr ICreateFeature(OGRFeature *poFeature) override; |
259 | | OGRErr CreateField(const OGRFieldDefn *poFieldIn, int) override; |
260 | | |
261 | | bool ReadTableDef(const CPLXMLNode *psTable); |
262 | | |
263 | | bool InitializeNewLayer(const OGRSpatialReference *poSRS, |
264 | | bool bForceGeographic, OGRwkbGeometryType eGType, |
265 | | const char *const *papszOptions); |
266 | | |
267 | | void RefreshFileAreaObservational(CPLXMLNode *psFAO) override; |
268 | | char **GetFileList() const override; |
269 | | |
270 | | PDS4DelimitedTable *NewLayer(PDS4Dataset *poDS, const char *pszName, |
271 | | const char *pszFilename) |
272 | 279 | { |
273 | 279 | return new PDS4DelimitedTable(poDS, pszName, pszFilename); |
274 | 279 | } |
275 | | }; |
276 | | |
277 | | /************************************************************************/ |
278 | | /* ==================================================================== */ |
279 | | /* PDS4EditableLayer */ |
280 | | /* ==================================================================== */ |
281 | | /************************************************************************/ |
282 | | |
283 | | class PDS4EditableLayer final : public OGREditableLayer |
284 | | { |
285 | | PDS4TableBaseLayer *GetBaseLayer() const; |
286 | | |
287 | | public: |
288 | | explicit PDS4EditableLayer( |
289 | | std::unique_ptr<PDS4FixedWidthTable> poBaseLayer); |
290 | | explicit PDS4EditableLayer(std::unique_ptr<PDS4DelimitedTable> poBaseLayer); |
291 | | ~PDS4EditableLayer() override; |
292 | | |
293 | | void RefreshFileAreaObservational(CPLXMLNode *psFAO) |
294 | 2.78k | { |
295 | 2.78k | GetBaseLayer()->RefreshFileAreaObservational(psFAO); |
296 | 2.78k | } |
297 | | |
298 | | const char *GetFileName() const |
299 | 2.78k | { |
300 | 2.78k | return GetBaseLayer()->GetFileName(); |
301 | 2.78k | } |
302 | | |
303 | | bool IsDirtyHeader() const |
304 | 2.78k | { |
305 | 2.78k | return GetBaseLayer()->IsDirtyHeader(); |
306 | 2.78k | } |
307 | | |
308 | | int GetRawFieldCount() const |
309 | 2.78k | { |
310 | 2.78k | return GetBaseLayer()->GetRawFieldCount(); |
311 | 2.78k | } |
312 | | |
313 | | void SetSpatialRef(OGRSpatialReference *poSRS); |
314 | | |
315 | | char **GetFileList() const |
316 | 2.40k | { |
317 | 2.40k | return GetBaseLayer()->GetFileList(); |
318 | 2.40k | } |
319 | | }; |
320 | | |
321 | | /************************************************************************/ |
322 | | /* PDS4Dataset */ |
323 | | /************************************************************************/ |
324 | | |
325 | | class PDS4Dataset final : public RawDataset |
326 | | { |
327 | | friend class PDS4RawRasterBand; |
328 | | friend class PDS4WrapperRasterBand; |
329 | | |
330 | | VSILFILE *m_fpImage = nullptr; |
331 | | vsi_l_offset m_nBaseOffset = 0; |
332 | | GDALDataset *m_poExternalDS = nullptr; // external dataset (GeoTIFF) |
333 | | OGRSpatialReference m_oSRS{}; |
334 | | bool m_bGotTransform = false; |
335 | | GDALGeoTransform m_gt{}; |
336 | | CPLString m_osXMLFilename{}; |
337 | | CPLString m_osImageFilename{}; |
338 | | CPLString m_osUnits{}; |
339 | | bool m_bCreatedFromExistingBinaryFile = false; |
340 | | |
341 | | std::vector<std::unique_ptr<PDS4EditableLayer>> m_apoLayers{}; |
342 | | |
343 | | // Write dedicated parameters |
344 | | bool m_bMustInitImageFile = false; |
345 | | bool m_bUseSrcLabel = true; |
346 | | bool m_bDirtyHeader = false; |
347 | | bool m_bCreateHeader = false; |
348 | | bool m_bStripFileAreaObservationalFromTemplate = false; |
349 | | bool m_bIsLSB = true; |
350 | | CPLString m_osHeaderParsingStandard{}; |
351 | | CPLString m_osInterleave{}; |
352 | | char **m_papszCreationOptions = nullptr; |
353 | | CPLString m_osXMLPDS4{}; |
354 | | |
355 | | void CreateHeader(CPLXMLNode *psProduct, const char *pszCARTVersion); |
356 | | void WriteHeader(); |
357 | | void WriteHeaderAppendCase(); |
358 | | void WriteVectorLayers(CPLXMLNode *psProduct); |
359 | | void WriteArray(const CPLString &osPrefix, CPLXMLNode *psFAO, |
360 | | const char *pszLocalIdentifier, |
361 | | CPLXMLNode *psTemplateSpecialConstants); |
362 | | void WriteGeoreferencing(CPLXMLNode *psCart, const char *pszCARTVersion); |
363 | | void ReadGeoreferencing(CPLXMLNode *psProduct); |
364 | | bool InitImageFile(); |
365 | | |
366 | | void SubstituteVariables(CPLXMLNode *psNode, char **papszDict); |
367 | | |
368 | | bool OpenTableCharacter(const char *pszFilename, const CPLXMLNode *psTable); |
369 | | |
370 | | bool OpenTableBinary(const char *pszFilename, const CPLXMLNode *psTable); |
371 | | |
372 | | bool OpenTableDelimited(const char *pszFilename, const CPLXMLNode *psTable); |
373 | | |
374 | | static std::unique_ptr<PDS4Dataset> |
375 | | CreateInternal(const char *pszFilename, GDALDataset *poSrcDS, int nXSize, |
376 | | int nYSize, int nBands, GDALDataType eType, |
377 | | const char *const *papszOptions); |
378 | | |
379 | | CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override; |
380 | | |
381 | | static std::unique_ptr<PDS4Dataset> OpenBrowse(GDALOpenInfo *, |
382 | | const CPLXMLNode *); |
383 | | |
384 | | CPL_DISALLOW_COPY_ASSIGN(PDS4Dataset) |
385 | | |
386 | | public: |
387 | | PDS4Dataset(); |
388 | | ~PDS4Dataset() override; |
389 | | |
390 | | int CloseDependentDatasets() override; |
391 | | |
392 | | const OGRSpatialReference *GetSpatialRef() const override; |
393 | | CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override; |
394 | | CPLErr GetGeoTransform(GDALGeoTransform >) const override; |
395 | | CPLErr SetGeoTransform(const GDALGeoTransform >) override; |
396 | | char **GetFileList() override; |
397 | | CPLErr SetMetadata(CSLConstList papszMD, |
398 | | const char *pszDomain = "") override; |
399 | | |
400 | | int GetLayerCount() const override |
401 | 66.8k | { |
402 | 66.8k | return static_cast<int>(m_apoLayers.size()); |
403 | 66.8k | } |
404 | | |
405 | | using GDALDataset::GetLayer; |
406 | | const OGRLayer *GetLayer(int) const override; |
407 | | |
408 | | OGRLayer *ICreateLayer(const char *pszName, |
409 | | const OGRGeomFieldDefn *poGeomFieldDefn, |
410 | | CSLConstList papszOptions) override; |
411 | | |
412 | | int TestCapability(const char *pszCap) const override; |
413 | | |
414 | | bool GetRawBinaryLayout(GDALDataset::RawBinaryLayout &) override; |
415 | | |
416 | | static std::unique_ptr<PDS4Dataset> OpenInternal(GDALOpenInfo *); |
417 | | |
418 | | static GDALDataset *Open(GDALOpenInfo *poOpenInfo) |
419 | 916 | { |
420 | 916 | return OpenInternal(poOpenInfo).release(); |
421 | 916 | } |
422 | | |
423 | | static GDALDataset *Create(const char *pszFilename, int nXSize, int nYSize, |
424 | | int nBands, GDALDataType eType, |
425 | | CSLConstList papszOptions); |
426 | | static GDALDataset *CreateCopy(const char *pszFilename, |
427 | | GDALDataset *poSrcDS, int bStrict, |
428 | | CSLConstList papszOptions, |
429 | | GDALProgressFunc pfnProgress, |
430 | | void *pProgressData); |
431 | | static CPLErr Delete(const char *pszName); |
432 | | |
433 | | const char *const *GetOpenOptions() const |
434 | 13.0k | { |
435 | 13.0k | return papszOpenOptions; |
436 | 13.0k | } |
437 | | |
438 | | void MarkHeaderDirty() |
439 | 25.6k | { |
440 | 25.6k | m_bDirtyHeader = true; |
441 | 25.6k | } |
442 | | }; |
443 | | |
444 | | /************************************************************************/ |
445 | | /* ==================================================================== */ |
446 | | /* PDS4RawRasterBand */ |
447 | | /* ==================================================================== */ |
448 | | /************************************************************************/ |
449 | | |
450 | | class PDS4RawRasterBand final : public RawRasterBand |
451 | | { |
452 | | friend class PDS4Dataset; |
453 | | |
454 | | bool m_bHasOffset{}; |
455 | | bool m_bHasScale{}; |
456 | | bool m_bHasNoData{}; |
457 | | bool m_bHasNoDataInt64{}; |
458 | | bool m_bHasNoDataUInt64{}; |
459 | | double m_dfOffset{}; |
460 | | double m_dfScale{}; |
461 | | double m_dfNoData{}; |
462 | | int64_t m_nNoDataInt64{}; |
463 | | uint64_t m_nNoDataUInt64{}; |
464 | | |
465 | | public: |
466 | | PDS4RawRasterBand(GDALDataset *l_poDS, int l_nBand, VSILFILE *l_fpRaw, |
467 | | vsi_l_offset l_nImgOffset, int l_nPixelOffset, |
468 | | int l_nLineOffset, GDALDataType l_eDataType, |
469 | | RawRasterBand::ByteOrder eByteOrderIn); |
470 | | |
471 | | CPLErr IWriteBlock(int, int, void *) override; |
472 | | |
473 | | CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, |
474 | | GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace, |
475 | | GDALRasterIOExtraArg *psExtraArg) override; |
476 | | |
477 | | double GetOffset(int *pbSuccess = nullptr) override; |
478 | | double GetScale(int *pbSuccess = nullptr) override; |
479 | | CPLErr SetOffset(double dfNewOffset) override; |
480 | | CPLErr SetScale(double dfNewScale) override; |
481 | | double GetNoDataValue(int *pbSuccess = nullptr) override; |
482 | | CPLErr SetNoDataValue(double dfNewNoData) override; |
483 | | int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override; |
484 | | uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override; |
485 | | CPLErr SetNoDataValueAsInt64(int64_t nNoData) override; |
486 | | CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override; |
487 | | |
488 | | const char *GetUnitType() override |
489 | 10 | { |
490 | 10 | return static_cast<PDS4Dataset *>(poDS)->m_osUnits.c_str(); |
491 | 10 | } |
492 | | |
493 | | CPLErr SetUnitType(const char *pszUnits) override |
494 | 1.32k | { |
495 | 1.32k | static_cast<PDS4Dataset *>(poDS)->m_osUnits = pszUnits; |
496 | 1.32k | return CE_None; |
497 | 1.32k | } |
498 | | |
499 | | void SetMaskBand(std::unique_ptr<GDALRasterBand> poMaskBand); |
500 | | }; |
501 | | |
502 | | /************************************************************************/ |
503 | | /* ==================================================================== */ |
504 | | /* PDS4BrowseImageProxyRasterBand */ |
505 | | /* */ |
506 | | /* proxy for bands stored in browse images */ |
507 | | /* ==================================================================== */ |
508 | | /************************************************************************/ |
509 | | class PDS4BrowseImageProxyRasterBand final : public GDALProxyRasterBand |
510 | | { |
511 | | friend class PDS4Dataset; |
512 | | |
513 | | GDALRasterBand *m_poBaseBand{}; |
514 | | |
515 | | CPL_DISALLOW_COPY_ASSIGN(PDS4BrowseImageProxyRasterBand) |
516 | | |
517 | | protected: |
518 | | GDALRasterBand *RefUnderlyingRasterBand(bool /*bForceOpen*/) const override; |
519 | | |
520 | | public: |
521 | | explicit PDS4BrowseImageProxyRasterBand(GDALRasterBand *poBaseBandIn); |
522 | | }; |
523 | | |
524 | | /************************************************************************/ |
525 | | /* ==================================================================== */ |
526 | | /* PDS4WrapperRasterBand */ |
527 | | /* */ |
528 | | /* proxy for bands stored in other formats. */ |
529 | | /* ==================================================================== */ |
530 | | /************************************************************************/ |
531 | | class PDS4WrapperRasterBand final : public GDALProxyRasterBand |
532 | | { |
533 | | friend class PDS4Dataset; |
534 | | |
535 | | GDALRasterBand *m_poBaseBand{}; |
536 | | bool m_bHasOffset{}; |
537 | | bool m_bHasScale{}; |
538 | | bool m_bHasNoData{}; |
539 | | bool m_bHasNoDataInt64{}; |
540 | | bool m_bHasNoDataUInt64{}; |
541 | | double m_dfOffset{}; |
542 | | double m_dfScale{1}; |
543 | | double m_dfNoData{}; |
544 | | int64_t m_nNoDataInt64{}; |
545 | | uint64_t m_nNoDataUInt64{}; |
546 | | |
547 | | CPL_DISALLOW_COPY_ASSIGN(PDS4WrapperRasterBand) |
548 | | |
549 | | protected: |
550 | | virtual GDALRasterBand * |
551 | | RefUnderlyingRasterBand(bool /*bForceOpen*/) const override |
552 | 0 | { |
553 | 0 | return m_poBaseBand; |
554 | 0 | } |
555 | | |
556 | | public: |
557 | | explicit PDS4WrapperRasterBand(GDALRasterBand *poBaseBandIn); |
558 | | |
559 | | virtual CPLErr Fill(double dfRealValue, |
560 | | double dfImaginaryValue = 0) override; |
561 | | CPLErr IWriteBlock(int, int, void *) override; |
562 | | |
563 | | CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, |
564 | | GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace, |
565 | | GDALRasterIOExtraArg *psExtraArg) override; |
566 | | |
567 | | double GetOffset(int *pbSuccess = nullptr) override; |
568 | | double GetScale(int *pbSuccess = nullptr) override; |
569 | | CPLErr SetOffset(double dfNewOffset) override; |
570 | | CPLErr SetScale(double dfNewScale) override; |
571 | | double GetNoDataValue(int *pbSuccess = nullptr) override; |
572 | | CPLErr SetNoDataValue(double dfNewNoData) override; |
573 | | int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override; |
574 | | uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override; |
575 | | CPLErr SetNoDataValueAsInt64(int64_t nNoData) override; |
576 | | CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override; |
577 | | |
578 | | const char *GetUnitType() override |
579 | 0 | { |
580 | 0 | return static_cast<PDS4Dataset *>(poDS)->m_osUnits.c_str(); |
581 | 0 | } |
582 | | |
583 | | CPLErr SetUnitType(const char *pszUnits) override |
584 | 0 | { |
585 | 0 | static_cast<PDS4Dataset *>(poDS)->m_osUnits = pszUnits; |
586 | 0 | return CE_None; |
587 | 0 | } |
588 | | |
589 | | int GetMaskFlags() override |
590 | 0 | { |
591 | 0 | return nMaskFlags; |
592 | 0 | } |
593 | | |
594 | | GDALRasterBand *GetMaskBand() override |
595 | 0 | { |
596 | 0 | return poMask; |
597 | 0 | } |
598 | | |
599 | | void SetMaskBand(std::unique_ptr<GDALRasterBand> poMaskBand); |
600 | | }; |
601 | | |
602 | | /************************************************************************/ |
603 | | /* ==================================================================== */ |
604 | | /* PDS4MaskBand */ |
605 | | /* ==================================================================== */ |
606 | | |
607 | | class PDS4MaskBand final : public GDALRasterBand |
608 | | { |
609 | | GDALRasterBand *m_poBaseBand{}; |
610 | | void *m_pBuffer{}; |
611 | | std::vector<double> m_adfConstants{}; |
612 | | |
613 | | CPL_DISALLOW_COPY_ASSIGN(PDS4MaskBand) |
614 | | |
615 | | public: |
616 | | PDS4MaskBand(GDALRasterBand *poBaseBand, |
617 | | const std::vector<double> &adfConstants); |
618 | | ~PDS4MaskBand() override; |
619 | | |
620 | | CPLErr IReadBlock(int, int, void *) override; |
621 | | }; |