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