Line data Source code
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 : #define _(x) (x)
23 : #endif
24 :
25 : /************************************************************************/
26 : /* GDALMdimInfoAlgorithm::GDALMdimInfoAlgorithm() */
27 : /************************************************************************/
28 :
29 7 : GDALMdimInfoAlgorithm::GDALMdimInfoAlgorithm()
30 7 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
31 : {
32 7 : AddOutputFormatArg(&m_format).SetHidden().SetDefault("json").SetChoices(
33 7 : "json", "text");
34 7 : AddOpenOptionsArg(&m_openOptions);
35 7 : AddInputFormatsArg(&m_inputFormats)
36 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES,
37 14 : {GDAL_DCAP_MULTIDIM_RASTER});
38 7 : AddInputDatasetArg(&m_dataset, GDAL_OF_MULTIDIM_RASTER).AddAlias("dataset");
39 7 : AddOutputStringArg(&m_output);
40 : AddArg(
41 : "detailed", 0,
42 : _("Most verbose output. Report attribute data types and array values."),
43 7 : &m_detailed);
44 : {
45 : auto &arg = AddArg("array", 0,
46 : _("Name of the array, used to restrict the output "
47 : "to the specified array."),
48 7 : &m_array);
49 :
50 : arg.SetAutoCompleteFunction(
51 4 : [this](const std::string &)
52 : {
53 2 : std::vector<std::string> ret;
54 :
55 2 : if (auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open(
56 2 : m_dataset.GetName().c_str(), GDAL_OF_MULTIDIM_RASTER,
57 4 : nullptr, nullptr, nullptr)))
58 : {
59 2 : if (auto poRG = poDS->GetRootGroup())
60 : {
61 1 : ret = poRG->GetMDArrayFullNamesRecursive();
62 : }
63 : }
64 :
65 2 : return ret;
66 7 : });
67 : }
68 :
69 : AddArg("limit", 0,
70 : _("Number of values in each dimension that is used to limit the "
71 : "display of array values."),
72 7 : &m_limit);
73 : {
74 : auto &arg = AddArg("array-option", 0,
75 : _("Option passed to GDALGroup::GetMDArrayNames() to "
76 : "filter reported arrays."),
77 14 : &m_arrayOptions)
78 14 : .SetMetaVar("<KEY>=<VALUE>")
79 7 : .SetPackedValuesAllowed(false);
80 1 : arg.AddValidationAction([this, &arg]()
81 8 : { return ParseAndValidateKeyValue(arg); });
82 :
83 : arg.SetAutoCompleteFunction(
84 4 : [this](const std::string ¤tValue)
85 : {
86 2 : std::vector<std::string> ret;
87 :
88 2 : if (auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open(
89 2 : m_dataset.GetName().c_str(), GDAL_OF_MULTIDIM_RASTER,
90 4 : nullptr, nullptr, nullptr)))
91 : {
92 1 : if (auto poDriver = poDS->GetDriver())
93 : {
94 1 : if (const char *pszXML = poDriver->GetMetadataItem(
95 1 : GDAL_DMD_MULTIDIM_ARRAY_OPENOPTIONLIST))
96 : {
97 1 : AddOptionsSuggestions(pszXML, 0, currentValue, ret);
98 : }
99 : }
100 : }
101 :
102 2 : return ret;
103 7 : });
104 : }
105 7 : AddArg("stats", 0, _("Read and display image statistics."), &m_stats);
106 :
107 : AddArg("stdout", 0,
108 : _("Directly output on stdout. If enabled, "
109 : "output-string will be empty"),
110 14 : &m_stdout)
111 7 : .SetHiddenForCLI();
112 7 : }
113 :
114 : /************************************************************************/
115 : /* GDALMdimInfoAlgorithm::RunImpl() */
116 : /************************************************************************/
117 :
118 2 : bool GDALMdimInfoAlgorithm::RunImpl(GDALProgressFunc, void *)
119 : {
120 2 : CPLAssert(m_dataset.GetDatasetRef());
121 :
122 2 : CPLStringList aosOptions;
123 :
124 2 : if (m_stdout)
125 0 : aosOptions.AddString("-stdout");
126 2 : if (m_detailed)
127 1 : aosOptions.AddString("-detailed");
128 2 : if (m_stats)
129 1 : aosOptions.AddString("-stats");
130 2 : if (m_limit > 0)
131 : {
132 1 : aosOptions.AddString("-limit");
133 1 : aosOptions.AddString(CPLSPrintf("%d", m_limit));
134 : }
135 2 : if (!m_array.empty())
136 : {
137 1 : aosOptions.AddString("-array");
138 1 : aosOptions.AddString(m_array.c_str());
139 : }
140 3 : for (const std::string &opt : m_arrayOptions)
141 : {
142 1 : aosOptions.AddString("-arrayoption");
143 1 : aosOptions.AddString(opt.c_str());
144 : }
145 :
146 2 : GDALDatasetH hDS = GDALDataset::ToHandle(m_dataset.GetDatasetRef());
147 : GDALMultiDimInfoOptions *psOptions =
148 2 : GDALMultiDimInfoOptionsNew(aosOptions.List(), nullptr);
149 2 : char *ret = GDALMultiDimInfo(hDS, psOptions);
150 2 : GDALMultiDimInfoOptionsFree(psOptions);
151 2 : const bool bOK = ret != nullptr;
152 2 : if (ret)
153 : {
154 2 : m_output = ret;
155 : }
156 2 : CPLFree(ret);
157 :
158 4 : return bOK;
159 : }
160 :
161 : //! @endcond
|