Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: gdal "vector info" subcommand
5 : * Author: Even Rouault <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdalalg_vector_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 : /* GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm() */
27 : /************************************************************************/
28 :
29 234 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm(bool standaloneStep)
30 : : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
31 0 : ConstructorOptions()
32 234 : .SetStandaloneStep(standaloneStep)
33 234 : .SetInputDatasetMaxCount(1)
34 468 : .SetAddDefaultArguments(false))
35 : {
36 234 : if (standaloneStep)
37 152 : AddProgressArg(/* hidden = */ true);
38 :
39 234 : AddOutputFormatArg(&m_format).SetChoices("json", "text");
40 234 : AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep);
41 234 : AddInputFormatsArg(&m_inputFormats)
42 702 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR})
43 234 : .SetHiddenForCLI(!standaloneStep);
44 :
45 : auto &datasetArg =
46 234 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR).AddAlias("dataset");
47 234 : if (!standaloneStep)
48 82 : datasetArg.SetHidden();
49 234 : auto &layerArg = AddLayerNameArg(&m_layerNames)
50 468 : .SetMutualExclusionGroup("layer-sql")
51 234 : .AddAlias("layer");
52 234 : SetAutoCompleteFunctionForLayerName(layerArg, datasetArg);
53 : auto &argFeature =
54 : AddArg(
55 : "features", 0,
56 : _("List all features (beware of RAM consumption on large layers)"),
57 468 : &m_listFeatures)
58 234 : .SetMutualExclusionGroup("summary-features");
59 : AddArg("summary", 0, _("List the layer names and the geometry type"),
60 468 : &m_summaryOnly)
61 234 : .SetMutualExclusionGroup("summary-features");
62 : AddArg("limit", 0,
63 : _("Limit the number of features per layer (implies --features)"),
64 468 : &m_limit)
65 234 : .SetMinValueIncluded(0)
66 468 : .SetMetaVar("FEATURE-COUNT")
67 237 : .AddAction([&argFeature]() { argFeature.Set(true); });
68 : AddArg("sql", 0,
69 : _("Execute the indicated SQL statement and return the result"),
70 468 : &m_sql)
71 234 : .SetReadFromFileAtSyntaxAllowed()
72 468 : .SetMetaVar("<statement>|@<filename>")
73 234 : .SetRemoveSQLCommentsEnabled()
74 234 : .SetMutualExclusionGroup("layer-sql");
75 : AddArg("where", 0,
76 : _("Attribute query in a restricted form of the queries used in the "
77 : "SQL WHERE statement"),
78 468 : &m_where)
79 234 : .SetReadFromFileAtSyntaxAllowed()
80 468 : .SetMetaVar("<WHERE>|@<filename>")
81 234 : .SetRemoveSQLCommentsEnabled();
82 468 : AddArg("fid", 0, _("Feature identifier"), &m_fid)
83 468 : .SetMetaVar("FID")
84 234 : .SetMutualExclusionGroup("layer-sql");
85 234 : AddArg("dialect", 0, _("SQL dialect"), &m_dialect);
86 234 : AddOutputStringArg(&m_output);
87 234 : AddStdoutArg(&m_stdout);
88 : AddArg("crs-format", 0, _("Which format to use to report CRS"),
89 468 : &m_crsFormat)
90 234 : .SetChoices("AUTO", "WKT2", "PROJJSON")
91 234 : .SetDefault(m_crsFormat)
92 234 : .SetCategory(GAAC_ESOTERIC);
93 :
94 234 : AddValidationAction(
95 149 : [this]()
96 : {
97 72 : if (!m_sql.empty() && !m_where.empty())
98 : {
99 1 : ReportError(CE_Failure, CPLE_NotSupported,
100 : "Option 'sql' and 'where' are mutually exclusive");
101 1 : return false;
102 : }
103 :
104 71 : if (m_crsFormat != "AUTO" && m_format == "json")
105 : {
106 0 : ReportError(CE_Failure, CPLE_AppDefined,
107 : "'crs-format' cannot be set when 'format' is set "
108 : "to 'json'");
109 0 : return false;
110 : }
111 :
112 71 : return true;
113 : });
114 234 : }
115 :
116 : /************************************************************************/
117 : /* GDALVectorInfoAlgorithm::RunStep() */
118 : /************************************************************************/
119 :
120 32 : bool GDALVectorInfoAlgorithm::RunStep(GDALPipelineStepRunContext &)
121 : {
122 32 : CPLAssert(m_inputDataset.size() == 1);
123 32 : auto poSrcDS = m_inputDataset[0].GetDatasetRef();
124 32 : CPLAssert(poSrcDS);
125 :
126 32 : if (m_format.empty())
127 19 : m_format = IsCalledFromCommandLine() ? "text" : "json";
128 :
129 64 : CPLStringList aosOptions;
130 :
131 32 : aosOptions.AddString("--cli");
132 32 : aosOptions.AddString("--crs-format=" + m_crsFormat);
133 :
134 32 : if (m_format == "json")
135 : {
136 18 : aosOptions.AddString("-json");
137 : }
138 :
139 32 : if (m_summaryOnly)
140 : {
141 4 : aosOptions.AddString("-summary");
142 : }
143 28 : else if (m_listFeatures)
144 : {
145 5 : aosOptions.AddString("-features");
146 : }
147 :
148 32 : if (!m_sql.empty())
149 : {
150 2 : aosOptions.AddString("-sql");
151 2 : aosOptions.AddString(m_sql.c_str());
152 : }
153 32 : if (!m_where.empty())
154 : {
155 2 : aosOptions.AddString("-where");
156 2 : aosOptions.AddString(m_where.c_str());
157 : }
158 32 : if (m_fid >= 0)
159 : {
160 1 : aosOptions.AddString("-fid");
161 1 : aosOptions.AddString(CPLSPrintf("%d", m_fid));
162 : }
163 32 : if (!m_dialect.empty())
164 : {
165 2 : aosOptions.AddString("-dialect");
166 2 : aosOptions.AddString(m_dialect.c_str());
167 : }
168 32 : if (m_stdout)
169 : {
170 6 : aosOptions.AddString("-stdout");
171 : }
172 32 : if (m_limit > 0)
173 : {
174 1 : aosOptions.AddString("-limit");
175 1 : aosOptions.AddString(std::to_string(m_limit));
176 : }
177 :
178 : // Must be last, as positional
179 32 : aosOptions.AddString("dummy");
180 33 : for (const std::string &name : m_layerNames)
181 1 : aosOptions.AddString(name.c_str());
182 :
183 32 : if (m_layerNames.empty())
184 : {
185 31 : aosOptions.AddString("-al");
186 : }
187 :
188 : GDALVectorInfoOptions *psInfo =
189 32 : GDALVectorInfoOptionsNew(aosOptions.List(), nullptr);
190 :
191 32 : char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo);
192 32 : GDALVectorInfoOptionsFree(psInfo);
193 32 : if (!ret)
194 0 : return false;
195 :
196 32 : m_output = ret;
197 32 : CPLFree(ret);
198 :
199 32 : return true;
200 : }
201 :
202 : GDALVectorInfoAlgorithmStandalone::~GDALVectorInfoAlgorithmStandalone() =
203 : default;
204 :
205 : //! @endcond
|