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

Generated by: LCOV version 1.14