Skip to content

Commit 8c1d084

Browse files
committed
Add 'gdal vector select' (extracting --fields functionality from 'gdal vector filter')
1 parent e7d1210 commit 8c1d084

15 files changed

+613
-349
lines changed

apps/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add_library(
3131
gdalalg_vector_read.cpp
3232
gdalalg_vector_filter.cpp
3333
gdalalg_vector_reproject.cpp
34+
gdalalg_vector_select.cpp
3435
gdalalg_vector_sql.cpp
3536
gdalalg_vector_write.cpp
3637
gdalinfo_lib.cpp

apps/gdalalg_vector.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "gdalalg_vector_pipeline.h"
1919
#include "gdalalg_vector_filter.h"
2020
#include "gdalalg_vector_reproject.h"
21+
#include "gdalalg_vector_select.h"
2122
#include "gdalalg_vector_sql.h"
2223

2324
/************************************************************************/
@@ -44,6 +45,7 @@ class GDALVectorAlgorithm final : public GDALAlgorithm
4445
RegisterSubAlgorithm<GDALVectorPipelineAlgorithm>();
4546
RegisterSubAlgorithm<GDALVectorFilterAlgorithmStandalone>();
4647
RegisterSubAlgorithm<GDALVectorReprojectAlgorithmStandalone>();
48+
RegisterSubAlgorithm<GDALVectorSelectAlgorithmStandalone>();
4749
RegisterSubAlgorithm<GDALVectorSQLAlgorithmStandalone>();
4850
}
4951

apps/gdalalg_vector_filter.cpp

+1-225
Original file line numberDiff line numberDiff line change
@@ -40,209 +40,8 @@ GDALVectorFilterAlgorithm::GDALVectorFilterAlgorithm(bool standaloneStep)
4040
.SetReadFromFileAtSyntaxAllowed()
4141
.SetMetaVar("<WHERE>|@<filename>")
4242
.SetRemoveSQLCommentsEnabled();
43-
AddArg("fields", 0, _("Selected fields"), &m_selectedFields);
4443
}
4544

46-
namespace
47-
{
48-
49-
/************************************************************************/
50-
/* GDALVectorFilterAlgorithmLayer */
51-
/************************************************************************/
52-
53-
class GDALVectorFilterAlgorithmLayer final
54-
: public OGRLayer,
55-
public OGRGetNextFeatureThroughRaw<GDALVectorFilterAlgorithmLayer>
56-
{
57-
private:
58-
bool m_bIsOK = true;
59-
OGRLayer *const m_poSrcLayer;
60-
OGRFeatureDefn *const m_poFeatureDefn = nullptr;
61-
std::vector<int> m_anMapSrcFieldsToDstFields{};
62-
std::vector<int> m_anMapDstGeomFieldsToSrcGeomFields{};
63-
64-
CPL_DISALLOW_COPY_ASSIGN(GDALVectorFilterAlgorithmLayer)
65-
66-
std::unique_ptr<OGRFeature> TranslateFeature(OGRFeature *poSrcFeature) const
67-
{
68-
auto poFeature = std::make_unique<OGRFeature>(m_poFeatureDefn);
69-
poFeature->SetFID(poSrcFeature->GetFID());
70-
const auto styleString = poSrcFeature->GetStyleString();
71-
if (styleString)
72-
poFeature->SetStyleString(styleString);
73-
poFeature->SetFieldsFrom(
74-
poSrcFeature, m_anMapSrcFieldsToDstFields.data(), false, false);
75-
int iDstGeomField = 0;
76-
for (int nSrcGeomField : m_anMapDstGeomFieldsToSrcGeomFields)
77-
{
78-
poFeature->SetGeomFieldDirectly(
79-
iDstGeomField, poSrcFeature->StealGeometry(nSrcGeomField));
80-
++iDstGeomField;
81-
}
82-
return poFeature;
83-
}
84-
85-
DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorFilterAlgorithmLayer)
86-
87-
public:
88-
GDALVectorFilterAlgorithmLayer(
89-
OGRLayer *poSrcLayer, const std::vector<std::string> &selectedFields,
90-
bool bStrict)
91-
: m_poSrcLayer(poSrcLayer),
92-
m_poFeatureDefn(new OGRFeatureDefn(poSrcLayer->GetName()))
93-
{
94-
SetDescription(poSrcLayer->GetDescription());
95-
m_poFeatureDefn->SetGeomType(wkbNone);
96-
m_poFeatureDefn->Reference();
97-
98-
std::set<std::string> oSetSelFields;
99-
std::set<std::string> oSetSelFieldsUC;
100-
for (const std::string &osFieldName : selectedFields)
101-
{
102-
oSetSelFields.insert(osFieldName);
103-
oSetSelFieldsUC.insert(CPLString(osFieldName).toupper());
104-
}
105-
106-
std::set<std::string> oSetUsedSetFieldsUC;
107-
108-
const auto poSrcLayerDefn = poSrcLayer->GetLayerDefn();
109-
for (int i = 0; i < poSrcLayerDefn->GetFieldCount(); ++i)
110-
{
111-
const auto poSrcFieldDefn = poSrcLayerDefn->GetFieldDefn(i);
112-
auto oIter = oSetSelFieldsUC.find(
113-
CPLString(poSrcFieldDefn->GetNameRef()).toupper());
114-
if (oIter != oSetSelFieldsUC.end())
115-
{
116-
m_anMapSrcFieldsToDstFields.push_back(
117-
m_poFeatureDefn->GetFieldCount());
118-
OGRFieldDefn oDstFieldDefn(*poSrcFieldDefn);
119-
m_poFeatureDefn->AddFieldDefn(&oDstFieldDefn);
120-
oSetUsedSetFieldsUC.insert(*oIter);
121-
}
122-
else
123-
{
124-
m_anMapSrcFieldsToDstFields.push_back(-1);
125-
}
126-
}
127-
128-
for (int i = 0; i < poSrcLayerDefn->GetGeomFieldCount(); ++i)
129-
{
130-
const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(i);
131-
auto oIter = oSetSelFieldsUC.find(
132-
CPLString(poSrcFieldDefn->GetNameRef()).toupper());
133-
if (oIter != oSetSelFieldsUC.end())
134-
{
135-
m_anMapDstGeomFieldsToSrcGeomFields.push_back(i);
136-
OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn);
137-
m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn);
138-
oSetUsedSetFieldsUC.insert(*oIter);
139-
}
140-
}
141-
142-
auto oIter = oSetSelFieldsUC.find(
143-
CPLString(OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME).toupper());
144-
if (m_poFeatureDefn->GetGeomFieldCount() == 0 &&
145-
oIter != oSetSelFieldsUC.end() &&
146-
poSrcLayerDefn->GetGeomFieldCount() == 1)
147-
{
148-
const auto poSrcFieldDefn = poSrcLayerDefn->GetGeomFieldDefn(0);
149-
m_anMapDstGeomFieldsToSrcGeomFields.push_back(0);
150-
OGRGeomFieldDefn oDstFieldDefn(*poSrcFieldDefn);
151-
m_poFeatureDefn->AddGeomFieldDefn(&oDstFieldDefn);
152-
oSetUsedSetFieldsUC.insert(*oIter);
153-
}
154-
155-
if (oSetUsedSetFieldsUC.size() != oSetSelFields.size())
156-
{
157-
for (const std::string &osName : oSetSelFields)
158-
{
159-
if (!cpl::contains(oSetUsedSetFieldsUC,
160-
CPLString(osName).toupper()))
161-
{
162-
CPLError(bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined,
163-
"Field '%s' does not exist in layer '%s'.%s",
164-
osName.c_str(), poSrcLayer->GetDescription(),
165-
bStrict ? "" : " It will be ignored");
166-
if (bStrict)
167-
m_bIsOK = false;
168-
}
169-
}
170-
}
171-
}
172-
173-
~GDALVectorFilterAlgorithmLayer() override
174-
{
175-
if (m_poFeatureDefn)
176-
m_poFeatureDefn->Dereference();
177-
}
178-
179-
bool IsOK() const
180-
{
181-
return m_bIsOK;
182-
}
183-
184-
OGRFeatureDefn *GetLayerDefn() override
185-
{
186-
return m_poFeatureDefn;
187-
}
188-
189-
GIntBig GetFeatureCount(int bForce) override
190-
{
191-
if (!m_poAttrQuery && !m_poFilterGeom)
192-
return m_poSrcLayer->GetFeatureCount(bForce);
193-
return OGRLayer::GetFeatureCount(bForce);
194-
}
195-
196-
OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
197-
{
198-
return m_poSrcLayer->GetExtent(psExtent, bForce);
199-
}
200-
201-
OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
202-
{
203-
return m_poSrcLayer->GetExtent(iGeomField, psExtent, bForce);
204-
}
205-
206-
void ResetReading() override
207-
{
208-
m_poSrcLayer->ResetReading();
209-
}
210-
211-
OGRFeature *GetNextRawFeature()
212-
{
213-
auto poSrcFeature =
214-
std::unique_ptr<OGRFeature>(m_poSrcLayer->GetNextFeature());
215-
if (!poSrcFeature)
216-
return nullptr;
217-
return TranslateFeature(poSrcFeature.get()).release();
218-
}
219-
220-
OGRFeature *GetFeature(GIntBig nFID) override
221-
{
222-
auto poSrcFeature =
223-
std::unique_ptr<OGRFeature>(m_poSrcLayer->GetFeature(nFID));
224-
if (!poSrcFeature)
225-
return nullptr;
226-
return TranslateFeature(poSrcFeature.get()).release();
227-
}
228-
229-
int TestCapability(const char *pszCap) override
230-
{
231-
if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) ||
232-
EQUAL(pszCap, OLCMeasuredGeometries) ||
233-
EQUAL(pszCap, OLCZGeometries) ||
234-
(EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery &&
235-
!m_poFilterGeom) ||
236-
EQUAL(pszCap, OLCFastGetExtent) || EQUAL(pszCap, OLCStringsAsUTF8))
237-
{
238-
return m_poSrcLayer->TestCapability(pszCap);
239-
}
240-
return false;
241-
}
242-
};
243-
244-
} // namespace
245-
24645
/************************************************************************/
24746
/* GDALVectorFilterAlgorithm::RunStep() */
24847
/************************************************************************/
@@ -284,30 +83,7 @@ bool GDALVectorFilterAlgorithm::RunStep(GDALProgressFunc, void *)
28483
}
28584
}
28685

287-
if (ret && !m_selectedFields.empty())
288-
{
289-
auto outDS = std::make_unique<GDALVectorPipelineOutputDataset>();
290-
outDS->SetDescription(poSrcDS->GetDescription());
291-
292-
for (int i = 0; i < nLayerCount; ++i)
293-
{
294-
auto poSrcLayer = poSrcDS->GetLayer(i);
295-
ret = ret && (poSrcLayer != nullptr);
296-
if (ret)
297-
{
298-
auto poLayer = std::make_unique<GDALVectorFilterAlgorithmLayer>(
299-
poSrcLayer, m_selectedFields, /* bStrict = */ true);
300-
ret = poLayer->IsOK();
301-
if (ret)
302-
{
303-
outDS->AddLayer(std::move(poLayer));
304-
}
305-
}
306-
}
307-
308-
m_outputDataset.Set(std::move(outDS));
309-
}
310-
else if (ret)
86+
if (ret)
31187
{
31288
m_outputDataset.Set(m_inputDataset.GetDatasetRef());
31389
}

apps/gdalalg_vector_filter.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ class GDALVectorFilterAlgorithm /* non final */
2727
public:
2828
static constexpr const char *NAME = "filter";
2929
static constexpr const char *DESCRIPTION = "Filter a vector dataset.";
30-
static constexpr const char *HELP_URL =
31-
"/programs/gdal_vector_pipeline.html";
30+
static constexpr const char *HELP_URL = "/programs/gdal_vector_filter.html";
3231

3332
static std::vector<std::string> GetAliases()
3433
{
@@ -42,7 +41,6 @@ class GDALVectorFilterAlgorithm /* non final */
4241

4342
std::vector<double> m_bbox{};
4443
std::string m_where{};
45-
std::vector<std::string> m_selectedFields{};
4644
};
4745

4846
/************************************************************************/

apps/gdalalg_vector_pipeline.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "gdalalg_vector_clip.h"
1616
#include "gdalalg_vector_filter.h"
1717
#include "gdalalg_vector_reproject.h"
18+
#include "gdalalg_vector_select.h"
1819
#include "gdalalg_vector_sql.h"
1920
#include "gdalalg_vector_write.h"
2021

@@ -193,6 +194,7 @@ GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()
193194
m_stepRegistry.Register<GDALVectorClipAlgorithm>();
194195
m_stepRegistry.Register<GDALVectorReprojectAlgorithm>();
195196
m_stepRegistry.Register<GDALVectorFilterAlgorithm>();
197+
m_stepRegistry.Register<GDALVectorSelectAlgorithm>();
196198
m_stepRegistry.Register<GDALVectorSQLAlgorithm>();
197199
}
198200

0 commit comments

Comments
 (0)