Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_mdim_info.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  gdal "mdim info" subcommand
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "gdalalg_mdim_info.h"
14
15
#include "cpl_conv.h"
16
#include "gdal_priv.h"
17
#include "gdal_utils.h"
18
19
//! @cond Doxygen_Suppress
20
21
#ifndef _
22
0
#define _(x) (x)
23
#endif
24
25
/************************************************************************/
26
/*            GDALMdimInfoAlgorithm::GDALMdimInfoAlgorithm()            */
27
/************************************************************************/
28
29
GDALMdimInfoAlgorithm::GDALMdimInfoAlgorithm(bool standaloneStep,
30
                                             bool openForMixedRasterVector)
31
0
    : GDALMdimPipelineStepAlgorithm(
32
0
          NAME, DESCRIPTION, HELP_URL,
33
0
          ConstructorOptions()
34
0
              .SetStandaloneStep(standaloneStep)
35
0
              .SetInputDatasetMaxCount(1)
36
0
              .SetAddDefaultArguments(false)
37
0
              .SetInputDatasetHelpMsg(_("Input multidimensional dataset"))
38
0
              .SetInputDatasetAlias("dataset"))
39
0
{
40
0
    if (standaloneStep)
41
0
    {
42
0
        AddProgressArg(/* hidden = */ true);
43
0
        AddMdimInputArgs(openForMixedRasterVector,
44
0
                         /* hiddenForCLI = */ false,
45
0
                         /* acceptRaster = */ false);
46
0
    }
47
0
    else
48
0
    {
49
0
        AddMdimHiddenInputDatasetArg();
50
0
    }
51
52
0
    AddOutputFormatArg(&m_format).SetChoices("json", "text");
53
0
    AddArg("summary", 0,
54
0
           _("Report only group and array hierarchy, without detailed "
55
0
             "information on attributes or dimensions."),
56
0
           &m_summary)
57
0
        .SetMutualExclusionGroup("structure_detailed");
58
0
    AddArg(
59
0
        "detailed", 0,
60
0
        _("Most verbose output. Report attribute data types and array values."),
61
0
        &m_detailed)
62
0
        .SetMutualExclusionGroup("structure_detailed");
63
0
    AddArrayNameArg(&m_array, _("Name of the array, used to restrict the "
64
0
                                "output to the specified array."));
65
66
0
    AddArg("limit", 0,
67
0
           _("Number of values in each dimension that is used to limit the "
68
0
             "display of array values."),
69
0
           &m_limit);
70
0
    {
71
0
        auto &arg = AddArg("array-option", 0,
72
0
                           _("Option passed to GDALGroup::GetMDArrayNames() to "
73
0
                             "filter reported arrays."),
74
0
                           &m_arrayOptions)
75
0
                        .SetMetaVar("<KEY>=<VALUE>")
76
0
                        .SetPackedValuesAllowed(false);
77
0
        arg.AddValidationAction([this, &arg]()
78
0
                                { return ParseAndValidateKeyValue(arg); });
79
80
0
        arg.SetAutoCompleteFunction(
81
0
            [this](const std::string &currentValue)
82
0
            {
83
0
                std::vector<std::string> ret;
84
0
                if (m_inputDataset.size() == 1)
85
0
                {
86
0
                    if (auto poDS =
87
0
                            std::unique_ptr<GDALDataset>(GDALDataset::Open(
88
0
                                m_inputDataset[0].GetName().c_str(),
89
0
                                GDAL_OF_MULTIDIM_RASTER, nullptr, nullptr,
90
0
                                nullptr)))
91
0
                    {
92
0
                        if (auto poDriver = poDS->GetDriver())
93
0
                        {
94
0
                            if (const char *pszXML = poDriver->GetMetadataItem(
95
0
                                    GDAL_DMD_MULTIDIM_ARRAY_OPENOPTIONLIST))
96
0
                            {
97
0
                                AddOptionsSuggestions(pszXML, 0, currentValue,
98
0
                                                      ret);
99
0
                            }
100
0
                        }
101
0
                    }
102
0
                }
103
104
0
                return ret;
105
0
            });
106
0
    }
107
0
    AddArg("stats", 0, _("Read and display image statistics."), &m_stats);
108
109
0
    AddOutputStringArg(&m_output);
110
0
    AddStdoutArg(&m_stdout);
111
0
}
112
113
/************************************************************************/
114
/*                   GDALMdimInfoAlgorithm::RunStep()                   */
115
/************************************************************************/
116
117
bool GDALMdimInfoAlgorithm::RunStep(GDALPipelineStepRunContext &)
118
0
{
119
0
    CPLAssert(m_inputDataset.size() == 1);
120
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
121
0
    CPLAssert(poSrcDS);
122
123
0
    if (m_format.empty())
124
0
        m_format = IsCalledFromCommandLine() ? "text" : "json";
125
126
0
    CPLStringList aosOptions;
127
128
0
    aosOptions.AddString("-format");
129
0
    aosOptions.AddString(m_format);
130
0
    if (m_stdout)
131
0
        aosOptions.AddString("-stdout");
132
0
    if (m_summary)
133
0
        aosOptions.AddString("-summary");
134
0
    else if (m_detailed)
135
0
        aosOptions.AddString("-detailed");
136
0
    if (m_stats)
137
0
        aosOptions.AddString("-stats");
138
0
    if (m_limit > 0)
139
0
    {
140
0
        aosOptions.AddString("-limit");
141
0
        aosOptions.AddString(CPLSPrintf("%d", m_limit));
142
0
    }
143
0
    if (!m_array.empty())
144
0
    {
145
0
        aosOptions.AddString("-array");
146
0
        aosOptions.AddString(m_array.c_str());
147
0
    }
148
0
    for (const std::string &opt : m_arrayOptions)
149
0
    {
150
0
        aosOptions.AddString("-arrayoption");
151
0
        aosOptions.AddString(opt.c_str());
152
0
    }
153
154
0
    GDALDatasetH hDS = GDALDataset::ToHandle(poSrcDS);
155
0
    GDALMultiDimInfoOptions *psOptions =
156
0
        GDALMultiDimInfoOptionsNew(aosOptions.List(), nullptr);
157
0
    char *ret = GDALMultiDimInfo(hDS, psOptions);
158
0
    GDALMultiDimInfoOptionsFree(psOptions);
159
0
    const bool bOK = ret != nullptr;
160
0
    if (ret && !m_stdout)
161
0
    {
162
0
        m_output = ret;
163
0
    }
164
0
    CPLFree(ret);
165
166
0
    return bOK;
167
0
}
168
169
0
GDALMdimInfoAlgorithmStandalone::~GDALMdimInfoAlgorithmStandalone() = default;
170
171
//! @endcond