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 8 : GDALMdimInfoAlgorithm::GDALMdimInfoAlgorithm()
30 8 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
31 : {
32 8 : AddOutputFormatArg(&m_format).SetHidden().SetDefault("json").SetChoices(
33 8 : "json", "text");
34 8 : AddOpenOptionsArg(&m_openOptions);
35 8 : AddInputFormatsArg(&m_inputFormats)
36 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES,
37 16 : {GDAL_DCAP_MULTIDIM_RASTER});
38 8 : AddInputDatasetArg(&m_dataset, GDAL_OF_MULTIDIM_RASTER).AddAlias("dataset");
39 8 : AddOutputStringArg(&m_output);
40 : AddArg(
41 : "detailed", 0,
42 : _("Most verbose output. Report attribute data types and array values."),
43 8 : &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 8 : &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 8 : });
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 8 : &m_limit);
73 : {
74 : auto &arg = AddArg("array-option", 0,
75 : _("Option passed to GDALGroup::GetMDArrayNames() to "
76 : "filter reported arrays."),
77 16 : &m_arrayOptions)
78 16 : .SetMetaVar("<KEY>=<VALUE>")
79 8 : .SetPackedValuesAllowed(false);
80 1 : arg.AddValidationAction([this, &arg]()
81 9 : { 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 8 : });
104 : }
105 8 : AddArg("stats", 0, _("Read and display image statistics."), &m_stats);
106 :
107 8 : AddStdoutArg(&m_stdout);
108 8 : }
109 :
110 : /************************************************************************/
111 : /* GDALMdimInfoAlgorithm::RunImpl() */
112 : /************************************************************************/
113 :
114 3 : bool GDALMdimInfoAlgorithm::RunImpl(GDALProgressFunc, void *)
115 : {
116 3 : CPLAssert(m_dataset.GetDatasetRef());
117 :
118 3 : CPLStringList aosOptions;
119 :
120 3 : if (m_stdout)
121 1 : aosOptions.AddString("-stdout");
122 3 : if (m_detailed)
123 1 : aosOptions.AddString("-detailed");
124 3 : if (m_stats)
125 1 : aosOptions.AddString("-stats");
126 3 : if (m_limit > 0)
127 : {
128 1 : aosOptions.AddString("-limit");
129 1 : aosOptions.AddString(CPLSPrintf("%d", m_limit));
130 : }
131 3 : if (!m_array.empty())
132 : {
133 1 : aosOptions.AddString("-array");
134 1 : aosOptions.AddString(m_array.c_str());
135 : }
136 4 : for (const std::string &opt : m_arrayOptions)
137 : {
138 1 : aosOptions.AddString("-arrayoption");
139 1 : aosOptions.AddString(opt.c_str());
140 : }
141 :
142 3 : GDALDatasetH hDS = GDALDataset::ToHandle(m_dataset.GetDatasetRef());
143 : GDALMultiDimInfoOptions *psOptions =
144 3 : GDALMultiDimInfoOptionsNew(aosOptions.List(), nullptr);
145 3 : char *ret = GDALMultiDimInfo(hDS, psOptions);
146 3 : GDALMultiDimInfoOptionsFree(psOptions);
147 3 : const bool bOK = ret != nullptr;
148 3 : if (ret && !m_stdout)
149 : {
150 2 : m_output = ret;
151 : }
152 3 : CPLFree(ret);
153 :
154 6 : return bOK;
155 : }
156 :
157 : //! @endcond
|