Coverage Report

Created: 2026-09-14 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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