Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: Hierarchical Data Format Release 5 (HDF5) 4 : * Purpose: RAT utility 5 : * Author: Even Rouault <even dot rouault at spatialys dot com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2023, Even Rouault <even dot rouault at spatialys dot com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "rat.h" 14 : 15 : /************************************************************************/ 16 : /* CreateRAT() */ 17 : /************************************************************************/ 18 : 19 : std::unique_ptr<GDALRasterAttributeTable> 20 10 : HDF5CreateRAT(const std::shared_ptr<GDALMDArray> &poValues, 21 : bool bFirstColIsMinMax) 22 : { 23 20 : auto poRAT = std::make_unique<GDALDefaultRasterAttributeTable>(); 24 10 : const auto &poComponents = poValues->GetDataType().GetComponents(); 25 40 : for (const auto &poComponent : poComponents) 26 : { 27 : GDALRATFieldType eType; 28 30 : if (poComponent->GetType().GetClass() == GEDTC_NUMERIC) 29 : { 30 20 : if (GDALDataTypeIsInteger( 31 40 : poComponent->GetType().GetNumericDataType())) 32 10 : eType = GFT_Integer; 33 : else 34 10 : eType = GFT_Real; 35 : } 36 : else 37 : { 38 10 : eType = GFT_String; 39 : } 40 60 : poRAT->CreateColumn(poComponent->GetName().c_str(), eType, 41 12 : bFirstColIsMinMax && poRAT->GetColumnCount() == 0 42 : ? GFU_MinMax 43 30 : : GFU_Generic); 44 : } 45 : 46 10 : const auto &oValuesDT = poValues->GetDataType(); 47 20 : std::vector<GByte> abyRow(oValuesDT.GetSize()); 48 10 : const int nRows = static_cast<int>(poValues->GetDimensions()[0]->GetSize()); 49 54 : for (int iRow = 0; iRow < nRows; iRow++) 50 : { 51 44 : const GUInt64 arrayStartIdx = static_cast<GUInt64>(iRow); 52 44 : const size_t count = 1; 53 44 : const GInt64 arrayStep = 0; 54 44 : const GPtrDiff_t bufferStride = 0; 55 88 : poValues->Read(&arrayStartIdx, &count, &arrayStep, &bufferStride, 56 44 : oValuesDT, &abyRow[0]); 57 44 : int iCol = 0; 58 176 : for (const auto &poComponent : poComponents) 59 : { 60 132 : const auto eRATType = poRAT->GetTypeOfCol(iCol); 61 132 : if (eRATType == GFT_Integer) 62 : { 63 44 : int nValue = 0; 64 44 : GDALCopyWords(&abyRow[poComponent->GetOffset()], 65 44 : poComponent->GetType().GetNumericDataType(), 0, 66 : &nValue, GDT_Int32, 0, 1); 67 44 : poRAT->SetValue(iRow, iCol, nValue); 68 : } 69 88 : else if (eRATType == GFT_Real) 70 : { 71 44 : double dfValue = 0; 72 44 : GDALCopyWords(&abyRow[poComponent->GetOffset()], 73 44 : poComponent->GetType().GetNumericDataType(), 0, 74 : &dfValue, GDT_Float64, 0, 1); 75 44 : poRAT->SetValue(iRow, iCol, dfValue); 76 : } 77 : else 78 : { 79 44 : char *pszStr = nullptr; 80 88 : GDALExtendedDataType::CopyValue( 81 44 : &abyRow[poComponent->GetOffset()], poComponent->GetType(), 82 88 : &pszStr, GDALExtendedDataType::CreateString()); 83 44 : if (pszStr) 84 : { 85 44 : poRAT->SetValue(iRow, iCol, pszStr); 86 : } 87 44 : CPLFree(pszStr); 88 : } 89 132 : iCol++; 90 : } 91 44 : oValuesDT.FreeDynamicMemory(&abyRow[0]); 92 : } 93 20 : return poRAT; 94 : }