RFC104: add capability of 'filter' and 'reproject' vector pipeline steps to be standalone too
This commit is contained in:
parent
6544ad4ccd
commit
580958dfda
|
@ -15,6 +15,8 @@
|
|||
#include "gdalalg_vector_info.h"
|
||||
#include "gdalalg_vector_convert.h"
|
||||
#include "gdalalg_vector_pipeline.h"
|
||||
#include "gdalalg_vector_filter.h"
|
||||
#include "gdalalg_vector_reproject.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorAlgorithm */
|
||||
|
@ -37,6 +39,8 @@ class GDALVectorAlgorithm final : public GDALAlgorithm
|
|||
RegisterSubAlgorithm<GDALVectorInfoAlgorithm>();
|
||||
RegisterSubAlgorithm<GDALVectorConvertAlgorithm>();
|
||||
RegisterSubAlgorithm<GDALVectorPipelineAlgorithm>();
|
||||
RegisterSubAlgorithm<GDALVectorFilterAlgorithmStandalone>();
|
||||
RegisterSubAlgorithm<GDALVectorReprojectAlgorithmStandalone>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
/* GDALVectorFilterAlgorithm::GDALVectorFilterAlgorithm() */
|
||||
/************************************************************************/
|
||||
|
||||
GDALVectorFilterAlgorithm::GDALVectorFilterAlgorithm()
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL)
|
||||
GDALVectorFilterAlgorithm::GDALVectorFilterAlgorithm(bool standaloneStep)
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
|
||||
standaloneStep)
|
||||
{
|
||||
auto &arg =
|
||||
AddArg("bbox", 0, _("Bounding box as xmin,ymin,xmax,ymax"), &m_bbox)
|
||||
|
@ -51,10 +52,10 @@ GDALVectorFilterAlgorithm::GDALVectorFilterAlgorithm()
|
|||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorFilterAlgorithm::RunImpl() */
|
||||
/* GDALVectorFilterAlgorithm::RunStep() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorFilterAlgorithm::RunImpl(GDALProgressFunc, void *)
|
||||
bool GDALVectorFilterAlgorithm::RunStep(GDALProgressFunc, void *)
|
||||
{
|
||||
CPLAssert(m_inputDataset.GetDatasetRef());
|
||||
CPLAssert(m_outputDataset.GetName().empty());
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
/* GDALVectorFilterAlgorithm */
|
||||
/************************************************************************/
|
||||
|
||||
class GDALVectorFilterAlgorithm final : public GDALVectorPipelineStepAlgorithm
|
||||
class GDALVectorFilterAlgorithm /* non final */
|
||||
: public GDALVectorPipelineStepAlgorithm
|
||||
{
|
||||
public:
|
||||
static constexpr const char *NAME = "filter";
|
||||
static constexpr const char *DESCRIPTION = "Filter.";
|
||||
static constexpr const char *DESCRIPTION = "Filter a vector dataset.";
|
||||
static constexpr const char *HELP_URL = ""; // TODO
|
||||
|
||||
static std::vector<std::string> GetAliases()
|
||||
|
@ -33,14 +34,28 @@ class GDALVectorFilterAlgorithm final : public GDALVectorPipelineStepAlgorithm
|
|||
return {};
|
||||
}
|
||||
|
||||
GDALVectorFilterAlgorithm();
|
||||
explicit GDALVectorFilterAlgorithm(bool standaloneStep = false);
|
||||
|
||||
private:
|
||||
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
|
||||
std::vector<double> m_bbox{};
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorFilterAlgorithmStandalone */
|
||||
/************************************************************************/
|
||||
|
||||
class GDALVectorFilterAlgorithmStandalone final
|
||||
: public GDALVectorFilterAlgorithm
|
||||
{
|
||||
public:
|
||||
GDALVectorFilterAlgorithmStandalone()
|
||||
: GDALVectorFilterAlgorithm(/* standaloneStep = */ true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif /* GDALALG_VECTOR_FILTER_INCLUDED */
|
||||
|
|
|
@ -28,6 +28,24 @@
|
|||
#define _(x) (x)
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm() */
|
||||
/************************************************************************/
|
||||
|
||||
GDALVectorPipelineStepAlgorithm::GDALVectorPipelineStepAlgorithm(
|
||||
const std::string &name, const std::string &description,
|
||||
const std::string &helpURL, bool standaloneStep)
|
||||
: GDALAlgorithm(name, description, helpURL),
|
||||
m_standaloneStep(standaloneStep)
|
||||
{
|
||||
if (m_standaloneStep)
|
||||
{
|
||||
AddInputArgs(false);
|
||||
AddProgressArg();
|
||||
AddOutputArgs(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorPipelineStepAlgorithm::AddInputArgs() */
|
||||
/************************************************************************/
|
||||
|
@ -81,12 +99,69 @@ void GDALVectorPipelineStepAlgorithm::AddOutputArgs(
|
|||
.SetHiddenForCLI(hiddenForCLI);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorPipelineStepAlgorithm::RunImpl() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorPipelineStepAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
|
||||
void *pProgressData)
|
||||
{
|
||||
if (m_standaloneStep)
|
||||
{
|
||||
GDALVectorReadAlgorithm readAlg;
|
||||
for (auto &arg : readAlg.GetArgs())
|
||||
{
|
||||
auto stepArg = GetArg(arg->GetName());
|
||||
if (stepArg && stepArg->IsExplicitlySet())
|
||||
{
|
||||
arg->SetSkipIfAlreadySet(true);
|
||||
arg->SetFrom(*stepArg);
|
||||
}
|
||||
}
|
||||
|
||||
GDALVectorWriteAlgorithm writeAlg;
|
||||
for (auto &arg : writeAlg.GetArgs())
|
||||
{
|
||||
auto stepArg = GetArg(arg->GetName());
|
||||
if (stepArg && stepArg->IsExplicitlySet())
|
||||
{
|
||||
arg->SetSkipIfAlreadySet(true);
|
||||
arg->SetFrom(*stepArg);
|
||||
}
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
if (readAlg.Run())
|
||||
{
|
||||
m_inputDataset.Set(readAlg.m_outputDataset.GetDatasetRef());
|
||||
m_outputDataset.Set(nullptr);
|
||||
if (RunStep(nullptr, nullptr))
|
||||
{
|
||||
writeAlg.m_inputDataset.Set(m_outputDataset.GetDatasetRef());
|
||||
if (writeAlg.Run(pfnProgress, pProgressData))
|
||||
{
|
||||
m_outputDataset.Set(
|
||||
writeAlg.m_outputDataset.GetDatasetRef());
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RunStep(pfnProgress, pProgressData);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm() */
|
||||
/************************************************************************/
|
||||
|
||||
GDALVectorPipelineAlgorithm::GDALVectorPipelineAlgorithm()
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL)
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
|
||||
/*standaloneStep=*/false)
|
||||
{
|
||||
AddInputArgs(/* hiddenForCLI = */ true);
|
||||
AddProgressArg();
|
||||
|
@ -369,10 +444,10 @@ bool GDALVectorPipelineAlgorithm::ParseCommandLineArguments(
|
|||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorPipelineAlgorithm::RunImpl() */
|
||||
/* GDALVectorPipelineAlgorithm::RunStep() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorPipelineAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
|
||||
bool GDALVectorPipelineAlgorithm::RunStep(GDALProgressFunc pfnProgress,
|
||||
void *pProgressData)
|
||||
{
|
||||
if (m_steps.empty())
|
||||
|
|
|
@ -26,16 +26,18 @@ class GDALVectorPipelineStepAlgorithm /* non final */ : public GDALAlgorithm
|
|||
protected:
|
||||
GDALVectorPipelineStepAlgorithm(const std::string &name,
|
||||
const std::string &description,
|
||||
const std::string &helpURL)
|
||||
: GDALAlgorithm(name, description, helpURL)
|
||||
{
|
||||
}
|
||||
const std::string &helpURL,
|
||||
bool standaloneStep);
|
||||
|
||||
friend class GDALVectorPipelineAlgorithm;
|
||||
|
||||
virtual bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) = 0;
|
||||
|
||||
void AddInputArgs(bool hiddenForCLI);
|
||||
void AddOutputArgs(bool hiddenForCLI, bool shortNameOutputLayerAllowed);
|
||||
|
||||
bool m_standaloneStep = false;
|
||||
|
||||
// Input arguments
|
||||
GDALArgDatasetValue m_inputDataset{};
|
||||
std::vector<std::string> m_openOptions{};
|
||||
|
@ -52,6 +54,9 @@ class GDALVectorPipelineStepAlgorithm /* non final */ : public GDALAlgorithm
|
|||
bool m_overwriteLayer = false;
|
||||
bool m_appendLayer = false;
|
||||
std::string m_outputLayerName{};
|
||||
|
||||
private:
|
||||
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -102,7 +107,7 @@ class GDALVectorPipelineAlgorithm final : public GDALVectorPipelineStepAlgorithm
|
|||
private:
|
||||
std::string m_pipeline{};
|
||||
|
||||
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
|
||||
std::unique_ptr<GDALVectorPipelineStepAlgorithm>
|
||||
GetStepAlg(const std::string &name) const;
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
/************************************************************************/
|
||||
|
||||
GDALVectorReadAlgorithm::GDALVectorReadAlgorithm()
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL)
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
|
||||
/* standaloneStep =*/false)
|
||||
{
|
||||
AddInputArgs(/* hiddenForCLI = */ false);
|
||||
}
|
||||
|
@ -62,10 +63,10 @@ class GDALVectorReadAlgorithmDataset final : public GDALDataset
|
|||
} // namespace
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorReadAlgorithm::RunImpl() */
|
||||
/* GDALVectorReadAlgorithm::RunStep() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorReadAlgorithm::RunImpl(GDALProgressFunc, void *)
|
||||
bool GDALVectorReadAlgorithm::RunStep(GDALProgressFunc, void *)
|
||||
{
|
||||
CPLAssert(m_inputDataset.GetDatasetRef());
|
||||
CPLAssert(m_outputDataset.GetName().empty());
|
||||
|
|
|
@ -36,7 +36,7 @@ class GDALVectorReadAlgorithm final : public GDALVectorPipelineStepAlgorithm
|
|||
GDALVectorReadAlgorithm();
|
||||
|
||||
private:
|
||||
bool RunImpl(GDALProgressFunc, void *) override;
|
||||
bool RunStep(GDALProgressFunc, void *) override;
|
||||
};
|
||||
|
||||
//! @endcond
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
/* GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm() */
|
||||
/************************************************************************/
|
||||
|
||||
GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm()
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL)
|
||||
GDALVectorReprojectAlgorithm::GDALVectorReprojectAlgorithm(bool standaloneStep)
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
|
||||
standaloneStep)
|
||||
{
|
||||
AddArg("src-crs", 's', _("Source CRS"), &m_srsCrs).AddHiddenAlias("s_srs");
|
||||
AddArg("dst-crs", 'd', _("Destination CRS"), &m_dstCrs)
|
||||
|
@ -68,10 +69,10 @@ class GDALVectorReprojectAlgorithmDataset final : public GDALDataset
|
|||
} // namespace
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorReprojectAlgorithm::RunImpl() */
|
||||
/* GDALVectorReprojectAlgorithm::RunStep() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorReprojectAlgorithm::RunImpl(GDALProgressFunc, void *)
|
||||
bool GDALVectorReprojectAlgorithm::RunStep(GDALProgressFunc, void *)
|
||||
{
|
||||
CPLAssert(m_inputDataset.GetDatasetRef());
|
||||
CPLAssert(m_outputDataset.GetName().empty());
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
/* GDALVectorReprojectAlgorithm */
|
||||
/************************************************************************/
|
||||
|
||||
class GDALVectorReprojectAlgorithm final
|
||||
class GDALVectorReprojectAlgorithm /* non final */
|
||||
: public GDALVectorPipelineStepAlgorithm
|
||||
{
|
||||
public:
|
||||
static constexpr const char *NAME = "reproject";
|
||||
static constexpr const char *DESCRIPTION = "Reproject.";
|
||||
static constexpr const char *DESCRIPTION = "Reproject a vector dataset.";
|
||||
static constexpr const char *HELP_URL = ""; // TODO
|
||||
|
||||
static std::vector<std::string> GetAliases()
|
||||
|
@ -34,15 +34,29 @@ class GDALVectorReprojectAlgorithm final
|
|||
return {};
|
||||
}
|
||||
|
||||
GDALVectorReprojectAlgorithm();
|
||||
explicit GDALVectorReprojectAlgorithm(bool standaloneStep = false);
|
||||
|
||||
private:
|
||||
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
|
||||
std::string m_srsCrs{};
|
||||
std::string m_dstCrs{};
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorReprojectAlgorithmStandalone */
|
||||
/************************************************************************/
|
||||
|
||||
class GDALVectorReprojectAlgorithmStandalone final
|
||||
: public GDALVectorReprojectAlgorithm
|
||||
{
|
||||
public:
|
||||
GDALVectorReprojectAlgorithmStandalone()
|
||||
: GDALVectorReprojectAlgorithm(/* standaloneStep = */ true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif /* GDALALG_VECTOR_REPROJECT_INCLUDED */
|
||||
|
|
|
@ -27,17 +27,18 @@
|
|||
/************************************************************************/
|
||||
|
||||
GDALVectorWriteAlgorithm::GDALVectorWriteAlgorithm()
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL)
|
||||
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
|
||||
/* standaloneStep =*/false)
|
||||
{
|
||||
AddOutputArgs(/* hiddenForCLI = */ false,
|
||||
/* shortNameOutputLayerAllowed=*/true);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* GDALVectorWriteAlgorithm::RunImpl() */
|
||||
/* GDALVectorWriteAlgorithm::RunStep() */
|
||||
/************************************************************************/
|
||||
|
||||
bool GDALVectorWriteAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
|
||||
bool GDALVectorWriteAlgorithm::RunStep(GDALProgressFunc pfnProgress,
|
||||
void *pProgressData)
|
||||
{
|
||||
CPLAssert(m_inputDataset.GetDatasetRef());
|
||||
|
|
|
@ -36,7 +36,7 @@ class GDALVectorWriteAlgorithm final : public GDALVectorPipelineStepAlgorithm
|
|||
GDALVectorWriteAlgorithm();
|
||||
|
||||
private:
|
||||
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) override;
|
||||
};
|
||||
|
||||
//! @endcond
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env pytest
|
||||
# -*- coding: utf-8 -*-
|
||||
###############################################################################
|
||||
# Project: GDAL/OGR Test Suite
|
||||
# Purpose: 'gdal vector filter' testing
|
||||
# Author: Even Rouault <even dot rouault @ spatialys.com>
|
||||
#
|
||||
###############################################################################
|
||||
# Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
###############################################################################
|
||||
|
||||
from osgeo import gdal
|
||||
|
||||
|
||||
def get_filter_alg():
|
||||
reg = gdal.GetGlobalAlgorithmRegistry()
|
||||
vector = reg.InstantiateAlg("vector")
|
||||
return vector.InstantiateSubAlgorithm("filter")
|
||||
|
||||
|
||||
def test_gdalalg_vector_filter_no_filter(tmp_vsimem):
|
||||
|
||||
out_filename = str(tmp_vsimem / "out.shp")
|
||||
|
||||
filter_alg = get_filter_alg()
|
||||
assert filter_alg.ParseCommandLineArguments(["../ogr/data/poly.shp", out_filename])
|
||||
assert filter_alg.Run()
|
||||
ds = filter_alg.GetArg("output").Get().GetDataset()
|
||||
assert ds.GetLayer(0).GetFeatureCount() == 10
|
||||
assert filter_alg.Finalize()
|
||||
ds = None
|
||||
|
||||
with gdal.OpenEx(out_filename) as ds:
|
||||
assert ds.GetLayer(0).GetFeatureCount() == 10
|
||||
|
||||
|
||||
def test_gdalalg_vector_filter_base(tmp_vsimem):
|
||||
|
||||
out_filename = str(tmp_vsimem / "out.shp")
|
||||
|
||||
filter_alg = get_filter_alg()
|
||||
assert filter_alg.ParseRunAndFinalize(
|
||||
["--bbox=479867,4762909,479868,4762910", "../ogr/data/poly.shp", out_filename]
|
||||
)
|
||||
|
||||
with gdal.OpenEx(out_filename) as ds:
|
||||
assert ds.GetLayer(0).GetFeatureCount() == 1
|
Loading…
Reference in New Issue