/src/gdal/apps/gdalalg_vector_select.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL |
4 | | * Purpose: "select" step of "vector pipeline" |
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_select.h" |
14 | | |
15 | | #include "gdal_priv.h" |
16 | | #include "ogrsf_frmts.h" |
17 | | #include "ogr_p.h" |
18 | | |
19 | | #include <set> |
20 | | |
21 | | //! @cond Doxygen_Suppress |
22 | | |
23 | | #ifndef _ |
24 | 0 | #define _(x) (x) |
25 | | #endif |
26 | | |
27 | | /************************************************************************/ |
28 | | /* GDALVectorSelectAlgorithm::GDALVectorSelectAlgorithm() */ |
29 | | /************************************************************************/ |
30 | | |
31 | | GDALVectorSelectAlgorithm::GDALVectorSelectAlgorithm(bool standaloneStep) |
32 | 0 | : GDALVectorPipelineStepAlgorithm( |
33 | 0 | NAME, DESCRIPTION, HELP_URL, |
34 | 0 | ConstructorOptions() |
35 | 0 | .SetStandaloneStep(standaloneStep) |
36 | 0 | .SetOutputLayerNameAvailableInPipelineStep(true)) |
37 | 0 | { |
38 | 0 | AddActiveLayerArg(&m_activeLayer); |
39 | 0 | if (!standaloneStep) |
40 | 0 | { |
41 | 0 | AddOutputLayerNameArg(/* hiddenForCLI = */ false, |
42 | 0 | /* shortNameOutputLayerAllowed = */ false); |
43 | 0 | } |
44 | 0 | AddArg("fields", 0, _("Fields to select (or exclude if --exclude)"), |
45 | 0 | &m_fieldsDeprecated) |
46 | 0 | .SetDuplicateValuesAllowed(false) |
47 | 0 | .SetPositional() |
48 | 0 | .SetHidden(); |
49 | |
|
50 | 0 | { |
51 | 0 | auto &arg = |
52 | 0 | AddArg("field", 0, _("Attribute fields(s) to select"), &m_fields) |
53 | 0 | .SetDuplicateValuesAllowed(false) |
54 | 0 | .SetMetaVar("FIELD"); |
55 | |
|
56 | 0 | SetAutoCompleteFunctionForFieldName(arg, nullptr, true, false, |
57 | 0 | m_inputDataset); |
58 | 0 | } |
59 | |
|
60 | 0 | AddArg("geometry", 0, _("Select default geometry field"), &m_defaultGeom); |
61 | |
|
62 | 0 | { |
63 | 0 | auto &arg = AddArg("geometry-field", 0, |
64 | 0 | _("Geometry field(s) to select"), &m_geomFields) |
65 | 0 | .SetDuplicateValuesAllowed(false) |
66 | 0 | .SetMetaVar("GEOMETRY-FIELD"); |
67 | 0 | SetAutoCompleteFunctionForFieldName(arg, nullptr, false, true, |
68 | 0 | m_inputDataset); |
69 | 0 | } |
70 | |
|
71 | 0 | AddArg("exclude", 0, _("Exclude specified fields"), &m_exclude) |
72 | 0 | .SetDuplicateValuesAllowed(false) |
73 | 0 | .SetMutualExclusionGroup("exclude-ignore"); |
74 | 0 | AddArg("ignore-missing-fields", 0, _("Ignore missing fields"), |
75 | 0 | &m_ignoreMissingFields) |
76 | 0 | .SetMutualExclusionGroup("exclude-ignore"); |
77 | |
|
78 | 0 | AddValidationAction( |
79 | 0 | [this]() |
80 | 0 | { |
81 | 0 | if (!m_outputLayerName.empty() && m_activeLayer.empty() && |
82 | 0 | m_inputDataset.size() == 1) |
83 | 0 | { |
84 | 0 | auto poSrcDS = m_inputDataset[0].GetDatasetRef(); |
85 | 0 | if (poSrcDS && poSrcDS->GetLayerCount() > 1) |
86 | 0 | { |
87 | 0 | ReportError(CE_Failure, CPLE_IllegalArg, |
88 | 0 | "Argument 'output-layer' cannot be used when " |
89 | 0 | "the input dataset has multiple layers, unless " |
90 | 0 | "argument 'active-layer' is specified"); |
91 | 0 | return false; |
92 | 0 | } |
93 | 0 | } |
94 | 0 | return true; |
95 | 0 | }); |
96 | 0 | } |
97 | | |
98 | | namespace |
99 | | { |
100 | | |
101 | | /************************************************************************/ |
102 | | /* GDALVectorSelectAlgorithmLayer */ |
103 | | /************************************************************************/ |
104 | | |
105 | | class GDALVectorSelectAlgorithmLayer final |
106 | | : public GDALVectorPipelineOutputLayer |
107 | | { |
108 | | private: |
109 | | const OGRFeatureDefnRefCountedPtr m_poFeatureDefn; |
110 | | std::vector<int> m_anMapSrcFieldsToDstFields{}; |
111 | | std::vector<int> m_anMapDstGeomFieldsToSrcGeomFields{}; |
112 | | |
113 | | CPL_DISALLOW_COPY_ASSIGN(GDALVectorSelectAlgorithmLayer) |
114 | | |
115 | | std::unique_ptr<OGRFeature> |
116 | | TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const |
117 | 0 | { |
118 | 0 | auto poFeature = std::make_unique<OGRFeature>(m_poFeatureDefn.get()); |
119 | 0 | poFeature->SetFID(poSrcFeature->GetFID()); |
120 | 0 | const auto styleString = poSrcFeature->GetStyleString(); |
121 | 0 | if (styleString) |
122 | 0 | poFeature->SetStyleString(styleString); |
123 | 0 | poFeature->SetFieldsFrom(poSrcFeature.get(), |
124 | 0 | m_anMapSrcFieldsToDstFields.data(), false, |
125 | 0 | false); |
126 | 0 | int iDstGeomField = 0; |
127 | 0 | for (int nSrcGeomField : m_anMapDstGeomFieldsToSrcGeomFields) |
128 | 0 | { |
129 | 0 | poFeature->SetGeomFieldDirectly( |
130 | 0 | iDstGeomField, poSrcFeature->StealGeometry(nSrcGeomField)); |
131 | 0 | ++iDstGeomField; |
132 | 0 | } |
133 | 0 | return poFeature; |
134 | 0 | } |
135 | | |
136 | | bool TranslateFeature( |
137 | | std::unique_ptr<OGRFeature> poSrcFeature, |
138 | | std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override |
139 | 0 | { |
140 | 0 | auto poDstFeature = TranslateFeature(std::move(poSrcFeature)); |
141 | 0 | if (PassesFilters(poDstFeature.get())) |
142 | 0 | { |
143 | 0 | apoOutFeatures.push_back(std::move(poDstFeature)); |
144 | 0 | } |
145 | 0 | return true; |
146 | 0 | } |
147 | | |
148 | | public: |
149 | | explicit GDALVectorSelectAlgorithmLayer( |
150 | | OGRLayer &oSrcLayer, const std::string &osOutputLayerName) |
151 | 0 | : GDALVectorPipelineOutputLayer(oSrcLayer), |
152 | 0 | m_poFeatureDefn(OGRFeatureDefnRefCountedPtr::makeInstance( |
153 | 0 | osOutputLayerName.empty() ? oSrcLayer.GetName() |
154 | 0 | : osOutputLayerName.c_str())) |
155 | 0 | { |
156 | 0 | SetDescription(m_poFeatureDefn->GetName()); |
157 | 0 | SetMetadata(oSrcLayer.GetMetadata()); |
158 | 0 | m_poFeatureDefn->SetGeomType(wkbNone); |
159 | 0 | } |
160 | | |
161 | | bool IncludeFieldsDeprecated(const std::vector<std::string> &selectedFields, |
162 | | bool bStrict) |
163 | 0 | { |
164 | 0 | std::set<std::string> oSetSelFields; |
165 | 0 | std::set<std::string> oSetSelFieldsUC; |
166 | 0 | for (const std::string &osFieldName : selectedFields) |
167 | 0 | { |
168 | 0 | oSetSelFields.insert(osFieldName); |
169 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
170 | 0 | } |
171 | |
|
172 | 0 | std::set<std::string> oSetUsedSetFieldsUC; |
173 | |
|
174 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
175 | 0 | for (const auto poSrcFieldDefn : poSrcLayerDefn->GetFields()) |
176 | 0 | { |
177 | 0 | const auto oIter = oSetSelFieldsUC.find( |
178 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
179 | 0 | if (oIter != oSetSelFieldsUC.end()) |
180 | 0 | { |
181 | 0 | m_anMapSrcFieldsToDstFields.push_back( |
182 | 0 | m_poFeatureDefn->GetFieldCount()); |
183 | 0 | OGRFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
184 | 0 | m_poFeatureDefn->AddFieldDefn(&oDstFieldDefn); |
185 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
186 | 0 | } |
187 | 0 | else |
188 | 0 | { |
189 | 0 | m_anMapSrcFieldsToDstFields.push_back(-1); |
190 | 0 | } |
191 | 0 | } |
192 | |
|
193 | 0 | const int nSrcGeomFieldCount = poSrcLayerDefn->GetGeomFieldCount(); |
194 | 0 | for (int i = 0; i < nSrcGeomFieldCount; ++i) |
195 | 0 | { |
196 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(i); |
197 | 0 | const auto oIter = oSetSelFieldsUC.find( |
198 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
199 | 0 | if (oIter != oSetSelFieldsUC.end()) |
200 | 0 | { |
201 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(i); |
202 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
203 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
204 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
205 | 0 | } |
206 | 0 | } |
207 | |
|
208 | 0 | const auto oIter = oSetSelFieldsUC.find( |
209 | 0 | CPLString(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME).toupper()); |
210 | 0 | if (m_poFeatureDefn->GetGeomFieldCount() == 0 && |
211 | 0 | oIter != oSetSelFieldsUC.end() && |
212 | 0 | poSrcLayerDefn->GetGeomFieldCount() == 1) |
213 | 0 | { |
214 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(0); |
215 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(0); |
216 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
217 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
218 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
219 | 0 | } |
220 | |
|
221 | 0 | if (oSetUsedSetFieldsUC.size() != oSetSelFields.size()) |
222 | 0 | { |
223 | 0 | for (const std::string &osName : oSetSelFields) |
224 | 0 | { |
225 | 0 | if (!cpl::contains(oSetUsedSetFieldsUC, |
226 | 0 | CPLString(osName).toupper())) |
227 | 0 | { |
228 | 0 | CPLError(bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, |
229 | 0 | "Field '%s' does not exist in layer '%s'.%s", |
230 | 0 | osName.c_str(), m_srcLayer.GetDescription(), |
231 | 0 | bStrict ? " You may specify " |
232 | 0 | "--ignore-missing-fields to skip it" |
233 | 0 | : " It will be ignored"); |
234 | 0 | if (bStrict) |
235 | 0 | return false; |
236 | 0 | } |
237 | 0 | } |
238 | 0 | } |
239 | | |
240 | 0 | return true; |
241 | 0 | } |
242 | | |
243 | | bool IncludeAttributeFields(const std::vector<std::string> &selectedFields, |
244 | | bool bStrict) |
245 | 0 | { |
246 | 0 | std::set<std::string> oSetSelFields; |
247 | 0 | std::set<std::string> oSetSelFieldsUC; |
248 | 0 | for (const std::string &osFieldName : selectedFields) |
249 | 0 | { |
250 | 0 | oSetSelFields.insert(osFieldName); |
251 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
252 | 0 | } |
253 | |
|
254 | 0 | std::set<std::string> oSetUsedSetFieldsUC; |
255 | |
|
256 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
257 | 0 | for (const auto poSrcFieldDefn : poSrcLayerDefn->GetFields()) |
258 | 0 | { |
259 | 0 | const auto oIter = oSetSelFieldsUC.find( |
260 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
261 | 0 | if (oIter != oSetSelFieldsUC.end()) |
262 | 0 | { |
263 | 0 | m_anMapSrcFieldsToDstFields.push_back( |
264 | 0 | m_poFeatureDefn->GetFieldCount()); |
265 | 0 | OGRFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
266 | 0 | m_poFeatureDefn->AddFieldDefn(&oDstFieldDefn); |
267 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
268 | 0 | } |
269 | 0 | else |
270 | 0 | { |
271 | 0 | m_anMapSrcFieldsToDstFields.push_back(-1); |
272 | 0 | } |
273 | 0 | } |
274 | |
|
275 | 0 | if (oSetUsedSetFieldsUC.size() != oSetSelFields.size()) |
276 | 0 | { |
277 | 0 | for (const std::string &osName : oSetSelFields) |
278 | 0 | { |
279 | 0 | if (!cpl::contains(oSetUsedSetFieldsUC, |
280 | 0 | CPLString(osName).toupper())) |
281 | 0 | { |
282 | 0 | CPLError(bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, |
283 | 0 | "Field '%s' does not exist in layer '%s'.%s", |
284 | 0 | osName.c_str(), m_srcLayer.GetDescription(), |
285 | 0 | bStrict ? " You may specify " |
286 | 0 | "--ignore-missing-fields to skip it" |
287 | 0 | : " It will be ignored"); |
288 | 0 | if (bStrict) |
289 | 0 | return false; |
290 | 0 | } |
291 | 0 | } |
292 | 0 | } |
293 | | |
294 | 0 | return true; |
295 | 0 | } |
296 | | |
297 | | bool IncludeGeometryFields(const std::vector<std::string> &selectedFields, |
298 | | bool bStrict) |
299 | 0 | { |
300 | 0 | std::set<std::string> oSetSelFields; |
301 | 0 | std::set<std::string> oSetSelFieldsUC; |
302 | 0 | for (const std::string &osFieldName : selectedFields) |
303 | 0 | { |
304 | 0 | oSetSelFields.insert(osFieldName); |
305 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
306 | 0 | } |
307 | |
|
308 | 0 | std::set<std::string> oSetUsedSetFieldsUC; |
309 | |
|
310 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
311 | |
|
312 | 0 | const int nSrcGeomFieldCount = poSrcLayerDefn->GetGeomFieldCount(); |
313 | 0 | for (int i = 0; i < nSrcGeomFieldCount; ++i) |
314 | 0 | { |
315 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(i); |
316 | 0 | const auto oIter = oSetSelFieldsUC.find( |
317 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
318 | 0 | if (oIter != oSetSelFieldsUC.end()) |
319 | 0 | { |
320 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(i); |
321 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
322 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
323 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
324 | 0 | } |
325 | 0 | } |
326 | |
|
327 | 0 | const auto oIter = oSetSelFieldsUC.find( |
328 | 0 | CPLString(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME).toupper()); |
329 | 0 | if (m_poFeatureDefn->GetGeomFieldCount() == 0 && |
330 | 0 | oIter != oSetSelFieldsUC.end() && |
331 | 0 | poSrcLayerDefn->GetGeomFieldCount() == 1) |
332 | 0 | { |
333 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(0); |
334 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(0); |
335 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
336 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
337 | 0 | oSetUsedSetFieldsUC.insert(*oIter); |
338 | 0 | } |
339 | |
|
340 | 0 | if (oSetUsedSetFieldsUC.size() != oSetSelFields.size()) |
341 | 0 | { |
342 | 0 | for (const std::string &osName : oSetSelFields) |
343 | 0 | { |
344 | 0 | if (!cpl::contains(oSetUsedSetFieldsUC, |
345 | 0 | CPLString(osName).toupper())) |
346 | 0 | { |
347 | 0 | CPLError(bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, |
348 | 0 | "Field '%s' does not exist in layer '%s'.%s", |
349 | 0 | osName.c_str(), m_srcLayer.GetDescription(), |
350 | 0 | bStrict ? " You may specify " |
351 | 0 | "--ignore-missing-fields to skip it" |
352 | 0 | : " It will be ignored"); |
353 | 0 | if (bStrict) |
354 | 0 | return false; |
355 | 0 | } |
356 | 0 | } |
357 | 0 | } |
358 | | |
359 | 0 | return true; |
360 | 0 | } |
361 | | |
362 | | void ExcludeFieldsDeprecated(const std::vector<std::string> &fields) |
363 | 0 | { |
364 | 0 | std::set<std::string> oSetSelFields; |
365 | 0 | std::set<std::string> oSetSelFieldsUC; |
366 | 0 | for (const std::string &osFieldName : fields) |
367 | 0 | { |
368 | 0 | oSetSelFields.insert(osFieldName); |
369 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
370 | 0 | } |
371 | |
|
372 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
373 | 0 | for (const auto poSrcFieldDefn : poSrcLayerDefn->GetFields()) |
374 | 0 | { |
375 | 0 | const auto oIter = oSetSelFieldsUC.find( |
376 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
377 | 0 | if (oIter != oSetSelFieldsUC.end()) |
378 | 0 | { |
379 | 0 | m_anMapSrcFieldsToDstFields.push_back(-1); |
380 | 0 | } |
381 | 0 | else |
382 | 0 | { |
383 | 0 | m_anMapSrcFieldsToDstFields.push_back( |
384 | 0 | m_poFeatureDefn->GetFieldCount()); |
385 | 0 | OGRFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
386 | 0 | m_poFeatureDefn->AddFieldDefn(&oDstFieldDefn); |
387 | 0 | } |
388 | 0 | } |
389 | |
|
390 | 0 | if (oSetSelFieldsUC.find( |
391 | 0 | CPLString(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME).toupper()) != |
392 | 0 | oSetSelFieldsUC.end() && |
393 | 0 | poSrcLayerDefn->GetGeomFieldCount() == 1) |
394 | 0 | { |
395 | | // exclude default geometry field |
396 | 0 | } |
397 | 0 | else |
398 | 0 | { |
399 | 0 | const int nSrcGeomFieldCount = poSrcLayerDefn->GetGeomFieldCount(); |
400 | 0 | for (int i = 0; i < nSrcGeomFieldCount; ++i) |
401 | 0 | { |
402 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(i); |
403 | 0 | const auto oIter = oSetSelFieldsUC.find( |
404 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
405 | 0 | if (oIter == oSetSelFieldsUC.end()) |
406 | 0 | { |
407 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(i); |
408 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
409 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
410 | 0 | } |
411 | 0 | } |
412 | 0 | } |
413 | 0 | } |
414 | | |
415 | | void ExcludeAttributeFields(const std::vector<std::string> &fields) |
416 | 0 | { |
417 | 0 | std::set<std::string> oSetSelFields; |
418 | 0 | std::set<std::string> oSetSelFieldsUC; |
419 | 0 | for (const std::string &osFieldName : fields) |
420 | 0 | { |
421 | 0 | oSetSelFields.insert(osFieldName); |
422 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
423 | 0 | } |
424 | |
|
425 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
426 | 0 | for (const auto poSrcFieldDefn : poSrcLayerDefn->GetFields()) |
427 | 0 | { |
428 | 0 | const auto oIter = oSetSelFieldsUC.find( |
429 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
430 | 0 | if (oIter != oSetSelFieldsUC.end()) |
431 | 0 | { |
432 | 0 | m_anMapSrcFieldsToDstFields.push_back(-1); |
433 | 0 | } |
434 | 0 | else |
435 | 0 | { |
436 | 0 | m_anMapSrcFieldsToDstFields.push_back( |
437 | 0 | m_poFeatureDefn->GetFieldCount()); |
438 | 0 | OGRFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
439 | 0 | m_poFeatureDefn->AddFieldDefn(&oDstFieldDefn); |
440 | 0 | } |
441 | 0 | } |
442 | 0 | } |
443 | | |
444 | | void ExcludeGeometryFields(const std::vector<std::string> &fields) |
445 | 0 | { |
446 | 0 | std::set<std::string> oSetSelFields; |
447 | 0 | std::set<std::string> oSetSelFieldsUC; |
448 | 0 | for (const std::string &osFieldName : fields) |
449 | 0 | { |
450 | 0 | oSetSelFields.insert(osFieldName); |
451 | 0 | oSetSelFieldsUC.insert(CPLString(osFieldName).toupper()); |
452 | 0 | } |
453 | |
|
454 | 0 | const auto poSrcLayerDefn = m_srcLayer.GetLayerDefn(); |
455 | |
|
456 | 0 | if (oSetSelFieldsUC.find( |
457 | 0 | CPLString(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME).toupper()) != |
458 | 0 | oSetSelFieldsUC.end() && |
459 | 0 | poSrcLayerDefn->GetGeomFieldCount() == 1) |
460 | 0 | { |
461 | | // exclude default geometry field |
462 | 0 | } |
463 | 0 | else |
464 | 0 | { |
465 | 0 | const int nSrcGeomFieldCount = poSrcLayerDefn->GetGeomFieldCount(); |
466 | 0 | for (int i = 0; i < nSrcGeomFieldCount; ++i) |
467 | 0 | { |
468 | 0 | const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(i); |
469 | 0 | const auto oIter = oSetSelFieldsUC.find( |
470 | 0 | CPLString(poSrcFieldDefn->GetNameRef()).toupper()); |
471 | 0 | if (oIter == oSetSelFieldsUC.end()) |
472 | 0 | { |
473 | 0 | m_anMapDstGeomFieldsToSrcGeomFields.push_back(i); |
474 | 0 | OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn); |
475 | 0 | m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn); |
476 | 0 | } |
477 | 0 | } |
478 | 0 | } |
479 | 0 | } |
480 | | |
481 | | const OGRFeatureDefn *GetLayerDefn() const override |
482 | 0 | { |
483 | 0 | return m_poFeatureDefn.get(); |
484 | 0 | } |
485 | | |
486 | | GIntBig GetFeatureCount(int bForce) override |
487 | 0 | { |
488 | 0 | if (!m_poAttrQuery && !m_poFilterGeom) |
489 | 0 | return m_srcLayer.GetFeatureCount(bForce); |
490 | 0 | return OGRLayer::GetFeatureCount(bForce); |
491 | 0 | } |
492 | | |
493 | | OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, |
494 | | bool bForce) override |
495 | 0 | { |
496 | 0 | return m_srcLayer.GetExtent(iGeomField, psExtent, bForce); |
497 | 0 | } |
498 | | |
499 | | OGRFeature *GetFeature(GIntBig nFID) override |
500 | 0 | { |
501 | 0 | auto poSrcFeature = |
502 | 0 | std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID)); |
503 | 0 | if (!poSrcFeature) |
504 | 0 | return nullptr; |
505 | 0 | return TranslateFeature(std::move(poSrcFeature)).release(); |
506 | 0 | } |
507 | | |
508 | | bool TestCapability(const char *pszCap) const override |
509 | 0 | { |
510 | 0 | if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) || |
511 | 0 | EQUAL(pszCap, OLCMeasuredGeometries) || |
512 | 0 | EQUAL(pszCap, OLCZGeometries) || |
513 | 0 | (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery && |
514 | 0 | !m_poFilterGeom) || |
515 | 0 | EQUAL(pszCap, OLCFastGetExtent) || EQUAL(pszCap, OLCStringsAsUTF8)) |
516 | 0 | { |
517 | 0 | return m_srcLayer.TestCapability(pszCap); |
518 | 0 | } |
519 | 0 | return false; |
520 | 0 | } |
521 | | }; |
522 | | |
523 | | } // namespace |
524 | | |
525 | | /************************************************************************/ |
526 | | /* GDALVectorSelectAlgorithm::RunStep() */ |
527 | | /************************************************************************/ |
528 | | |
529 | | bool GDALVectorSelectAlgorithm::RunStep(GDALPipelineStepRunContext &) |
530 | 0 | { |
531 | 0 | auto poSrcDS = m_inputDataset[0].GetDatasetRef(); |
532 | 0 | CPLAssert(poSrcDS); |
533 | | |
534 | 0 | CPLAssert(m_outputDataset.GetName().empty()); |
535 | 0 | CPLAssert(!m_outputDataset.GetDatasetRef()); |
536 | | |
537 | 0 | auto outDS = std::make_unique<GDALVectorPipelineOutputDataset>(*poSrcDS); |
538 | |
|
539 | 0 | if (!m_fieldsDeprecated.empty()) |
540 | 0 | { |
541 | 0 | if (!m_fields.empty() || !m_geomFields.empty()) |
542 | 0 | { |
543 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
544 | 0 | "Deprecated --fields argument cannot be used together " |
545 | 0 | "with --field or --geometry-field"); |
546 | 0 | return false; |
547 | 0 | } |
548 | 0 | CPLErrorOnce(CE_Warning, CPLE_AppDefined, |
549 | 0 | "--fields is deprecated and will be removed in GDAL 3.15, " |
550 | 0 | "use --field and/or --geometry-field instead"); |
551 | |
|
552 | 0 | if (m_defaultGeom && |
553 | 0 | std::find(m_fieldsDeprecated.begin(), m_fieldsDeprecated.end(), |
554 | 0 | OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME) == |
555 | 0 | m_fieldsDeprecated.end()) |
556 | 0 | { |
557 | 0 | m_fieldsDeprecated.emplace_back( |
558 | 0 | OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME); |
559 | 0 | } |
560 | 0 | } |
561 | 0 | else |
562 | 0 | { |
563 | 0 | if (m_defaultGeom && std::find(m_geomFields.begin(), m_geomFields.end(), |
564 | 0 | OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME) == |
565 | 0 | m_geomFields.end()) |
566 | 0 | { |
567 | 0 | m_geomFields.emplace_back(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME); |
568 | 0 | } |
569 | 0 | } |
570 | | |
571 | 0 | if (m_fieldsDeprecated.empty() && m_fields.empty() && |
572 | 0 | m_geomFields.empty() && !m_defaultGeom) |
573 | 0 | { |
574 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
575 | 0 | "Must specify --field, --geometry-field and/or --geometry"); |
576 | 0 | return false; |
577 | 0 | } |
578 | | |
579 | 0 | for (auto &&poSrcLayer : poSrcDS->GetLayers()) |
580 | 0 | { |
581 | 0 | if (m_activeLayer.empty() || |
582 | 0 | m_activeLayer == poSrcLayer->GetDescription()) |
583 | 0 | { |
584 | 0 | auto poLayer = std::make_unique<GDALVectorSelectAlgorithmLayer>( |
585 | 0 | *poSrcLayer, m_outputLayerName); |
586 | 0 | if (m_exclude) |
587 | 0 | { |
588 | 0 | if (!m_fieldsDeprecated.empty()) |
589 | 0 | { |
590 | 0 | poLayer->ExcludeFieldsDeprecated(m_fieldsDeprecated); |
591 | 0 | } |
592 | 0 | else |
593 | 0 | { |
594 | 0 | poLayer->ExcludeAttributeFields(m_fields); |
595 | 0 | poLayer->ExcludeGeometryFields(m_geomFields); |
596 | 0 | } |
597 | 0 | } |
598 | 0 | else |
599 | 0 | { |
600 | 0 | if (!m_fieldsDeprecated.empty()) |
601 | 0 | { |
602 | 0 | if (!poLayer->IncludeFieldsDeprecated( |
603 | 0 | m_fieldsDeprecated, !m_ignoreMissingFields)) |
604 | 0 | return false; |
605 | 0 | } |
606 | 0 | else |
607 | 0 | { |
608 | 0 | if (!poLayer->IncludeAttributeFields( |
609 | 0 | m_fields, !m_ignoreMissingFields)) |
610 | 0 | return false; |
611 | 0 | if (!poLayer->IncludeGeometryFields(m_geomFields, |
612 | 0 | !m_ignoreMissingFields)) |
613 | 0 | return false; |
614 | 0 | } |
615 | 0 | } |
616 | 0 | outDS->AddLayer(*poSrcLayer, std::move(poLayer)); |
617 | 0 | } |
618 | 0 | else |
619 | 0 | { |
620 | 0 | outDS->AddLayer( |
621 | 0 | *poSrcLayer, |
622 | 0 | std::make_unique<GDALVectorPipelinePassthroughLayer>( |
623 | 0 | *poSrcLayer)); |
624 | 0 | } |
625 | 0 | } |
626 | | |
627 | 0 | m_outputDataset.Set(std::move(outDS)); |
628 | |
|
629 | 0 | return true; |
630 | 0 | } |
631 | | |
632 | 0 | GDALVectorSelectAlgorithmStandalone::~GDALVectorSelectAlgorithmStandalone() = |
633 | | default; |
634 | | |
635 | | //! @endcond |