@@ -31,6 +31,9 @@ GDALVectorCheckGeometryAlgorithm::GDALVectorCheckGeometryAlgorithm(
3131 : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
3232 standaloneStep)
3333{
34+ AddArg (" include-field" , 0 ,
35+ _ (" Fields from input layer to include in output" ), &m_includeFields);
36+
3437 AddArg (" include-valid" , 0 ,
3538 _ (" Include valid inputs in output, with empty geometry" ),
3639 &m_includeValid);
@@ -47,8 +50,10 @@ class GDALInvalidLocationLayer final : public GDALVectorPipelineOutputLayer
4750 static constexpr const char *ERROR_DESCRIPTION_FIELD = " error" ;
4851
4952 public:
50- GDALInvalidLocationLayer (OGRLayer &layer, bool bSingleLayerOutput,
51- int srcGeomField, bool skipValid)
53+ GDALInvalidLocationLayer (OGRLayer &layer,
54+ const std::vector<int > &srcFieldIndices,
55+ bool bSingleLayerOutput, int srcGeomField,
56+ bool skipValid)
5257 : GDALVectorPipelineOutputLayer(layer),
5358 m_defn (OGRFeatureDefn::CreateFeatureDefn(
5459 bSingleLayerOutput ? " error_location"
@@ -60,6 +65,18 @@ class GDALInvalidLocationLayer final : public GDALVectorPipelineOutputLayer
6065 {
6166 m_defn->Reference ();
6267
68+ if (!srcFieldIndices.empty ())
69+ {
70+ const OGRFeatureDefn &srcDefn = *layer.GetLayerDefn ();
71+ m_srcFieldMap.resize (srcDefn.GetFieldCount (), -1 );
72+ int iDstField = 0 ;
73+ for (int iSrcField : srcFieldIndices)
74+ {
75+ m_defn->AddFieldDefn (srcDefn.GetFieldDefn (iSrcField));
76+ m_srcFieldMap[iSrcField] = iDstField++;
77+ }
78+ }
79+
6380 auto poDescriptionFieldDefn =
6481 std::make_unique<OGRFieldDefn>(ERROR_DESCRIPTION_FIELD, OFTString);
6582 m_defn->AddFieldDefn (std::move (poDescriptionFieldDefn));
@@ -82,7 +99,7 @@ class GDALInvalidLocationLayer final : public GDALVectorPipelineOutputLayer
8299 return m_defn;
83100 }
84101
85- std::unique_ptr<OGRFeature> CreateFeatureFromLastError ()
102+ std::unique_ptr<OGRFeature> CreateFeatureFromLastError () const
86103 {
87104 auto poErrorFeature = std::make_unique<OGRFeature>(m_defn);
88105
@@ -244,6 +261,11 @@ class GDALInvalidLocationLayer final : public GDALVectorPipelineOutputLayer
244261
245262 if (poErrorFeature)
246263 {
264+ if (!m_srcFieldMap.empty ())
265+ {
266+ poErrorFeature->SetFieldsFrom (
267+ poSrcFeature.get (), m_srcFieldMap.data (), false , false );
268+ }
247269 poErrorFeature->SetFID (poSrcFeature->GetFID ());
248270 apoOutputFeatures.push_back (std::move (poErrorFeature));
249271 }
@@ -252,6 +274,7 @@ class GDALInvalidLocationLayer final : public GDALVectorPipelineOutputLayer
252274 CPL_DISALLOW_COPY_ASSIGN (GDALInvalidLocationLayer)
253275
254276 private:
277+ std::vector<int> m_srcFieldMap{};
255278 OGRFeatureDefn *const m_defn;
256279 const GEOSContextHandle_t m_geosContext;
257280 const int m_srcGeomField;
@@ -310,9 +333,26 @@ bool GDALVectorCheckGeometryAlgorithm::RunStep(GDALPipelineStepRunContext &)
310333 return false ;
311334 }
312335
336+ std::vector<int > includeFieldIndices;
337+ for (const auto &fieldName : m_includeFields)
338+ {
339+ auto iSrcField =
340+ poSrcLayerDefn->GetFieldIndex (fieldName.c_str ());
341+ if (iSrcField == -1 )
342+ {
343+ ReportError (
344+ CE_Failure, CPLE_AppDefined,
345+ " Specified field '%s' does not exist in layer '%s'" ,
346+ fieldName.c_str (), poSrcLayer->GetDescription ());
347+ return false ;
348+ }
349+ includeFieldIndices.push_back (iSrcField);
350+ }
351+
313352 outDS->AddLayer (*poSrcLayer,
314353 std::make_unique<GDALInvalidLocationLayer>(
315- *poSrcLayer, bSingleLayerOutput, geomFieldIndex,
354+ *poSrcLayer, includeFieldIndices,
355+ bSingleLayerOutput, geomFieldIndex,
316356 !m_includeValid));
317357 }
318358 }
0 commit comments