13#ifndef GDALALG_TEE_INCLUDED
14#define GDALALG_TEE_INCLUDED
16#include "gdalalg_abstract_pipeline.h"
17#include "gdalalg_raster_pipeline.h"
18#include "gdalalg_vector_pipeline.h"
33class GDALTeeStepAlgorithmAbstract
36 static constexpr const char *NAME =
"tee";
37 static constexpr const char *DESCRIPTION =
38 "Pipes the input into the output stream and side nested pipelines.";
39 static constexpr const char *HELP_URL =
"/programs/gdal_pipeline.html";
41 virtual ~GDALTeeStepAlgorithmAbstract();
43 void CopyFilenameBindingsFrom(
const GDALTeeStepAlgorithmAbstract *other);
45 bool BindFilename(
const std::string &filename,
46 GDALAbstractPipelineAlgorithm *alg,
47 const std::vector<std::string> &args);
49 bool HasOutputString()
const;
52 GDALTeeStepAlgorithmAbstract() =
default;
54 std::vector<GDALArgDatasetValue> m_pipelines{};
55 std::map<std::string, std::pair<GDALAbstractPipelineAlgorithm *,
56 std::vector<std::string>>>
64template <
class BaseStepAlgorithm,
int nDatasetType>
65class GDALTeeStepAlgorithmBase
66 :
public BaseStepAlgorithm,
67 public GDALTeeStepAlgorithmAbstract
70 bool IsNativelyStreamingCompatible()
const override
75 bool CanBeMiddleStep()
const override
80 bool CanBeLastStep()
const override
85 bool GeneratesFilesFromUserInput()
const override
90 bool HasOutputString()
const override
92 return GDALTeeStepAlgorithmAbstract::HasOutputString();
96 explicit GDALTeeStepAlgorithmBase();
98 int GetInputType()
const override
103 int GetOutputType()
const override
109 bool RunStep(GDALPipelineStepRunContext &ctxt)
override;
116template <
class BaseStepAlgorithm,
int nDatasetType>
117GDALTeeStepAlgorithmBase<BaseStepAlgorithm,
118 nDatasetType>::GDALTeeStepAlgorithmBase()
119 : BaseStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
120 GDALPipelineStepAlgorithm::ConstructorOptions()
121 .SetAddDefaultArguments(false))
123 this->AddInputDatasetArg(&this->m_inputDataset, 0,
true).SetHidden();
125 this->AddArg(
"tee-pipeline", 0, _(
"Nested pipeline"), &m_pipelines,
129 .SetMaxCount(INT_MAX)
130 .SetMetaVar(
"PIPELINE")
131 .SetPackedValuesAllowed(
false)
132 .SetDatasetInputFlags(GADV_NAME)
133 .SetDatasetOutputFlags(GADV_NAME)
134 .SetAutoOpenDataset(
false);
141template <
class BaseStepAlgorithm,
int nDatasetType>
142bool GDALTeeStepAlgorithmBase<BaseStepAlgorithm, nDatasetType>::RunStep(
143 GDALPipelineStepRunContext &ctxt)
145 auto pfnProgress = ctxt.m_pfnProgress;
146 auto pProgressData = ctxt.m_pProgressData;
148 auto poSrcDS = this->m_inputDataset[0].GetDatasetRef();
150 CPLAssert(this->m_outputDataset.GetName().empty());
151 CPLAssert(!this->m_outputDataset.GetDatasetRef());
154 std::vector<std::string> aosAttributeFilters;
155 std::vector<std::unique_ptr<OGRGeometry>> apoSpatialFilters;
156 for (
auto *poLayer : poSrcDS->GetLayers())
158 const char *pszQueryString = poLayer->GetAttrQueryString();
159 aosAttributeFilters.push_back(pszQueryString ? pszQueryString :
"");
160 const auto poSpatFilter = poLayer->GetSpatialFilter();
161 apoSpatialFilters.push_back(std::unique_ptr<OGRGeometry>(
162 poSpatFilter ? poSpatFilter->clone() : nullptr));
166 for (
const auto &dataset : m_pipelines)
168 const auto oIter = m_oMapNameToAlg.find(dataset.GetName());
169 if (oIter == m_oMapNameToAlg.end())
172 "'%s' is not a valid nested pipeline",
173 dataset.GetName().c_str());
176 auto subAlg = oIter->second.first;
177 const auto &subAlgArgs = oIter->second.second;
179 auto &subAlgInputDatasets = subAlg->GetInputDatasets();
181 subAlgInputDatasets.resize(1);
182 subAlgInputDatasets[0].Set(poSrcDS);
184 std::unique_ptr<void,
decltype(&GDALDestroyScaledProgress)>
186 GDALCreateScaledProgress(
187 double(iTeeDS) /
static_cast<int>(m_pipelines.size()),
188 double(iTeeDS + 1) /
static_cast<int>(m_pipelines.size()),
189 pfnProgress, pProgressData),
190 GDALDestroyScaledProgress);
192 if (this->IsCalledFromCommandLine())
193 subAlg->SetCalledFromCommandLine();
195 bool ret = (subAlg->ParseCommandLineArguments(subAlgArgs) &&
196 subAlg->Run(pScaledProgress ? GDALScaledProgress : nullptr,
197 pScaledProgress.get()) &&
200 this->m_output += subAlg->GetOutputString();
203 for (
int i = 0; i < static_cast<int>(aosAttributeFilters.size()); ++i)
205 auto poLayer = poSrcDS->GetLayer(i);
206 poLayer->SetAttributeFilter(aosAttributeFilters[i].empty()
207 ? aosAttributeFilters[i].c_str()
209 poLayer->SetSpatialFilter(apoSpatialFilters[i].get());
210 poLayer->ResetReading();
219 this->m_outputDataset.Set(poSrcDS);
227class GDALTeeRasterAlgorithm final
228 :
public GDALTeeStepAlgorithmBase<GDALRasterPipelineStepAlgorithm,
232 GDALTeeRasterAlgorithm() =
default;
234 ~GDALTeeRasterAlgorithm()
override;
241class GDALTeeVectorAlgorithm final
242 :
public GDALTeeStepAlgorithmBase<GDALVectorPipelineStepAlgorithm,
246 GDALTeeVectorAlgorithm() =
default;
248 ~GDALTeeVectorAlgorithm()
override;
#define CPLAssert(expr)
Assert on an expression.
Definition cpl_error.h:353
@ CE_Failure
Error that prevents the current operation to succeed.
Definition cpl_error.h:60
#define CPLE_AppDefined
Application defined error.
Definition cpl_error.h:108
Classes related to registration of format support, and opening datasets.