LCOV - code coverage report
Current view: top level - frmts/hdf5 - rat.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 55 80 68.8 %
Date: 2025-11-16 23:43:36 Functions: 1 1 100.0 %

          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             : #include "ogr_p.h"
      15             : 
      16             : #include <cmath>
      17             : 
      18             : /************************************************************************/
      19             : /*                             CreateRAT()                              */
      20             : /************************************************************************/
      21             : 
      22             : std::unique_ptr<GDALRasterAttributeTable>
      23          11 : HDF5CreateRAT(const std::shared_ptr<GDALMDArray> &poValues,
      24             :               bool bFirstColIsMinMax)
      25             : {
      26          22 :     auto poRAT = std::make_unique<GDALDefaultRasterAttributeTable>();
      27          11 :     const auto &poComponents = poValues->GetDataType().GetComponents();
      28          42 :     for (const auto &poComponent : poComponents)
      29             :     {
      30             :         GDALRATFieldType eType;
      31          31 :         if (poComponent->GetType().GetClass() == GEDTC_NUMERIC)
      32             :         {
      33          21 :             if (GDALDataTypeIsInteger(
      34          42 :                     poComponent->GetType().GetNumericDataType()))
      35             :             {
      36             :                 // S102 featureAttributeTable
      37          11 :                 if (poComponent->GetName() ==
      38             :                         "featuresDetected."
      39          11 :                         "leastDepthOfDetectedFeaturesMeasured" ||
      40          11 :                     poComponent->GetName() ==
      41          11 :                         "featuresDetected.significantFeaturesDetected" ||
      42          33 :                     poComponent->GetName() == "fullSeafloorCoverageAchieved" ||
      43          11 :                     poComponent->GetName() == "bathyCoverage")
      44             :                 {
      45           0 :                     eType = GFT_Boolean;
      46             :                 }
      47             :                 else
      48             :                 {
      49          11 :                     eType = GFT_Integer;
      50             :                 }
      51             :             }
      52             :             else
      53          10 :                 eType = GFT_Real;
      54             :         }
      55             :         else
      56             :         {
      57             :             // S102 featureAttributeTable
      58          20 :             if (poComponent->GetName() == "surveyDateRange.dateStart" ||
      59          10 :                 poComponent->GetName() == "surveyDateRange.dateEnd")
      60           0 :                 eType = GFT_DateTime;
      61             :             else
      62          10 :                 eType = GFT_String;
      63             :         }
      64          62 :         poRAT->CreateColumn(poComponent->GetName().c_str(), eType,
      65          13 :                             bFirstColIsMinMax && poRAT->GetColumnCount() == 0
      66             :                                 ? GFU_MinMax
      67          31 :                                 : GFU_Generic);
      68             :     }
      69             : 
      70          11 :     const auto &oValuesDT = poValues->GetDataType();
      71          22 :     std::vector<GByte> abyRow(oValuesDT.GetSize());
      72          11 :     const int nRows = static_cast<int>(poValues->GetDimensions()[0]->GetSize());
      73          63 :     for (int iRow = 0; iRow < nRows; iRow++)
      74             :     {
      75          52 :         const GUInt64 arrayStartIdx = static_cast<GUInt64>(iRow);
      76          52 :         const size_t count = 1;
      77          52 :         const GInt64 arrayStep = 0;
      78          52 :         const GPtrDiff_t bufferStride = 0;
      79         104 :         poValues->Read(&arrayStartIdx, &count, &arrayStep, &bufferStride,
      80          52 :                        oValuesDT, &abyRow[0]);
      81          52 :         int iCol = 0;
      82         192 :         for (const auto &poComponent : poComponents)
      83             :         {
      84         140 :             const auto eRATType = poRAT->GetTypeOfCol(iCol);
      85         140 :             if (eRATType == GFT_Integer || eRATType == GFT_Boolean)
      86             :             {
      87          52 :                 int nValue = 0;
      88          52 :                 GDALCopyWords(&abyRow[poComponent->GetOffset()],
      89          52 :                               poComponent->GetType().GetNumericDataType(), 0,
      90             :                               &nValue, GDT_Int32, 0, 1);
      91          52 :                 poRAT->SetValue(iRow, iCol, nValue);
      92             :             }
      93          88 :             else if (eRATType == GFT_Real)
      94             :             {
      95          44 :                 double dfValue = 0;
      96          44 :                 GDALCopyWords(&abyRow[poComponent->GetOffset()],
      97          44 :                               poComponent->GetType().GetNumericDataType(), 0,
      98             :                               &dfValue, GDT_Float64, 0, 1);
      99          44 :                 poRAT->SetValue(iRow, iCol, dfValue);
     100             :             }
     101             :             else
     102             :             {
     103          44 :                 char *pszStr = nullptr;
     104          88 :                 GDALExtendedDataType::CopyValue(
     105          44 :                     &abyRow[poComponent->GetOffset()], poComponent->GetType(),
     106          88 :                     &pszStr, GDALExtendedDataType::CreateString());
     107          44 :                 if (pszStr)
     108             :                 {
     109          44 :                     if (eRATType == GFT_DateTime)
     110             :                     {
     111           0 :                         GDALRATDateTime sDateTime;
     112           0 :                         if (strlen(pszStr) == 8 &&
     113           0 :                             sscanf(pszStr, "%04d%02d%02d", &(sDateTime.nYear),
     114             :                                    &(sDateTime.nMonth), &(sDateTime.nDay)) == 3)
     115             :                         {
     116           0 :                             sDateTime.bPositiveTimeZone = true;
     117           0 :                             sDateTime.bIsValid = true;
     118             :                         }
     119             :                         else
     120             :                         {
     121             :                             OGRField sField;
     122           0 :                             if (OGRParseDate(pszStr, &sField, 0))
     123             :                             {
     124           0 :                                 sDateTime.nYear = sField.Date.Year;
     125           0 :                                 sDateTime.nMonth = sField.Date.Month;
     126           0 :                                 sDateTime.nDay = sField.Date.Day;
     127           0 :                                 sDateTime.nHour = sField.Date.Hour;
     128           0 :                                 sDateTime.nMinute = sField.Date.Minute;
     129           0 :                                 sDateTime.fSecond = sField.Date.Second;
     130           0 :                                 sDateTime.bPositiveTimeZone =
     131           0 :                                     sField.Date.TZFlag >= 100 ||
     132           0 :                                     sField.Date.TZFlag <= 2;
     133           0 :                                 if (sField.Date.TZFlag > 2)
     134             :                                 {
     135           0 :                                     sDateTime.nTimeZoneHour =
     136           0 :                                         std::abs(sField.Date.TZFlag - 100) / 4;
     137           0 :                                     sDateTime.nTimeZoneMinute =
     138           0 :                                         (std::abs(sField.Date.TZFlag - 100) %
     139           0 :                                          4) *
     140             :                                         15;
     141             :                                 }
     142           0 :                                 sDateTime.bIsValid = true;
     143             :                             }
     144             :                         }
     145           0 :                         poRAT->SetValue(iRow, iCol, sDateTime);
     146             :                     }
     147             :                     else
     148             :                     {
     149          44 :                         poRAT->SetValue(iRow, iCol, pszStr);
     150             :                     }
     151             :                 }
     152          44 :                 CPLFree(pszStr);
     153             :             }
     154         140 :             iCol++;
     155             :         }
     156          52 :         oValuesDT.FreeDynamicMemory(&abyRow[0]);
     157             :     }
     158          22 :     return poRAT;
     159             : }

Generated by: LCOV version 1.14