LCOV - code coverage report
Current view: top level - gcore/multidim - gdalmultidim_c_api_array.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 319 346 92.2 %
Date: 2026-04-15 22:10:00 Functions: 59 65 90.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Name:     gdalmultidim_c_api_array.cpp
       4             :  * Project:  GDAL Core
       5             :  * Purpose:  C API for GDALMDArray
       6             :  * Author:   Even Rouault <even.rouault at spatialys.com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "gdal_multidim.h"
      15             : #include "gdalmultidim_priv.h"
      16             : #include "gdal_fwd.h"
      17             : 
      18             : /************************************************************************/
      19             : /*                         GDALMDArrayRelease()                         */
      20             : /************************************************************************/
      21             : 
      22             : /** Release the GDAL in-memory object associated with a GDALMDArray.
      23             :  *
      24             :  * Note: when applied on a object coming from a driver, this does not
      25             :  * destroy the object in the file, database, etc...
      26             :  */
      27        3087 : void GDALMDArrayRelease(GDALMDArrayH hMDArray)
      28             : {
      29        3087 :     delete hMDArray;
      30        3087 : }
      31             : 
      32             : /************************************************************************/
      33             : /*                         GDALMDArrayGetName()                         */
      34             : /************************************************************************/
      35             : 
      36             : /** Return array name.
      37             :  *
      38             :  * This is the same as the C++ method GDALMDArray::GetName()
      39             :  */
      40          84 : const char *GDALMDArrayGetName(GDALMDArrayH hArray)
      41             : {
      42          84 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
      43          84 :     return hArray->m_poImpl->GetName().c_str();
      44             : }
      45             : 
      46             : /************************************************************************/
      47             : /*                       GDALMDArrayGetFullName()                       */
      48             : /************************************************************************/
      49             : 
      50             : /** Return array full name.
      51             :  *
      52             :  * This is the same as the C++ method GDALMDArray::GetFullName()
      53             :  */
      54          71 : const char *GDALMDArrayGetFullName(GDALMDArrayH hArray)
      55             : {
      56          71 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
      57          71 :     return hArray->m_poImpl->GetFullName().c_str();
      58             : }
      59             : 
      60             : /************************************************************************/
      61             : /*                         GDALMDArrayGetName()                         */
      62             : /************************************************************************/
      63             : 
      64             : /** Return the total number of values in the array.
      65             :  *
      66             :  * This is the same as the C++ method
      67             :  * GDALAbstractMDArray::GetTotalElementsCount()
      68             :  */
      69           6 : GUInt64 GDALMDArrayGetTotalElementsCount(GDALMDArrayH hArray)
      70             : {
      71           6 :     VALIDATE_POINTER1(hArray, __func__, 0);
      72           6 :     return hArray->m_poImpl->GetTotalElementsCount();
      73             : }
      74             : 
      75             : /************************************************************************/
      76             : /*                    GDALMDArrayGetDimensionCount()                    */
      77             : /************************************************************************/
      78             : 
      79             : /** Return the number of dimensions.
      80             :  *
      81             :  * This is the same as the C++ method GDALAbstractMDArray::GetDimensionCount()
      82             :  */
      83       16476 : size_t GDALMDArrayGetDimensionCount(GDALMDArrayH hArray)
      84             : {
      85       16476 :     VALIDATE_POINTER1(hArray, __func__, 0);
      86       16476 :     return hArray->m_poImpl->GetDimensionCount();
      87             : }
      88             : 
      89             : /************************************************************************/
      90             : /*                      GDALMDArrayGetDimensions()                      */
      91             : /************************************************************************/
      92             : 
      93             : /** Return the dimensions of the array
      94             :  *
      95             :  * The returned array must be freed with GDALReleaseDimensions(). If only the
      96             :  * array itself needs to be freed, CPLFree() should be called (and
      97             :  * GDALDimensionRelease() on individual array members).
      98             :  *
      99             :  * This is the same as the C++ method GDALAbstractMDArray::GetDimensions()
     100             :  *
     101             :  * @param hArray Array.
     102             :  * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
     103             :  *
     104             :  * @return an array of *pnCount dimensions.
     105             :  */
     106        3530 : GDALDimensionH *GDALMDArrayGetDimensions(GDALMDArrayH hArray, size_t *pnCount)
     107             : {
     108        3530 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     109        3530 :     VALIDATE_POINTER1(pnCount, __func__, nullptr);
     110        3530 :     const auto &dims(hArray->m_poImpl->GetDimensions());
     111             :     auto ret = static_cast<GDALDimensionH *>(
     112        3530 :         CPLMalloc(sizeof(GDALDimensionH) * dims.size()));
     113       10126 :     for (size_t i = 0; i < dims.size(); i++)
     114             :     {
     115        6596 :         ret[i] = new GDALDimensionHS(dims[i]);
     116             :     }
     117        3530 :     *pnCount = dims.size();
     118        3530 :     return ret;
     119             : }
     120             : 
     121             : /************************************************************************/
     122             : /*                       GDALMDArrayGetDataType()                       */
     123             : /************************************************************************/
     124             : 
     125             : /** Return the data type
     126             :  *
     127             :  * The return must be freed with GDALExtendedDataTypeRelease().
     128             :  */
     129        6240 : GDALExtendedDataTypeH GDALMDArrayGetDataType(GDALMDArrayH hArray)
     130             : {
     131        6240 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     132             :     return new GDALExtendedDataTypeHS(
     133        6240 :         new GDALExtendedDataType(hArray->m_poImpl->GetDataType()));
     134             : }
     135             : 
     136             : /************************************************************************/
     137             : /*                          GDALMDArrayRead()                           */
     138             : /************************************************************************/
     139             : 
     140             : /** Read part or totality of a multidimensional array.
     141             :  *
     142             :  * This is the same as the C++ method GDALAbstractMDArray::Read()
     143             :  *
     144             :  * @return TRUE in case of success.
     145             :  */
     146        3036 : int GDALMDArrayRead(GDALMDArrayH hArray, const GUInt64 *arrayStartIdx,
     147             :                     const size_t *count, const GInt64 *arrayStep,
     148             :                     const GPtrDiff_t *bufferStride,
     149             :                     GDALExtendedDataTypeH bufferDataType, void *pDstBuffer,
     150             :                     const void *pDstBufferAllocStart,
     151             :                     size_t nDstBufferAllocSize)
     152             : {
     153        3036 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     154        3036 :     if ((arrayStartIdx == nullptr || count == nullptr) &&
     155           0 :         hArray->m_poImpl->GetDimensionCount() > 0)
     156             :     {
     157           0 :         VALIDATE_POINTER1(arrayStartIdx, __func__, FALSE);
     158           0 :         VALIDATE_POINTER1(count, __func__, FALSE);
     159             :     }
     160        3036 :     VALIDATE_POINTER1(bufferDataType, __func__, FALSE);
     161        3036 :     VALIDATE_POINTER1(pDstBuffer, __func__, FALSE);
     162        6072 :     return hArray->m_poImpl->Read(arrayStartIdx, count, arrayStep, bufferStride,
     163        3036 :                                   *(bufferDataType->m_poImpl), pDstBuffer,
     164        3036 :                                   pDstBufferAllocStart, nDstBufferAllocSize);
     165             : }
     166             : 
     167             : /************************************************************************/
     168             : /*                          GDALMDArrayWrite()                          */
     169             : /************************************************************************/
     170             : 
     171             : /** Write part or totality of a multidimensional array.
     172             :  *
     173             :  * This is the same as the C++ method GDALAbstractMDArray::Write()
     174             :  *
     175             :  * @return TRUE in case of success.
     176             :  */
     177         897 : int GDALMDArrayWrite(GDALMDArrayH hArray, const GUInt64 *arrayStartIdx,
     178             :                      const size_t *count, const GInt64 *arrayStep,
     179             :                      const GPtrDiff_t *bufferStride,
     180             :                      GDALExtendedDataTypeH bufferDataType,
     181             :                      const void *pSrcBuffer, const void *pSrcBufferAllocStart,
     182             :                      size_t nSrcBufferAllocSize)
     183             : {
     184         897 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     185         897 :     if ((arrayStartIdx == nullptr || count == nullptr) &&
     186           0 :         hArray->m_poImpl->GetDimensionCount() > 0)
     187             :     {
     188           0 :         VALIDATE_POINTER1(arrayStartIdx, __func__, FALSE);
     189           0 :         VALIDATE_POINTER1(count, __func__, FALSE);
     190             :     }
     191         897 :     VALIDATE_POINTER1(bufferDataType, __func__, FALSE);
     192         897 :     VALIDATE_POINTER1(pSrcBuffer, __func__, FALSE);
     193        1794 :     return hArray->m_poImpl->Write(arrayStartIdx, count, arrayStep,
     194         897 :                                    bufferStride, *(bufferDataType->m_poImpl),
     195             :                                    pSrcBuffer, pSrcBufferAllocStart,
     196         897 :                                    nSrcBufferAllocSize);
     197             : }
     198             : 
     199             : /************************************************************************/
     200             : /*                       GDALMDArrayAdviseRead()                        */
     201             : /************************************************************************/
     202             : 
     203             : /** Advise driver of upcoming read requests.
     204             :  *
     205             :  * This is the same as the C++ method GDALMDArray::AdviseRead()
     206             :  *
     207             :  * @return TRUE in case of success.
     208             :  *
     209             :  * @since GDAL 3.2
     210             :  */
     211           0 : int GDALMDArrayAdviseRead(GDALMDArrayH hArray, const GUInt64 *arrayStartIdx,
     212             :                           const size_t *count)
     213             : {
     214           0 :     return GDALMDArrayAdviseReadEx(hArray, arrayStartIdx, count, nullptr);
     215             : }
     216             : 
     217             : /************************************************************************/
     218             : /*                      GDALMDArrayAdviseReadEx()                       */
     219             : /************************************************************************/
     220             : 
     221             : /** Advise driver of upcoming read requests.
     222             :  *
     223             :  * This is the same as the C++ method GDALMDArray::AdviseRead()
     224             :  *
     225             :  * @return TRUE in case of success.
     226             :  *
     227             :  * @since GDAL 3.4
     228             :  */
     229          19 : int GDALMDArrayAdviseReadEx(GDALMDArrayH hArray, const GUInt64 *arrayStartIdx,
     230             :                             const size_t *count, CSLConstList papszOptions)
     231             : {
     232          19 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     233          19 :     return hArray->m_poImpl->AdviseRead(arrayStartIdx, count, papszOptions);
     234             : }
     235             : 
     236             : /************************************************************************/
     237             : /*                      GDALMDArrayGetAttribute()                       */
     238             : /************************************************************************/
     239             : 
     240             : /** Return an attribute by its name.
     241             :  *
     242             :  * This is the same as the C++ method GDALIHasAttribute::GetAttribute()
     243             :  *
     244             :  * The returned attribute must be freed with GDALAttributeRelease().
     245             :  */
     246         120 : GDALAttributeH GDALMDArrayGetAttribute(GDALMDArrayH hArray, const char *pszName)
     247             : {
     248         120 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     249         120 :     VALIDATE_POINTER1(pszName, __func__, nullptr);
     250         360 :     auto attr = hArray->m_poImpl->GetAttribute(std::string(pszName));
     251         120 :     if (attr)
     252         111 :         return new GDALAttributeHS(attr);
     253           9 :     return nullptr;
     254             : }
     255             : 
     256             : /************************************************************************/
     257             : /*                      GDALMDArrayGetAttributes()                      */
     258             : /************************************************************************/
     259             : 
     260             : /** Return the list of attributes contained in this array.
     261             :  *
     262             :  * The returned array must be freed with GDALReleaseAttributes(). If only the
     263             :  * array itself needs to be freed, CPLFree() should be called (and
     264             :  * GDALAttributeRelease() on individual array members).
     265             :  *
     266             :  * This is the same as the C++ method GDALMDArray::GetAttributes().
     267             :  *
     268             :  * @param hArray Array.
     269             :  * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
     270             :  * @param papszOptions Driver specific options determining how attributes
     271             :  * should be retrieved. Pass nullptr for default behavior.
     272             :  *
     273             :  * @return an array of *pnCount attributes.
     274             :  */
     275          59 : GDALAttributeH *GDALMDArrayGetAttributes(GDALMDArrayH hArray, size_t *pnCount,
     276             :                                          CSLConstList papszOptions)
     277             : {
     278          59 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     279          59 :     VALIDATE_POINTER1(pnCount, __func__, nullptr);
     280          59 :     auto attrs = hArray->m_poImpl->GetAttributes(papszOptions);
     281             :     auto ret = static_cast<GDALAttributeH *>(
     282          59 :         CPLMalloc(sizeof(GDALAttributeH) * attrs.size()));
     283         189 :     for (size_t i = 0; i < attrs.size(); i++)
     284             :     {
     285         130 :         ret[i] = new GDALAttributeHS(attrs[i]);
     286             :     }
     287          59 :     *pnCount = attrs.size();
     288          59 :     return ret;
     289             : }
     290             : 
     291             : /************************************************************************/
     292             : /*                     GDALMDArrayCreateAttribute()                     */
     293             : /************************************************************************/
     294             : 
     295             : /** Create a attribute within an array.
     296             :  *
     297             :  * This is the same as the C++ method GDALMDArray::CreateAttribute().
     298             :  *
     299             :  * @return the attribute, to be freed with GDALAttributeRelease(), or nullptr.
     300             :  */
     301         188 : GDALAttributeH GDALMDArrayCreateAttribute(GDALMDArrayH hArray,
     302             :                                           const char *pszName,
     303             :                                           size_t nDimensions,
     304             :                                           const GUInt64 *panDimensions,
     305             :                                           GDALExtendedDataTypeH hEDT,
     306             :                                           CSLConstList papszOptions)
     307             : {
     308         188 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     309         188 :     VALIDATE_POINTER1(pszName, __func__, nullptr);
     310         188 :     VALIDATE_POINTER1(hEDT, __func__, nullptr);
     311         376 :     std::vector<GUInt64> dims;
     312         188 :     dims.reserve(nDimensions);
     313         249 :     for (size_t i = 0; i < nDimensions; i++)
     314          61 :         dims.push_back(panDimensions[i]);
     315         188 :     auto ret = hArray->m_poImpl->CreateAttribute(
     316         564 :         std::string(pszName), dims, *(hEDT->m_poImpl), papszOptions);
     317         188 :     if (!ret)
     318           9 :         return nullptr;
     319         179 :     return new GDALAttributeHS(ret);
     320             : }
     321             : 
     322             : /************************************************************************/
     323             : /*                     GDALMDArrayDeleteAttribute()                     */
     324             : /************************************************************************/
     325             : 
     326             : /** Delete an attribute from an array.
     327             :  *
     328             :  * After this call, if a previously obtained instance of the deleted object
     329             :  * is still alive, no method other than for freeing it should be invoked.
     330             :  *
     331             :  * This is the same as the C++ method GDALMDArray::DeleteAttribute().
     332             :  *
     333             :  * @return true in case of success.
     334             :  * @since GDAL 3.8
     335             :  */
     336          24 : bool GDALMDArrayDeleteAttribute(GDALMDArrayH hArray, const char *pszName,
     337             :                                 CSLConstList papszOptions)
     338             : {
     339          24 :     VALIDATE_POINTER1(hArray, __func__, false);
     340          24 :     VALIDATE_POINTER1(pszName, __func__, false);
     341          48 :     return hArray->m_poImpl->DeleteAttribute(std::string(pszName),
     342          24 :                                              papszOptions);
     343             : }
     344             : 
     345             : /************************************************************************/
     346             : /*                    GDALMDArrayGetRawNoDataValue()                    */
     347             : /************************************************************************/
     348             : 
     349             : /** Return the nodata value as a "raw" value.
     350             :  *
     351             :  * The value returned might be nullptr in case of no nodata value. When
     352             :  * a nodata value is registered, a non-nullptr will be returned whose size in
     353             :  * bytes is GetDataType().GetSize().
     354             :  *
     355             :  * The returned value should not be modified or freed.
     356             :  *
     357             :  * This is the same as the ++ method GDALMDArray::GetRawNoDataValue().
     358             :  *
     359             :  * @return nullptr or a pointer to GetDataType().GetSize() bytes.
     360             :  */
     361          79 : const void *GDALMDArrayGetRawNoDataValue(GDALMDArrayH hArray)
     362             : {
     363          79 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     364          79 :     return hArray->m_poImpl->GetRawNoDataValue();
     365             : }
     366             : 
     367             : /************************************************************************/
     368             : /*                 GDALMDArrayGetNoDataValueAsDouble()                  */
     369             : /************************************************************************/
     370             : 
     371             : /** Return the nodata value as a double.
     372             :  *
     373             :  * The value returned might be nullptr in case of no nodata value. When
     374             :  * a nodata value is registered, a non-nullptr will be returned whose size in
     375             :  * bytes is GetDataType().GetSize().
     376             :  *
     377             :  * This is the same as the C++ method GDALMDArray::GetNoDataValueAsDouble().
     378             :  *
     379             :  * @param hArray Array handle.
     380             :  * @param pbHasNoDataValue Pointer to a output boolean that will be set to true
     381             :  * if a nodata value exists and can be converted to double. Might be nullptr.
     382             :  *
     383             :  * @return the nodata value as a double. A 0.0 value might also indicate the
     384             :  * absence of a nodata value or an error in the conversion (*pbHasNoDataValue
     385             :  * will be set to false then).
     386             :  */
     387         124 : double GDALMDArrayGetNoDataValueAsDouble(GDALMDArrayH hArray,
     388             :                                          int *pbHasNoDataValue)
     389             : {
     390         124 :     VALIDATE_POINTER1(hArray, __func__, 0);
     391         124 :     bool bHasNodataValue = false;
     392         124 :     double ret = hArray->m_poImpl->GetNoDataValueAsDouble(&bHasNodataValue);
     393         124 :     if (pbHasNoDataValue)
     394         124 :         *pbHasNoDataValue = bHasNodataValue;
     395         124 :     return ret;
     396             : }
     397             : 
     398             : /************************************************************************/
     399             : /*                  GDALMDArrayGetNoDataValueAsInt64()                  */
     400             : /************************************************************************/
     401             : 
     402             : /** Return the nodata value as a Int64.
     403             :  *
     404             :  * This is the same as the C++ method GDALMDArray::GetNoDataValueAsInt64().
     405             :  *
     406             :  * @param hArray Array handle.
     407             :  * @param pbHasNoDataValue Pointer to a output boolean that will be set to true
     408             :  * if a nodata value exists and can be converted to Int64. Might be nullptr.
     409             :  *
     410             :  * @return the nodata value as a Int64.
     411             :  * @since GDAL 3.5
     412             :  */
     413          13 : int64_t GDALMDArrayGetNoDataValueAsInt64(GDALMDArrayH hArray,
     414             :                                          int *pbHasNoDataValue)
     415             : {
     416          13 :     VALIDATE_POINTER1(hArray, __func__, 0);
     417          13 :     bool bHasNodataValue = false;
     418          13 :     const auto ret = hArray->m_poImpl->GetNoDataValueAsInt64(&bHasNodataValue);
     419          13 :     if (pbHasNoDataValue)
     420          13 :         *pbHasNoDataValue = bHasNodataValue;
     421          13 :     return ret;
     422             : }
     423             : 
     424             : /************************************************************************/
     425             : /*                 GDALMDArrayGetNoDataValueAsUInt64()                  */
     426             : /************************************************************************/
     427             : 
     428             : /** Return the nodata value as a UInt64.
     429             :  *
     430             :  * This is the same as the C++ method GDALMDArray::GetNoDataValueAsInt64().
     431             :  *
     432             :  * @param hArray Array handle.
     433             :  * @param pbHasNoDataValue Pointer to a output boolean that will be set to true
     434             :  * if a nodata value exists and can be converted to UInt64. Might be nullptr.
     435             :  *
     436             :  * @return the nodata value as a UInt64.
     437             :  * @since GDAL 3.5
     438             :  */
     439           7 : uint64_t GDALMDArrayGetNoDataValueAsUInt64(GDALMDArrayH hArray,
     440             :                                            int *pbHasNoDataValue)
     441             : {
     442           7 :     VALIDATE_POINTER1(hArray, __func__, 0);
     443           7 :     bool bHasNodataValue = false;
     444           7 :     const auto ret = hArray->m_poImpl->GetNoDataValueAsUInt64(&bHasNodataValue);
     445           7 :     if (pbHasNoDataValue)
     446           7 :         *pbHasNoDataValue = bHasNodataValue;
     447           7 :     return ret;
     448             : }
     449             : 
     450             : /************************************************************************/
     451             : /*                    GDALMDArraySetRawNoDataValue()                    */
     452             : /************************************************************************/
     453             : 
     454             : /** Set the nodata value as a "raw" value.
     455             :  *
     456             :  * This is the same as the C++ method GDALMDArray::SetRawNoDataValue(const
     457             :  * void*).
     458             :  *
     459             :  * @return TRUE in case of success.
     460             :  */
     461          15 : int GDALMDArraySetRawNoDataValue(GDALMDArrayH hArray, const void *pNoData)
     462             : {
     463          15 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     464          15 :     return hArray->m_poImpl->SetRawNoDataValue(pNoData);
     465             : }
     466             : 
     467             : /************************************************************************/
     468             : /*                 GDALMDArraySetNoDataValueAsDouble()                  */
     469             : /************************************************************************/
     470             : 
     471             : /** Set the nodata value as a double.
     472             :  *
     473             :  * If the natural data type of the attribute/array is not double, type
     474             :  * conversion will occur to the type returned by GetDataType().
     475             :  *
     476             :  * This is the same as the C++ method GDALMDArray::SetNoDataValue(double).
     477             :  *
     478             :  * @return TRUE in case of success.
     479             :  */
     480          58 : int GDALMDArraySetNoDataValueAsDouble(GDALMDArrayH hArray, double dfNoDataValue)
     481             : {
     482          58 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     483          58 :     return hArray->m_poImpl->SetNoDataValue(dfNoDataValue);
     484             : }
     485             : 
     486             : /************************************************************************/
     487             : /*                  GDALMDArraySetNoDataValueAsInt64()                  */
     488             : /************************************************************************/
     489             : 
     490             : /** Set the nodata value as a Int64.
     491             :  *
     492             :  * If the natural data type of the attribute/array is not Int64, type conversion
     493             :  * will occur to the type returned by GetDataType().
     494             :  *
     495             :  * This is the same as the C++ method GDALMDArray::SetNoDataValue(int64_t).
     496             :  *
     497             :  * @return TRUE in case of success.
     498             :  * @since GDAL 3.5
     499             :  */
     500           1 : int GDALMDArraySetNoDataValueAsInt64(GDALMDArrayH hArray, int64_t nNoDataValue)
     501             : {
     502           1 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     503           1 :     return hArray->m_poImpl->SetNoDataValue(nNoDataValue);
     504             : }
     505             : 
     506             : /************************************************************************/
     507             : /*                 GDALMDArraySetNoDataValueAsUInt64()                  */
     508             : /************************************************************************/
     509             : 
     510             : /** Set the nodata value as a UInt64.
     511             :  *
     512             :  * If the natural data type of the attribute/array is not UInt64, type
     513             :  * conversion will occur to the type returned by GetDataType().
     514             :  *
     515             :  * This is the same as the C++ method GDALMDArray::SetNoDataValue(uint64_t).
     516             :  *
     517             :  * @return TRUE in case of success.
     518             :  * @since GDAL 3.5
     519             :  */
     520           1 : int GDALMDArraySetNoDataValueAsUInt64(GDALMDArrayH hArray,
     521             :                                       uint64_t nNoDataValue)
     522             : {
     523           1 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     524           1 :     return hArray->m_poImpl->SetNoDataValue(nNoDataValue);
     525             : }
     526             : 
     527             : /************************************************************************/
     528             : /*                         GDALMDArrayResize()                          */
     529             : /************************************************************************/
     530             : 
     531             : /** Resize an array to new dimensions.
     532             :  *
     533             :  * Not all drivers may allow this operation, and with restrictions (e.g.
     534             :  * for netCDF, this is limited to growing of "unlimited" dimensions)
     535             :  *
     536             :  * Resizing a dimension used in other arrays will cause those other arrays
     537             :  * to be resized.
     538             :  *
     539             :  * This is the same as the C++ method GDALMDArray::Resize().
     540             :  *
     541             :  * @param hArray Array.
     542             :  * @param panNewDimSizes Array of GetDimensionCount() values containing the
     543             :  *                       new size of each indexing dimension.
     544             :  * @param papszOptions Options. (Driver specific)
     545             :  * @return true in case of success.
     546             :  * @since GDAL 3.7
     547             :  */
     548          42 : bool GDALMDArrayResize(GDALMDArrayH hArray, const GUInt64 *panNewDimSizes,
     549             :                        CSLConstList papszOptions)
     550             : {
     551          42 :     VALIDATE_POINTER1(hArray, __func__, false);
     552          42 :     VALIDATE_POINTER1(panNewDimSizes, __func__, false);
     553          84 :     std::vector<GUInt64> anNewDimSizes(hArray->m_poImpl->GetDimensionCount());
     554         125 :     for (size_t i = 0; i < anNewDimSizes.size(); ++i)
     555             :     {
     556          83 :         anNewDimSizes[i] = panNewDimSizes[i];
     557             :     }
     558          42 :     return hArray->m_poImpl->Resize(anNewDimSizes, papszOptions);
     559             : }
     560             : 
     561             : /************************************************************************/
     562             : /*                        GDALMDArraySetScale()                         */
     563             : /************************************************************************/
     564             : 
     565             : /** Set the scale value to apply to raw values.
     566             :  *
     567             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     568             :  *
     569             :  * This is the same as the C++ method GDALMDArray::SetScale().
     570             :  *
     571             :  * @return TRUE in case of success.
     572             :  */
     573           0 : int GDALMDArraySetScale(GDALMDArrayH hArray, double dfScale)
     574             : {
     575           0 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     576           0 :     return hArray->m_poImpl->SetScale(dfScale);
     577             : }
     578             : 
     579             : /************************************************************************/
     580             : /*                       GDALMDArraySetScaleEx()                        */
     581             : /************************************************************************/
     582             : 
     583             : /** Set the scale value to apply to raw values.
     584             :  *
     585             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     586             :  *
     587             :  * This is the same as the C++ method GDALMDArray::SetScale().
     588             :  *
     589             :  * @return TRUE in case of success.
     590             :  * @since GDAL 3.3
     591             :  */
     592          21 : int GDALMDArraySetScaleEx(GDALMDArrayH hArray, double dfScale,
     593             :                           GDALDataType eStorageType)
     594             : {
     595          21 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     596          21 :     return hArray->m_poImpl->SetScale(dfScale, eStorageType);
     597             : }
     598             : 
     599             : /************************************************************************/
     600             : /*                        GDALMDArraySetOffset()                        */
     601             : /************************************************************************/
     602             : 
     603             : /** Set the scale value to apply to raw values.
     604             :  *
     605             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     606             :  *
     607             :  * This is the same as the C++ method GDALMDArray::SetOffset().
     608             :  *
     609             :  * @return TRUE in case of success.
     610             :  */
     611           0 : int GDALMDArraySetOffset(GDALMDArrayH hArray, double dfOffset)
     612             : {
     613           0 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     614           0 :     return hArray->m_poImpl->SetOffset(dfOffset);
     615             : }
     616             : 
     617             : /************************************************************************/
     618             : /*                       GDALMDArraySetOffsetEx()                       */
     619             : /************************************************************************/
     620             : 
     621             : /** Set the scale value to apply to raw values.
     622             :  *
     623             :  * unscaled_value = raw_value * GetOffset() + GetOffset()
     624             :  *
     625             :  * This is the same as the C++ method GDALMDArray::SetOffset().
     626             :  *
     627             :  * @return TRUE in case of success.
     628             :  * @since GDAL 3.3
     629             :  */
     630          21 : int GDALMDArraySetOffsetEx(GDALMDArrayH hArray, double dfOffset,
     631             :                            GDALDataType eStorageType)
     632             : {
     633          21 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     634          21 :     return hArray->m_poImpl->SetOffset(dfOffset, eStorageType);
     635             : }
     636             : 
     637             : /************************************************************************/
     638             : /*                        GDALMDArrayGetScale()                         */
     639             : /************************************************************************/
     640             : 
     641             : /** Get the scale value to apply to raw values.
     642             :  *
     643             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     644             :  *
     645             :  * This is the same as the C++ method GDALMDArray::GetScale().
     646             :  *
     647             :  * @return the scale value
     648             :  */
     649         105 : double GDALMDArrayGetScale(GDALMDArrayH hArray, int *pbHasValue)
     650             : {
     651         105 :     VALIDATE_POINTER1(hArray, __func__, 0.0);
     652         105 :     bool bHasValue = false;
     653         105 :     double dfRet = hArray->m_poImpl->GetScale(&bHasValue);
     654         105 :     if (pbHasValue)
     655         105 :         *pbHasValue = bHasValue;
     656         105 :     return dfRet;
     657             : }
     658             : 
     659             : /************************************************************************/
     660             : /*                       GDALMDArrayGetScaleEx()                        */
     661             : /************************************************************************/
     662             : 
     663             : /** Get the scale value to apply to raw values.
     664             :  *
     665             :  * unscaled_value = raw_value * GetScale() + GetScale()
     666             :  *
     667             :  * This is the same as the C++ method GDALMDArray::GetScale().
     668             :  *
     669             :  * @return the scale value
     670             :  * @since GDAL 3.3
     671             :  */
     672           5 : double GDALMDArrayGetScaleEx(GDALMDArrayH hArray, int *pbHasValue,
     673             :                              GDALDataType *peStorageType)
     674             : {
     675           5 :     VALIDATE_POINTER1(hArray, __func__, 0.0);
     676           5 :     bool bHasValue = false;
     677           5 :     double dfRet = hArray->m_poImpl->GetScale(&bHasValue, peStorageType);
     678           5 :     if (pbHasValue)
     679           5 :         *pbHasValue = bHasValue;
     680           5 :     return dfRet;
     681             : }
     682             : 
     683             : /************************************************************************/
     684             : /*                        GDALMDArrayGetOffset()                        */
     685             : /************************************************************************/
     686             : 
     687             : /** Get the scale value to apply to raw values.
     688             :  *
     689             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     690             :  *
     691             :  * This is the same as the C++ method GDALMDArray::GetOffset().
     692             :  *
     693             :  * @return the scale value
     694             :  */
     695         102 : double GDALMDArrayGetOffset(GDALMDArrayH hArray, int *pbHasValue)
     696             : {
     697         102 :     VALIDATE_POINTER1(hArray, __func__, 0.0);
     698         102 :     bool bHasValue = false;
     699         102 :     double dfRet = hArray->m_poImpl->GetOffset(&bHasValue);
     700         102 :     if (pbHasValue)
     701         102 :         *pbHasValue = bHasValue;
     702         102 :     return dfRet;
     703             : }
     704             : 
     705             : /************************************************************************/
     706             : /*                       GDALMDArrayGetOffsetEx()                       */
     707             : /************************************************************************/
     708             : 
     709             : /** Get the scale value to apply to raw values.
     710             :  *
     711             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     712             :  *
     713             :  * This is the same as the C++ method GDALMDArray::GetOffset().
     714             :  *
     715             :  * @return the scale value
     716             :  * @since GDAL 3.3
     717             :  */
     718           5 : double GDALMDArrayGetOffsetEx(GDALMDArrayH hArray, int *pbHasValue,
     719             :                               GDALDataType *peStorageType)
     720             : {
     721           5 :     VALIDATE_POINTER1(hArray, __func__, 0.0);
     722           5 :     bool bHasValue = false;
     723           5 :     double dfRet = hArray->m_poImpl->GetOffset(&bHasValue, peStorageType);
     724           5 :     if (pbHasValue)
     725           5 :         *pbHasValue = bHasValue;
     726           5 :     return dfRet;
     727             : }
     728             : 
     729             : /************************************************************************/
     730             : /*                      GDALMDArrayGetBlockSize()                       */
     731             : /************************************************************************/
     732             : 
     733             : /** Return the "natural" block size of the array along all dimensions.
     734             :  *
     735             :  * Some drivers might organize the array in tiles/blocks and reading/writing
     736             :  * aligned on those tile/block boundaries will be more efficient.
     737             :  *
     738             :  * The returned number of elements in the vector is the same as
     739             :  * GetDimensionCount(). A value of 0 should be interpreted as no hint regarding
     740             :  * the natural block size along the considered dimension.
     741             :  * "Flat" arrays will typically return a vector of values set to 0.
     742             :  *
     743             :  * The default implementation will return a vector of values set to 0.
     744             :  *
     745             :  * This method is used by GetProcessingChunkSize().
     746             :  *
     747             :  * Pedantic note: the returned type is GUInt64, so in the highly unlikely
     748             :  * theoretical case of a 32-bit platform, this might exceed its size_t
     749             :  * allocation capabilities.
     750             :  *
     751             :  * This is the same as the C++ method GDALAbstractMDArray::GetBlockSize().
     752             :  *
     753             :  * @return the block size, in number of elements along each dimension.
     754             :  */
     755         110 : GUInt64 *GDALMDArrayGetBlockSize(GDALMDArrayH hArray, size_t *pnCount)
     756             : {
     757         110 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     758         110 :     VALIDATE_POINTER1(pnCount, __func__, nullptr);
     759         110 :     auto res = hArray->m_poImpl->GetBlockSize();
     760         110 :     auto ret = static_cast<GUInt64 *>(CPLMalloc(sizeof(GUInt64) * res.size()));
     761         339 :     for (size_t i = 0; i < res.size(); i++)
     762             :     {
     763         229 :         ret[i] = res[i];
     764             :     }
     765         110 :     *pnCount = res.size();
     766         110 :     return ret;
     767             : }
     768             : 
     769             : /************************************************************************/
     770             : /*                 GDALMDArrayGetProcessingChunkSize()                  */
     771             : /************************************************************************/
     772             : 
     773             : /** \brief Return an optimal chunk size for read/write operations, given the
     774             :  * natural block size and memory constraints specified.
     775             :  *
     776             :  * This method will use GetBlockSize() to define a chunk whose dimensions are
     777             :  * multiple of those returned by GetBlockSize() (unless the block define by
     778             :  * GetBlockSize() is larger than nMaxChunkMemory, in which case it will be
     779             :  * returned by this method).
     780             :  *
     781             :  * This is the same as the C++ method
     782             :  * GDALAbstractMDArray::GetProcessingChunkSize().
     783             :  *
     784             :  * @param hArray Array.
     785             :  * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
     786             :  * @param nMaxChunkMemory Maximum amount of memory, in bytes, to use for the
     787             :  * chunk.
     788             :  *
     789             :  * @return the chunk size, in number of elements along each dimension.
     790             :  */
     791             : 
     792           1 : size_t *GDALMDArrayGetProcessingChunkSize(GDALMDArrayH hArray, size_t *pnCount,
     793             :                                           size_t nMaxChunkMemory)
     794             : {
     795           1 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     796           1 :     VALIDATE_POINTER1(pnCount, __func__, nullptr);
     797           1 :     auto res = hArray->m_poImpl->GetProcessingChunkSize(nMaxChunkMemory);
     798           1 :     auto ret = static_cast<size_t *>(CPLMalloc(sizeof(size_t) * res.size()));
     799           3 :     for (size_t i = 0; i < res.size(); i++)
     800             :     {
     801           2 :         ret[i] = res[i];
     802             :     }
     803           1 :     *pnCount = res.size();
     804           1 :     return ret;
     805             : }
     806             : 
     807             : /************************************************************************/
     808             : /*                    GDALMDArrayGetStructuralInfo()                    */
     809             : /************************************************************************/
     810             : 
     811             : /** Return structural information on the array.
     812             :  *
     813             :  * This may be the compression, etc..
     814             :  *
     815             :  * The return value should not be freed and is valid until GDALMDArray is
     816             :  * released or this function called again.
     817             :  *
     818             :  * This is the same as the C++ method GDALMDArray::GetStructuralInfo().
     819             :  */
     820          17 : CSLConstList GDALMDArrayGetStructuralInfo(GDALMDArrayH hArray)
     821             : {
     822          17 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     823          17 :     return hArray->m_poImpl->GetStructuralInfo();
     824             : }
     825             : 
     826             : /************************************************************************/
     827             : /*                         GDALMDArrayGetView()                         */
     828             : /************************************************************************/
     829             : 
     830             : /** Return a view of the array using slicing or field access.
     831             :  *
     832             :  * The returned object should be released with GDALMDArrayRelease().
     833             :  *
     834             :  * This is the same as the C++ method GDALMDArray::GetView().
     835             :  */
     836         438 : GDALMDArrayH GDALMDArrayGetView(GDALMDArrayH hArray, const char *pszViewExpr)
     837             : {
     838         438 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     839         438 :     VALIDATE_POINTER1(pszViewExpr, __func__, nullptr);
     840        1314 :     auto sliced = hArray->m_poImpl->GetView(std::string(pszViewExpr));
     841         438 :     if (!sliced)
     842          23 :         return nullptr;
     843         415 :     return new GDALMDArrayHS(sliced);
     844             : }
     845             : 
     846             : /************************************************************************/
     847             : /*                        GDALMDArrayTranspose()                        */
     848             : /************************************************************************/
     849             : 
     850             : /** Return a view of the array whose axis have been reordered.
     851             :  *
     852             :  * The returned object should be released with GDALMDArrayRelease().
     853             :  *
     854             :  * This is the same as the C++ method GDALMDArray::Transpose().
     855             :  */
     856          46 : GDALMDArrayH GDALMDArrayTranspose(GDALMDArrayH hArray, size_t nNewAxisCount,
     857             :                                   const int *panMapNewAxisToOldAxis)
     858             : {
     859          46 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     860          92 :     std::vector<int> anMapNewAxisToOldAxis(nNewAxisCount);
     861          46 :     if (nNewAxisCount)
     862             :     {
     863          45 :         memcpy(&anMapNewAxisToOldAxis[0], panMapNewAxisToOldAxis,
     864             :                nNewAxisCount * sizeof(int));
     865             :     }
     866          92 :     auto reordered = hArray->m_poImpl->Transpose(anMapNewAxisToOldAxis);
     867          46 :     if (!reordered)
     868           7 :         return nullptr;
     869          39 :     return new GDALMDArrayHS(reordered);
     870             : }
     871             : 
     872             : /************************************************************************/
     873             : /*                       GDALMDArrayGetUnscaled()                       */
     874             : /************************************************************************/
     875             : 
     876             : /** Return an array that is the unscaled version of the current one.
     877             :  *
     878             :  * That is each value of the unscaled array will be
     879             :  * unscaled_value = raw_value * GetScale() + GetOffset()
     880             :  *
     881             :  * Starting with GDAL 3.3, the Write() method is implemented and will convert
     882             :  * from unscaled values to raw values.
     883             :  *
     884             :  * The returned object should be released with GDALMDArrayRelease().
     885             :  *
     886             :  * This is the same as the C++ method GDALMDArray::GetUnscaled().
     887             :  */
     888          13 : GDALMDArrayH GDALMDArrayGetUnscaled(GDALMDArrayH hArray)
     889             : {
     890          13 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     891          26 :     auto unscaled = hArray->m_poImpl->GetUnscaled();
     892          13 :     if (!unscaled)
     893           0 :         return nullptr;
     894          13 :     return new GDALMDArrayHS(unscaled);
     895             : }
     896             : 
     897             : /************************************************************************/
     898             : /*                         GDALMDArrayGetMask()                         */
     899             : /************************************************************************/
     900             : 
     901             : /** Return an array that is a mask for the current array
     902             :  *
     903             :  * This array will be of type Byte, with values set to 0 to indicate invalid
     904             :  * pixels of the current array, and values set to 1 to indicate valid pixels.
     905             :  *
     906             :  * The returned object should be released with GDALMDArrayRelease().
     907             :  *
     908             :  * This is the same as the C++ method GDALMDArray::GetMask().
     909             :  */
     910          35 : GDALMDArrayH GDALMDArrayGetMask(GDALMDArrayH hArray, CSLConstList papszOptions)
     911             : {
     912          35 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     913          70 :     auto unscaled = hArray->m_poImpl->GetMask(papszOptions);
     914          35 :     if (!unscaled)
     915           7 :         return nullptr;
     916          28 :     return new GDALMDArrayHS(unscaled);
     917             : }
     918             : 
     919             : /************************************************************************/
     920             : /*                      GDALMDArrayGetResampled()                       */
     921             : /************************************************************************/
     922             : 
     923             : /** Return an array that is a resampled / reprojected view of the current array
     924             :  *
     925             :  * This is the same as the C++ method GDALMDArray::GetResampled().
     926             :  *
     927             :  * Currently this method can only resample along the last 2 dimensions, unless
     928             :  * orthorectifying a NASA EMIT dataset.
     929             :  *
     930             :  * The returned object should be released with GDALMDArrayRelease().
     931             :  *
     932             :  * @since 3.4
     933             :  */
     934          34 : GDALMDArrayH GDALMDArrayGetResampled(GDALMDArrayH hArray, size_t nNewDimCount,
     935             :                                      const GDALDimensionH *pahNewDims,
     936             :                                      GDALRIOResampleAlg resampleAlg,
     937             :                                      OGRSpatialReferenceH hTargetSRS,
     938             :                                      CSLConstList papszOptions)
     939             : {
     940          34 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
     941          34 :     VALIDATE_POINTER1(pahNewDims, __func__, nullptr);
     942          68 :     std::vector<std::shared_ptr<GDALDimension>> apoNewDims(nNewDimCount);
     943         112 :     for (size_t i = 0; i < nNewDimCount; ++i)
     944             :     {
     945          78 :         if (pahNewDims[i])
     946           8 :             apoNewDims[i] = pahNewDims[i]->m_poImpl;
     947             :     }
     948          34 :     auto poNewArray = hArray->m_poImpl->GetResampled(
     949          34 :         apoNewDims, resampleAlg, OGRSpatialReference::FromHandle(hTargetSRS),
     950          68 :         papszOptions);
     951          34 :     if (!poNewArray)
     952           8 :         return nullptr;
     953          26 :     return new GDALMDArrayHS(poNewArray);
     954             : }
     955             : 
     956             : /************************************************************************/
     957             : /*                         GDALMDArraySetUnit()                         */
     958             : /************************************************************************/
     959             : 
     960             : /** Set the variable unit.
     961             :  *
     962             :  * Values should conform as much as possible with those allowed by
     963             :  * the NetCDF CF conventions:
     964             :  * http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/cf-conventions.html#units
     965             :  * but others might be returned.
     966             :  *
     967             :  * Few examples are "meter", "degrees", "second", ...
     968             :  * Empty value means unknown.
     969             :  *
     970             :  * This is the same as the C function GDALMDArraySetUnit()
     971             :  *
     972             :  * @param hArray array.
     973             :  * @param pszUnit unit name.
     974             :  * @return TRUE in case of success.
     975             :  */
     976          15 : int GDALMDArraySetUnit(GDALMDArrayH hArray, const char *pszUnit)
     977             : {
     978          15 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
     979          15 :     return hArray->m_poImpl->SetUnit(pszUnit ? pszUnit : "");
     980             : }
     981             : 
     982             : /************************************************************************/
     983             : /*                         GDALMDArrayGetUnit()                         */
     984             : /************************************************************************/
     985             : 
     986             : /** Return the array unit.
     987             :  *
     988             :  * Values should conform as much as possible with those allowed by
     989             :  * the NetCDF CF conventions:
     990             :  * http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/cf-conventions.html#units
     991             :  * but others might be returned.
     992             :  *
     993             :  * Few examples are "meter", "degrees", "second", ...
     994             :  * Empty value means unknown.
     995             :  *
     996             :  * The return value should not be freed and is valid until GDALMDArray is
     997             :  * released or this function called again.
     998             :  *
     999             :  * This is the same as the C++ method GDALMDArray::GetUnit().
    1000             :  */
    1001         113 : const char *GDALMDArrayGetUnit(GDALMDArrayH hArray)
    1002             : {
    1003         113 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1004         113 :     return hArray->m_poImpl->GetUnit().c_str();
    1005             : }
    1006             : 
    1007             : /************************************************************************/
    1008             : /*                      GDALMDArrayGetSpatialRef()                      */
    1009             : /************************************************************************/
    1010             : 
    1011             : /** Assign a spatial reference system object to the array.
    1012             :  *
    1013             :  * This is the same as the C++ method GDALMDArray::SetSpatialRef().
    1014             :  * @return TRUE in case of success.
    1015             :  */
    1016          30 : int GDALMDArraySetSpatialRef(GDALMDArrayH hArray, OGRSpatialReferenceH hSRS)
    1017             : {
    1018          30 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
    1019          60 :     return hArray->m_poImpl->SetSpatialRef(
    1020          60 :         OGRSpatialReference::FromHandle(hSRS));
    1021             : }
    1022             : 
    1023             : /************************************************************************/
    1024             : /*                      GDALMDArrayGetSpatialRef()                      */
    1025             : /************************************************************************/
    1026             : 
    1027             : /** Return the spatial reference system object associated with the array.
    1028             :  *
    1029             :  * This is the same as the C++ method GDALMDArray::GetSpatialRef().
    1030             :  *
    1031             :  * The returned object must be freed with OSRDestroySpatialReference().
    1032             :  */
    1033          82 : OGRSpatialReferenceH GDALMDArrayGetSpatialRef(GDALMDArrayH hArray)
    1034             : {
    1035          82 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1036          82 :     auto poSRS = hArray->m_poImpl->GetSpatialRef();
    1037          82 :     return poSRS ? OGRSpatialReference::ToHandle(poSRS->Clone()) : nullptr;
    1038             : }
    1039             : 
    1040             : /************************************************************************/
    1041             : /*                      GDALMDArrayGetStatistics()                      */
    1042             : /************************************************************************/
    1043             : 
    1044             : /**
    1045             :  * \brief Fetch statistics.
    1046             :  *
    1047             :  * This is the same as the C++ method GDALMDArray::GetStatistics().
    1048             :  *
    1049             :  * @since GDAL 3.2
    1050             :  */
    1051             : 
    1052          15 : CPLErr GDALMDArrayGetStatistics(GDALMDArrayH hArray, GDALDatasetH /*hDS*/,
    1053             :                                 int bApproxOK, int bForce, double *pdfMin,
    1054             :                                 double *pdfMax, double *pdfMean,
    1055             :                                 double *pdfStdDev, GUInt64 *pnValidCount,
    1056             :                                 GDALProgressFunc pfnProgress,
    1057             :                                 void *pProgressData)
    1058             : {
    1059          15 :     VALIDATE_POINTER1(hArray, __func__, CE_Failure);
    1060          30 :     return hArray->m_poImpl->GetStatistics(
    1061          15 :         CPL_TO_BOOL(bApproxOK), CPL_TO_BOOL(bForce), pdfMin, pdfMax, pdfMean,
    1062          15 :         pdfStdDev, pnValidCount, pfnProgress, pProgressData);
    1063             : }
    1064             : 
    1065             : /************************************************************************/
    1066             : /*                    GDALMDArrayComputeStatistics()                    */
    1067             : /************************************************************************/
    1068             : 
    1069             : /**
    1070             :  * \brief Compute statistics.
    1071             :  *
    1072             :  * This is the same as the C++ method GDALMDArray::ComputeStatistics().
    1073             :  *
    1074             :  * @since GDAL 3.2
    1075             :  * @see GDALMDArrayComputeStatisticsEx()
    1076             :  */
    1077             : 
    1078           0 : int GDALMDArrayComputeStatistics(GDALMDArrayH hArray, GDALDatasetH /* hDS */,
    1079             :                                  int bApproxOK, double *pdfMin, double *pdfMax,
    1080             :                                  double *pdfMean, double *pdfStdDev,
    1081             :                                  GUInt64 *pnValidCount,
    1082             :                                  GDALProgressFunc pfnProgress,
    1083             :                                  void *pProgressData)
    1084             : {
    1085           0 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
    1086           0 :     return hArray->m_poImpl->ComputeStatistics(
    1087           0 :         CPL_TO_BOOL(bApproxOK), pdfMin, pdfMax, pdfMean, pdfStdDev,
    1088           0 :         pnValidCount, pfnProgress, pProgressData, nullptr);
    1089             : }
    1090             : 
    1091             : /************************************************************************/
    1092             : /*                   GDALMDArrayComputeStatisticsEx()                   */
    1093             : /************************************************************************/
    1094             : 
    1095             : /**
    1096             :  * \brief Compute statistics.
    1097             :  *
    1098             :  * Same as GDALMDArrayComputeStatistics() with extra papszOptions argument.
    1099             :  *
    1100             :  * This is the same as the C++ method GDALMDArray::ComputeStatistics().
    1101             :  *
    1102             :  * @since GDAL 3.8
    1103             :  */
    1104             : 
    1105           4 : int GDALMDArrayComputeStatisticsEx(GDALMDArrayH hArray, GDALDatasetH /* hDS */,
    1106             :                                    int bApproxOK, double *pdfMin,
    1107             :                                    double *pdfMax, double *pdfMean,
    1108             :                                    double *pdfStdDev, GUInt64 *pnValidCount,
    1109             :                                    GDALProgressFunc pfnProgress,
    1110             :                                    void *pProgressData,
    1111             :                                    CSLConstList papszOptions)
    1112             : {
    1113           4 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
    1114           8 :     return hArray->m_poImpl->ComputeStatistics(
    1115           4 :         CPL_TO_BOOL(bApproxOK), pdfMin, pdfMax, pdfMean, pdfStdDev,
    1116           8 :         pnValidCount, pfnProgress, pProgressData, papszOptions);
    1117             : }
    1118             : 
    1119             : /************************************************************************/
    1120             : /*                 GDALMDArrayGetCoordinateVariables()                  */
    1121             : /************************************************************************/
    1122             : 
    1123             : /** Return coordinate variables.
    1124             :  *
    1125             :  * The returned array must be freed with GDALReleaseArrays(). If only the array
    1126             :  * itself needs to be freed, CPLFree() should be called (and
    1127             :  * GDALMDArrayRelease() on individual array members).
    1128             :  *
    1129             :  * This is the same as the C++ method GDALMDArray::GetCoordinateVariables()
    1130             :  *
    1131             :  * @param hArray Array.
    1132             :  * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
    1133             :  *
    1134             :  * @return an array of *pnCount arrays.
    1135             :  * @since 3.4
    1136             :  */
    1137          13 : GDALMDArrayH *GDALMDArrayGetCoordinateVariables(GDALMDArrayH hArray,
    1138             :                                                 size_t *pnCount)
    1139             : {
    1140          13 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1141          13 :     VALIDATE_POINTER1(pnCount, __func__, nullptr);
    1142          13 :     const auto coordinates(hArray->m_poImpl->GetCoordinateVariables());
    1143             :     auto ret = static_cast<GDALMDArrayH *>(
    1144          13 :         CPLMalloc(sizeof(GDALMDArrayH) * coordinates.size()));
    1145          29 :     for (size_t i = 0; i < coordinates.size(); i++)
    1146             :     {
    1147          16 :         ret[i] = new GDALMDArrayHS(coordinates[i]);
    1148             :     }
    1149          13 :     *pnCount = coordinates.size();
    1150          13 :     return ret;
    1151             : }
    1152             : 
    1153             : /************************************************************************/
    1154             : /*                       GDALMDArrayGetGridded()                        */
    1155             : /************************************************************************/
    1156             : 
    1157             : /** Return a gridded array from scattered point data, that is from an array
    1158             :  * whose last dimension is the indexing variable of X and Y arrays.
    1159             :  *
    1160             :  * The returned object should be released with GDALMDArrayRelease().
    1161             :  *
    1162             :  * This is the same as the C++ method GDALMDArray::GetGridded().
    1163             :  *
    1164             :  * @since GDAL 3.7
    1165             :  */
    1166          22 : GDALMDArrayH GDALMDArrayGetGridded(GDALMDArrayH hArray,
    1167             :                                    const char *pszGridOptions,
    1168             :                                    GDALMDArrayH hXArray, GDALMDArrayH hYArray,
    1169             :                                    CSLConstList papszOptions)
    1170             : {
    1171          22 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1172          22 :     VALIDATE_POINTER1(pszGridOptions, __func__, nullptr);
    1173          22 :     auto gridded = hArray->m_poImpl->GetGridded(
    1174          44 :         pszGridOptions, hXArray ? hXArray->m_poImpl : nullptr,
    1175          88 :         hYArray ? hYArray->m_poImpl : nullptr, papszOptions);
    1176          22 :     if (!gridded)
    1177          19 :         return nullptr;
    1178           3 :     return new GDALMDArrayHS(gridded);
    1179             : }
    1180             : 
    1181             : /************************************************************************/
    1182             : /*                       GDALMDArrayGetMeshGrid()                       */
    1183             : /************************************************************************/
    1184             : 
    1185             : /** Return a list of multidimensional arrays from a list of one-dimensional
    1186             :  * arrays.
    1187             :  *
    1188             :  * This is typically used to transform one-dimensional longitude, latitude
    1189             :  * arrays into 2D ones.
    1190             :  *
    1191             :  * More formally, for one-dimensional arrays x1, x2,..., xn with lengths
    1192             :  * Ni=len(xi), returns (N1, N2, ..., Nn) shaped arrays if indexing="ij" or
    1193             :  * (N2, N1, ..., Nn) shaped arrays if indexing="xy" with the elements of xi
    1194             :  * repeated to fill the matrix along the first dimension for x1, the second
    1195             :  * for x2 and so on.
    1196             :  *
    1197             :  * For example, if x = [1, 2], and y = [3, 4, 5],
    1198             :  * GetMeshGrid([x, y], ["INDEXING=xy"]) will return [xm, ym] such that
    1199             :  * xm=[[1, 2],[1, 2],[1, 2]] and ym=[[3, 3],[4, 4],[5, 5]],
    1200             :  * or more generally xm[any index][i] = x[i] and ym[i][any index]=y[i]
    1201             :  *
    1202             :  * and
    1203             :  * GetMeshGrid([x, y], ["INDEXING=ij"]) will return [xm, ym] such that
    1204             :  * xm=[[1, 1, 1],[2, 2, 2]] and ym=[[3, 4, 5],[3, 4, 5]],
    1205             :  * or more generally xm[i][any index] = x[i] and ym[any index][i]=y[i]
    1206             :  *
    1207             :  * The currently supported options are:
    1208             :  * <ul>
    1209             :  * <li>INDEXING=xy/ij: Cartesian ("xy", default) or matrix ("ij") indexing of
    1210             :  * output.
    1211             :  * </li>
    1212             :  * </ul>
    1213             :  *
    1214             :  * This is the same as
    1215             :  * <a href="https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html">numpy.meshgrid()</a>
    1216             :  * function.
    1217             :  *
    1218             :  * The returned array (of arrays) must be freed with GDALReleaseArrays().
    1219             :  * If only the array itself needs to be freed, CPLFree() should be called
    1220             :  * (and GDALMDArrayRelease() on individual array members).
    1221             :  *
    1222             :  * This is the same as the C++ method GDALMDArray::GetMeshGrid()
    1223             :  *
    1224             :  * @param pahInputArrays Input arrays
    1225             :  * @param nCountInputArrays Number of input arrays
    1226             :  * @param pnCountOutputArrays Pointer to the number of values returned. Must NOT be NULL.
    1227             :  * @param papszOptions NULL, or NULL terminated list of options.
    1228             :  *
    1229             :  * @return an array of *pnCountOutputArrays arrays.
    1230             :  * @since 3.10
    1231             :  */
    1232           7 : GDALMDArrayH *GDALMDArrayGetMeshGrid(const GDALMDArrayH *pahInputArrays,
    1233             :                                      size_t nCountInputArrays,
    1234             :                                      size_t *pnCountOutputArrays,
    1235             :                                      CSLConstList papszOptions)
    1236             : {
    1237           7 :     VALIDATE_POINTER1(pahInputArrays, __func__, nullptr);
    1238           7 :     VALIDATE_POINTER1(pnCountOutputArrays, __func__, nullptr);
    1239             : 
    1240          14 :     std::vector<std::shared_ptr<GDALMDArray>> apoInputArrays;
    1241          20 :     for (size_t i = 0; i < nCountInputArrays; ++i)
    1242          13 :         apoInputArrays.push_back(pahInputArrays[i]->m_poImpl);
    1243             : 
    1244             :     const auto apoOutputArrays =
    1245           7 :         GDALMDArray::GetMeshGrid(apoInputArrays, papszOptions);
    1246             :     auto ret = static_cast<GDALMDArrayH *>(
    1247           7 :         CPLMalloc(sizeof(GDALMDArrayH) * apoOutputArrays.size()));
    1248          17 :     for (size_t i = 0; i < apoOutputArrays.size(); i++)
    1249             :     {
    1250          10 :         ret[i] = new GDALMDArrayHS(apoOutputArrays[i]);
    1251             :     }
    1252           7 :     *pnCountOutputArrays = apoOutputArrays.size();
    1253           7 :     return ret;
    1254             : }
    1255             : 
    1256             : /************************************************************************/
    1257             : /*                         GDALReleaseArrays()                          */
    1258             : /************************************************************************/
    1259             : 
    1260             : /** Free the return of GDALMDArrayGetCoordinateVariables()
    1261             :  *
    1262             :  * @param arrays return pointer of above methods
    1263             :  * @param nCount *pnCount value returned by above methods
    1264             :  */
    1265          20 : void GDALReleaseArrays(GDALMDArrayH *arrays, size_t nCount)
    1266             : {
    1267          46 :     for (size_t i = 0; i < nCount; i++)
    1268             :     {
    1269          26 :         delete arrays[i];
    1270             :     }
    1271          20 :     CPLFree(arrays);
    1272          20 : }
    1273             : 
    1274             : /************************************************************************/
    1275             : /*                          GDALMDArrayCache()                          */
    1276             : /************************************************************************/
    1277             : 
    1278             : /**
    1279             :  * \brief Cache the content of the array into an auxiliary filename.
    1280             :  *
    1281             :  * This is the same as the C++ method GDALMDArray::Cache().
    1282             :  *
    1283             :  * @since GDAL 3.4
    1284             :  */
    1285             : 
    1286           7 : int GDALMDArrayCache(GDALMDArrayH hArray, CSLConstList papszOptions)
    1287             : {
    1288           7 :     VALIDATE_POINTER1(hArray, __func__, FALSE);
    1289           7 :     return hArray->m_poImpl->Cache(papszOptions);
    1290             : }
    1291             : 
    1292             : /************************************************************************/
    1293             : /*                         GDALMDArrayRename()                          */
    1294             : /************************************************************************/
    1295             : 
    1296             : /** Rename the array.
    1297             :  *
    1298             :  * This is not implemented by all drivers.
    1299             :  *
    1300             :  * Drivers known to implement it: MEM, netCDF, Zarr.
    1301             :  *
    1302             :  * This is the same as the C++ method GDALAbstractMDArray::Rename()
    1303             :  *
    1304             :  * @return true in case of success
    1305             :  * @since GDAL 3.8
    1306             :  */
    1307          28 : bool GDALMDArrayRename(GDALMDArrayH hArray, const char *pszNewName)
    1308             : {
    1309          28 :     VALIDATE_POINTER1(hArray, __func__, false);
    1310          28 :     VALIDATE_POINTER1(pszNewName, __func__, false);
    1311          28 :     return hArray->m_poImpl->Rename(pszNewName);
    1312             : }
    1313             : 
    1314             : /************************************************************************/
    1315             : /*                    GDALMDArrayAsClassicDataset()                     */
    1316             : /************************************************************************/
    1317             : 
    1318             : /** Return a view of this array as a "classic" GDALDataset (ie 2D)
    1319             :  *
    1320             :  * Only 2D or more arrays are supported.
    1321             :  *
    1322             :  * In the case of > 2D arrays, additional dimensions will be represented as
    1323             :  * raster bands.
    1324             :  *
    1325             :  * The "reverse" methods are GDALRasterBand::AsMDArray() and
    1326             :  * GDALDataset::AsMDArray()
    1327             :  *
    1328             :  * This is the same as the C++ method GDALMDArray::AsClassicDataset().
    1329             :  *
    1330             :  * @param hArray Array.
    1331             :  * @param iXDim Index of the dimension that will be used as the X/width axis.
    1332             :  * @param iYDim Index of the dimension that will be used as the Y/height axis.
    1333             :  * @return a new GDALDataset that must be freed with GDALClose(), or nullptr
    1334             :  */
    1335           0 : GDALDatasetH GDALMDArrayAsClassicDataset(GDALMDArrayH hArray, size_t iXDim,
    1336             :                                          size_t iYDim)
    1337             : {
    1338           0 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1339           0 :     return GDALDataset::ToHandle(
    1340           0 :         hArray->m_poImpl->AsClassicDataset(iXDim, iYDim));
    1341             : }
    1342             : 
    1343             : /************************************************************************/
    1344             : /*                   GDALMDArrayAsClassicDatasetEx()                    */
    1345             : /************************************************************************/
    1346             : 
    1347             : /** Return a view of this array as a "classic" GDALDataset (ie 2D)
    1348             :  *
    1349             :  * Only 2D or more arrays are supported.
    1350             :  *
    1351             :  * In the case of > 2D arrays, additional dimensions will be represented as
    1352             :  * raster bands.
    1353             :  *
    1354             :  * The "reverse" method is GDALRasterBand::AsMDArray().
    1355             :  *
    1356             :  * This is the same as the C++ method GDALMDArray::AsClassicDataset().
    1357             :  * @param hArray Array.
    1358             :  * @param iXDim Index of the dimension that will be used as the X/width axis.
    1359             :  * @param iYDim Index of the dimension that will be used as the Y/height axis.
    1360             :  *              Ignored if the dimension count is 1.
    1361             :  * @param hRootGroup Root group, or NULL. Used with the BAND_METADATA and
    1362             :  *                   BAND_IMAGERY_METADATA option.
    1363             :  * @param papszOptions Cf GDALMDArray::AsClassicDataset()
    1364             :  * @return a new GDALDataset that must be freed with GDALClose(), or nullptr
    1365             :  * @since GDAL 3.8
    1366             :  */
    1367         112 : GDALDatasetH GDALMDArrayAsClassicDatasetEx(GDALMDArrayH hArray, size_t iXDim,
    1368             :                                            size_t iYDim, GDALGroupH hRootGroup,
    1369             :                                            CSLConstList papszOptions)
    1370             : {
    1371         112 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1372         224 :     return GDALDataset::ToHandle(hArray->m_poImpl->AsClassicDataset(
    1373         224 :         iXDim, iYDim, hRootGroup ? hRootGroup->m_poImpl : nullptr,
    1374         224 :         papszOptions));
    1375             : }
    1376             : 
    1377             : /************************************************************************/
    1378             : /*                    GDALMDArray::GetRawBlockInfo()                    */
    1379             : /************************************************************************/
    1380             : 
    1381             : /** Return information on a raw block.
    1382             :  *
    1383             :  * The block coordinates must be between 0 and
    1384             :  * (GetDimensions()[i]->GetSize() / GetBlockSize()[i]) - 1, for all i between
    1385             :  * 0 and GetDimensionCount()-1.
    1386             :  *
    1387             :  * If the queried block has valid coordinates but is missing in the dataset,
    1388             :  * all fields of info will be set to 0/nullptr, but the function will return
    1389             :  * true.
    1390             :  *
    1391             :  * This method is only implemented by a subset of drivers. The base
    1392             :  * implementation just returns false and empty info.
    1393             :  *
    1394             :  * The values returned in psBlockInfo->papszInfo are driver dependent.
    1395             :  *
    1396             :  * For multi-byte data types, drivers should return a "ENDIANNESS" key whose
    1397             :  * value is "LITTLE" or "BIG".
    1398             :  *
    1399             :  * For HDF5 and netCDF 4, the potential keys are "COMPRESSION" (possible values
    1400             :  * "DEFLATE" or "SZIP") and "FILTER" (if several filters, names are
    1401             :  * comma-separated)
    1402             :  *
    1403             :  * For ZARR, the potential keys are "COMPRESSOR" (value is the JSON encoded
    1404             :  * content from the array definition), "FILTERS" (for Zarr V2, value is JSON
    1405             :  * encoded content) and "TRANSPOSE_ORDER" (value is a string like
    1406             :  * "[idx0,...,idxN]" with the permutation).
    1407             :  *
    1408             :  * For VRT, the potential keys are the ones of the underlying source(s). Note
    1409             :  * that GetRawBlockInfo() on VRT only works when the VRT declares a block size,
    1410             :  * that for each queried VRT block, there is one and only one source that
    1411             :  * is used to fill the VRT block and that the block size of this source is
    1412             :  * exactly the one of the VRT block.
    1413             :  *
    1414             :  * This is the same as C function GDALMDArrayGetRawBlockInfo().
    1415             :  *
    1416             :  * @param panBlockCoordinates array of GetDimensionCount() values with the block
    1417             :  *                            coordinates.
    1418             :  * @param[out] info structure to fill with block information.
    1419             :  * @return true in case of success, or false if an error occurs.
    1420             :  * @since 3.12
    1421             :  */
    1422           0 : bool GDALMDArray::GetRawBlockInfo(const uint64_t *panBlockCoordinates,
    1423             :                                   GDALMDArrayRawBlockInfo &info) const
    1424             : {
    1425             :     (void)panBlockCoordinates;
    1426           0 :     info.clear();
    1427           0 :     return false;
    1428             : }
    1429             : 
    1430             : /************************************************************************/
    1431             : /*                     GDALMDArrayGetRawBlockInfo()                     */
    1432             : /************************************************************************/
    1433             : 
    1434             : /** Return information on a raw block.
    1435             :  *
    1436             :  * The block coordinates must be between 0 and
    1437             :  * (GetDimensions()[i]->GetSize() / GetBlockSize()[i]) - 1, for all i between
    1438             :  * 0 and GetDimensionCount()-1.
    1439             :  *
    1440             :  * If the queried block has valid coordinates but is missing in the dataset,
    1441             :  * all fields of info will be set to 0/nullptr, but the function will return
    1442             :  * true.
    1443             :  *
    1444             :  * This method is only implemented by a subset of drivers. The base
    1445             :  * implementation just returns false and empty info.
    1446             :  *
    1447             :  * The values returned in psBlockInfo->papszInfo are driver dependent.
    1448             :  *
    1449             :  * For multi-byte data types, drivers should return a "ENDIANNESS" key whose
    1450             :  * value is "LITTLE" or "BIG".
    1451             :  *
    1452             :  * For HDF5 and netCDF 4, the potential keys are "COMPRESSION" (possible values
    1453             :  * "DEFLATE" or "SZIP") and "FILTER" (if several filters, names are
    1454             :  * comma-separated)
    1455             :  *
    1456             :  * For ZARR, the potential keys are "COMPRESSOR" (value is the JSON encoded
    1457             :  * content from the array definition), "FILTERS" (for Zarr V2, value is JSON
    1458             :  * encoded content) and "TRANSPOSE_ORDER" (value is a string like
    1459             :  * "[idx0,...,idxN]" with the permutation).
    1460             :  *
    1461             :  * For VRT, the potential keys are the ones of the underlying source(s). Note
    1462             :  * that GetRawBlockInfo() on VRT only works when the VRT declares a block size,
    1463             :  * that for each queried VRT block, there is one and only one source that
    1464             :  * is used to fill the VRT block and that the block size of this source is
    1465             :  * exactly the one of the VRT block.
    1466             :  *
    1467             :  * This is the same as C++ method GDALMDArray::GetRawBlockInfo().
    1468             :  *
    1469             :  * @param hArray handle to array.
    1470             :  * @param panBlockCoordinates array of GetDimensionCount() values with the block
    1471             :  *                            coordinates.
    1472             :  * @param[out] psBlockInfo structure to fill with block information.
    1473             :  *                         Must be allocated with GDALMDArrayRawBlockInfoCreate(),
    1474             :  *                         and freed with GDALMDArrayRawBlockInfoRelease().
    1475             :  * @return true in case of success, or false if an error occurs.
    1476             :  * @since 3.12
    1477             :  */
    1478          21 : bool GDALMDArrayGetRawBlockInfo(GDALMDArrayH hArray,
    1479             :                                 const uint64_t *panBlockCoordinates,
    1480             :                                 GDALMDArrayRawBlockInfo *psBlockInfo)
    1481             : {
    1482          21 :     VALIDATE_POINTER1(hArray, __func__, false);
    1483          21 :     VALIDATE_POINTER1(panBlockCoordinates, __func__, false);
    1484          21 :     VALIDATE_POINTER1(psBlockInfo, __func__, false);
    1485          21 :     return hArray->m_poImpl->GetRawBlockInfo(panBlockCoordinates, *psBlockInfo);
    1486             : }
    1487             : 
    1488             : /************************************************************************/
    1489             : /*                   GDALMDArrayRawBlockInfoCreate()                    */
    1490             : /************************************************************************/
    1491             : 
    1492             : /** Allocate a new instance of GDALMDArrayRawBlockInfo.
    1493             :  *
    1494             :  * Returned pointer must be freed with GDALMDArrayRawBlockInfoRelease().
    1495             :  *
    1496             :  * @since 3.12
    1497             :  */
    1498          21 : GDALMDArrayRawBlockInfo *GDALMDArrayRawBlockInfoCreate(void)
    1499             : {
    1500          21 :     return new GDALMDArrayRawBlockInfo();
    1501             : }
    1502             : 
    1503             : /************************************************************************/
    1504             : /*                   GDALMDArrayRawBlockInfoRelease()                   */
    1505             : /************************************************************************/
    1506             : 
    1507             : /** Free an instance of GDALMDArrayRawBlockInfo.
    1508             :  *
    1509             :  * @since 3.12
    1510             :  */
    1511          21 : void GDALMDArrayRawBlockInfoRelease(GDALMDArrayRawBlockInfo *psBlockInfo)
    1512             : {
    1513          21 :     delete psBlockInfo;
    1514          21 : }
    1515             : 
    1516             : /************************************************************************/
    1517             : /*                   GDALMDArray::GetOverviewCount()                    */
    1518             : /************************************************************************/
    1519             : 
    1520             : /**
    1521             :  * \brief Return the number of overview arrays available.
    1522             :  *
    1523             :  * This method is the same as the C function GDALMDArrayGetOverviewCount().
    1524             :  *
    1525             :  * @return overview count, zero if none.
    1526             :  *
    1527             :  * @since 3.13
    1528             :  */
    1529             : 
    1530         118 : int GDALMDArray::GetOverviewCount() const
    1531             : {
    1532         118 :     return 0;
    1533             : }
    1534             : 
    1535             : /************************************************************************/
    1536             : /*                    GDALMDArrayGetOverviewCount()                     */
    1537             : /************************************************************************/
    1538             : /**
    1539             :  * \brief Return the number of overview arrays available.
    1540             :  *
    1541             :  * This method is the same as the C++ method GDALMDArray::GetOverviewCount().
    1542             :  *
    1543             :  * @param hArray Array.
    1544             :  * @return overview count, zero if none.
    1545             :  *
    1546             :  * @since 3.13
    1547             :  */
    1548             : 
    1549         113 : int GDALMDArrayGetOverviewCount(GDALMDArrayH hArray)
    1550             : {
    1551         113 :     VALIDATE_POINTER1(hArray, __func__, 0);
    1552         113 :     return hArray->m_poImpl->GetOverviewCount();
    1553             : }
    1554             : 
    1555             : /************************************************************************/
    1556             : /*                      GDALMDArray::GetOverview()                      */
    1557             : /************************************************************************/
    1558             : 
    1559             : /**
    1560             :  * \brief Get overview array object.
    1561             :  *
    1562             :  * This method is the same as the C function GDALMDArrayGetOverview().
    1563             :  *
    1564             :  * @param nIdx overview index between 0 and GetOverviewCount()-1.
    1565             :  *
    1566             :  * @return overview GDALMDArray, or nullptr
    1567             :  *
    1568             :  * @since 3.13
    1569             :  */
    1570             : 
    1571          70 : std::shared_ptr<GDALMDArray> GDALMDArray::GetOverview(int nIdx) const
    1572             : {
    1573             :     (void)nIdx;
    1574          70 :     return nullptr;
    1575             : }
    1576             : 
    1577             : /************************************************************************/
    1578             : /*                       GDALMDArrayGetOverview()                       */
    1579             : /************************************************************************/
    1580             : 
    1581             : /**
    1582             :  * \brief Get overview array object.
    1583             :  *
    1584             :  * This method is the same as the C++ method GDALMDArray::GetOverview().
    1585             :  *
    1586             :  * @param hArray Array.
    1587             :  * @param nIdx overview index between 0 and GDALMDArrayGetOverviewCount()-1.
    1588             :  *
    1589             :  * @return overview GDALMDArray, or nullptr.
    1590             :  * Must be released with GDALMDArrayRelease()
    1591             :  *
    1592             :  * @since 3.13
    1593             :  */
    1594             : 
    1595         124 : GDALMDArrayH GDALMDArrayGetOverview(GDALMDArrayH hArray, int nIdx)
    1596             : {
    1597         124 :     VALIDATE_POINTER1(hArray, __func__, nullptr);
    1598         248 :     auto poOverview = hArray->m_poImpl->GetOverview(nIdx);
    1599         124 :     if (!poOverview)
    1600          89 :         return nullptr;
    1601          35 :     return new GDALMDArrayHS(poOverview);
    1602             : }
    1603             : 
    1604             : /************************************************************************/
    1605             : /*                    GDALMDArray::BuildOverviews()                     */
    1606             : /************************************************************************/
    1607             : 
    1608             : /** Build overviews for this array.
    1609             :  *
    1610             :  * Creates reduced resolution copies of this array using the specified
    1611             :  * resampling method. The driver is responsible for storing the overview
    1612             :  * arrays and any associated metadata (e.g., multiscales convention for Zarr).
    1613             :  *
    1614             :  * For arrays with more than 2 dimensions, only the spatial dimensions
    1615             :  * (last two by default, or as specified by the spatial:dimensions
    1616             :  * attribute) are downsampled. Non-spatial dimensions are preserved.
    1617             :  *
    1618             :  * Overview factors need not be sorted; the implementation will sort and
    1619             :  * deduplicate them. Each level is resampled sequentially from the
    1620             :  * previous level (e.g., 4x is built from 2x, not from the base).
    1621             :  *
    1622             :  * This method can also be invoked via GDALDataset::BuildOverviews()
    1623             :  * when the dataset was obtained through GDALMDArray::AsClassicDataset().
    1624             :  *
    1625             :  * @note The Zarr v3 implementation replaces all existing overviews on each
    1626             :  * call, unlike GDALDataset::BuildOverviews() which may add new levels.
    1627             :  *
    1628             :  * @note Currently only implemented by the Zarr v3 driver.
    1629             :  *
    1630             :  * @param pszResampling Resampling method name (e.g., "NEAREST", "AVERAGE").
    1631             :  *                      If nullptr or empty, defaults to "NEAREST".
    1632             :  * @param nOverviews Number of overview levels to build. Pass 0 to remove
    1633             :  *                   all existing overviews.
    1634             :  * @param panOverviewList Array of overview decimation factors (e.g., 2, 4, 8).
    1635             :  *                        Each factor must be >= 2. May be nullptr when
    1636             :  *                        nOverviews is 0.
    1637             :  * @param pfnProgress Progress callback, or nullptr.
    1638             :  * @param pProgressData Progress callback user data.
    1639             :  * @param papszOptions Driver-specific options, or nullptr.
    1640             :  * @return CE_None on success, CE_Failure otherwise.
    1641             :  * @since GDAL 3.13
    1642             :  */
    1643           2 : CPLErr GDALMDArray::BuildOverviews(CPL_UNUSED const char *pszResampling,
    1644             :                                    CPL_UNUSED int nOverviews,
    1645             :                                    CPL_UNUSED const int *panOverviewList,
    1646             :                                    CPL_UNUSED GDALProgressFunc pfnProgress,
    1647             :                                    CPL_UNUSED void *pProgressData,
    1648             :                                    CPL_UNUSED CSLConstList papszOptions)
    1649             : {
    1650           2 :     CPLError(CE_Failure, CPLE_NotSupported,
    1651             :              "BuildOverviews() not supported by this driver");
    1652           2 :     return CE_Failure;
    1653             : }
    1654             : 
    1655             : /************************************************************************/
    1656             : /*                     GDALMDArrayBuildOverviews()                      */
    1657             : /************************************************************************/
    1658             : 
    1659             : /** \brief Build overviews for a multidimensional array.
    1660             :  *
    1661             :  * This is the same as the C++ method GDALMDArray::BuildOverviews().
    1662             :  *
    1663             :  * @since GDAL 3.13
    1664             :  */
    1665          13 : CPLErr GDALMDArrayBuildOverviews(GDALMDArrayH hArray, const char *pszResampling,
    1666             :                                  int nOverviews, const int *panOverviewList,
    1667             :                                  GDALProgressFunc pfnProgress,
    1668             :                                  void *pProgressData, CSLConstList papszOptions)
    1669             : {
    1670          13 :     VALIDATE_POINTER1(hArray, __func__, CE_Failure);
    1671          26 :     return hArray->m_poImpl->BuildOverviews(pszResampling, nOverviews,
    1672             :                                             panOverviewList, pfnProgress,
    1673          13 :                                             pProgressData, papszOptions);
    1674             : }

Generated by: LCOV version 1.14