Skip to content

Commit

Permalink
Add where-merge option.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Jul 20, 2020
1 parent bfb88df commit a9abb36
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 29 deletions.
12 changes: 12 additions & 0 deletions pdal/Filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct Filter::Args
{
expr::Expression m_where;
Arg *m_whereArg;
Stage::WhereMergeMode m_whereMerge;
Arg *m_whereMergeArg;
};

Filter::Filter() : m_args(new Args)
Expand Down Expand Up @@ -69,6 +71,9 @@ void Filter::l_addArgs(ProgramArgs& args)
m_args->m_whereArg = &args.add("where",
"Expression describing points to be passed to this "
"filter", m_args->m_where);
m_args->m_whereMergeArg = &args.add("where_merge", "If 'where' option is set, describes "
"how skipped points should be merged with kept points in standard mode.",
m_whereMerge, WhereMergeMode::Auto);
}

void Filter::l_prepared(PointTableRef table)
Expand All @@ -77,6 +82,8 @@ void Filter::l_prepared(PointTableRef table)
auto status = m_args->m_where.prepare(table.layout());
if (!status)
throwError("Invalid 'where': " + status.what());
if (m_args->m_whereMergeArg->set() && !m_args->m_whereArg->set())
throwError("Can't set 'where_merge' options without also setting 'where' option.");
}

void Filter::l_prerun(const PointViewSet& views, PointViewSet& keeps,
Expand All @@ -103,6 +110,11 @@ void Filter::l_prerun(const PointViewSet& views, PointViewSet& keeps,
keeps = std::move(views);
}

Stage::WhereMergeMode Filter::mergeMode() const
{
return m_args->m_whereMerge;
}

bool Filter::eval(PointRef& p) const
{
if (!m_args->m_whereArg->set())
Expand Down
2 changes: 2 additions & 0 deletions pdal/Filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ class PDAL_DLL Filter : public virtual Stage
virtual void l_initialize(PointTableRef table) final;
virtual void l_addArgs(ProgramArgs& args) final;
virtual void l_prepared(PointTableRef table) final;
virtual WhereMergeMode mergeMode() const;
virtual PointViewSet run(PointViewPtr view);
virtual void filter(PointView& /*view*/)
{}

std::unique_ptr<Args> m_args;
Stage::WhereMergeMode m_whereMerge;
};

} // namespace pdal
Expand Down
81 changes: 65 additions & 16 deletions pdal/Stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,17 +247,7 @@ PointViewSet Stage::execute(PointTableRef table, PointViewSet& views)
for (auto it = views.rbegin(); it != views.rend(); it++)
table.addSpatialReference((*it)->spatialReference());

// Count the number of views and the number of points and faces so they're
// available to stages.
m_pointCount = 0;
m_faceCount = 0;
for (auto const& it : views)
{
m_pointCount += it->size();
auto m = it->mesh();
if (m)
m_faceCount += m->size();
}
countElements(views);

// Do the ready operation and then start running all the views
// through the stage.
Expand All @@ -268,11 +258,19 @@ PointViewSet Stage::execute(PointTableRef table, PointViewSet& views)
l_prerun(views, keeps, skips);
prerun(keeps);

for (auto const& it : keeps)
// Note that keeps and skips should be paired in order because of the
// way the key is generated.
auto ki = keeps.begin();
auto si = skips.begin();
for (; ki != keeps.end(); ++ki)
{
StageRunnerPtr runner(new StageRunner(this, it));
PointViewPtr k = *ki;
PointViewPtr s = ((si != skips.end()) ? *si : PointViewPtr());
StageRunnerPtr runner(new StageRunner(this, k, s));
runners.push_back(runner);
runner->run();
if (si != skips.end())
si++;
}

// As the stages complete (synchronously at this time), propagate the
Expand All @@ -291,16 +289,27 @@ PointViewSet Stage::execute(PointTableRef table, PointViewSet& views)
outViews.insert(temp.begin(), temp.end());
}

// Add skipped views back into the list of views.
outViews.insert(skips.begin(), skips.end());

done(table);
stopLogging();
m_pointCount = 0;
m_faceCount = 0;
return outViews;
}

void Stage::countElements(const PointViewSet& views)
{
// Count the number of views and the number of points and faces so they're
// available to stages.
m_pointCount = 0;
m_faceCount = 0;
for (auto const& v : views)
{
m_pointCount += v->size();
auto m = v->mesh();
if (m)
m_faceCount += m->size();
}
}

void Stage::setupLog()
{
Expand Down Expand Up @@ -418,5 +427,45 @@ void Stage::stopLogging() const
m_log->popLeader();
}

Stage::WhereMergeMode Stage::mergeMode() const
{
return WhereMergeMode::Auto;
}

std::istream& operator>>(std::istream& in, Stage::WhereMergeMode& mode)
{
std::string s;
in >> s;

s = Utils::tolower(s);
if (s == "auto")
mode = Stage::WhereMergeMode::Auto;
else if (s == "true")
mode = Stage::WhereMergeMode::True;
else if (s == "false")
mode = Stage::WhereMergeMode::False;
else
in.setstate(std::ios_base::failbit);
return in;
}

std::ostream& operator<<(std::ostream& out, const Stage::WhereMergeMode& mode)
{
switch (mode)
{
case Stage::WhereMergeMode::Auto:
out << "auto";
break;
case Stage::WhereMergeMode::True:
out << "true";
break;
case Stage::WhereMergeMode::False:
out << "false";
break;
}

return out;
}

} // namespace pdal

13 changes: 13 additions & 0 deletions pdal/Stage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ class PDAL_DLL Stage
friend class Reader;
friend class Filter;
friend class Writer;
public:
enum class WhereMergeMode
{
True,
False,
Auto
};

public:
Stage();
virtual ~Stage();
Expand Down Expand Up @@ -372,10 +380,12 @@ class PDAL_DLL Stage

void setupLog();
void handleOptions();
void countElements(const PointViewSet& views);

virtual void l_addArgs(ProgramArgs& args);
virtual void l_initialize(PointTableRef table);
virtual void l_prepared(PointTableRef table);
virtual WhereMergeMode mergeMode() const;

/**
Get basic metadata (avoids reading points). Implement in subclass.
Expand Down Expand Up @@ -494,6 +504,9 @@ class PDAL_DLL Stage
*/
const Options& getOptions() const
{ return m_options; }

friend std::istream& operator>>(std::istream& in, Stage::WhereMergeMode& mode);
friend std::ostream& operator<<(std::ostream& out, const Stage::WhereMergeMode& mode);
};

} // namespace pdal
21 changes: 8 additions & 13 deletions pdal/private/StageRunner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,25 @@

#pragma once

#include <memory>

#include <pdal/Stage.hpp>
#include <pdal/PointView.hpp>

namespace pdal
{

class Stage;

class StageRunner
{
public:
StageRunner(Stage *s, PointViewPtr view) :
m_stage(s), m_view(view)
{}

// For now this is all synchronous
void run()
{ m_viewSet = m_stage->run(m_view); }
StageRunner(Stage *s, PointViewPtr keeps, PointViewPtr skips);

PointViewSet wait()
{ return m_viewSet; }
void run();
PointViewSet wait();

private:
Stage *m_stage;
PointViewPtr m_view;
PointViewPtr m_keep;
PointViewPtr m_skip;
PointViewSet m_viewSet;
};
typedef std::shared_ptr<StageRunner> StageRunnerPtr;
Expand Down

0 comments on commit a9abb36

Please sign in to comment.