Skip to content

Commit

Permalink
Add "where" support for skipping points (#3177)
Browse files Browse the repository at this point in the history
* Initial commit with parser.

* Working parser.

* Move stuff around a bit.

* Hook up 'where' expression to filter argument.

* Prepare statements based on registered dimensions.

* Better separation of value/logical.

* Working where for standard mode.

* Streaming support for "where".

* Remove debug.
Accept stage names containing digits.

* Include header.

* Add header.

* What's up with Stage on windows?

* Remove dead code.

* Change "undefined" to be an explicitly deleted function.

* Add where-merge option.

* Add missed file.

* Move all skip processing to StageRunner.
Remove bad m_whereMerge from Filter.

* Add Where test.

* export operators on merge mode.

* Don't accept '/' in dimension names.
  • Loading branch information
abellgithub committed Jul 27, 2020
1 parent defc92b commit f6ed2d3
Show file tree
Hide file tree
Showing 22 changed files with 2,111 additions and 77 deletions.
435 changes: 435 additions & 0 deletions filters/private/expr/Expression.cpp

Large diffs are not rendered by default.

253 changes: 253 additions & 0 deletions filters/private/expr/Expression.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
#pragma once

#include <stack>
#include <string>
#include <memory>

#include <pdal/Dimension.hpp>
#include <pdal/PointLayout.hpp>
#include <pdal/PointRef.hpp>
#include <pdal/util/Utils.hpp>

namespace pdal
{
namespace expr
{

enum class NodeType
{
And,
Or,
Add,
Subtract,
Multiply,
Divide,
Not,
Equal,
NotEqual,
Greater,
GreaterEqual,
Less,
LessEqual,
Negative,
Value,
Identifier,
None
};

struct Result
{
Result(double d)
{ m_dval = d; m_bval = false; }

Result(bool b)
{ m_bval = b; m_dval = 0; }

enum class Type
{
Bool,
Val
};

double m_dval;
bool m_bval;
Type m_type;
};

class Node
{
protected:
Node(NodeType type);

public:
virtual ~Node();
NodeType type() const;

virtual std::string print() const = 0;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l) = 0;
virtual Result eval(PointRef& p) const = 0;
virtual bool isBool() const = 0;
virtual bool isValue() const
{ return !isBool(); }

private:
NodeType m_type;

protected:
size_t m_pos;
size_t m_level;
};
using NodePtr = std::unique_ptr<Node>;

class LogicalNode : public Node
{
public:
LogicalNode(NodeType type) : Node(type)
{}

virtual bool isBool() const
{ return true; }
};

class ValueNode : public Node
{
public:
ValueNode(NodeType type) : Node(type)
{}

virtual bool isBool() const
{ return false; }
};

class BinMathNode : public ValueNode
{
public:
BinMathNode(NodeType type, NodePtr left, NodePtr right);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
NodePtr m_left;
NodePtr m_right;
};

class UnMathNode : public ValueNode
{
public:
UnMathNode(NodeType type, NodePtr sub);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
NodePtr m_sub;
};

class NotNode : public LogicalNode
{
public:
NotNode(NodeType type, NodePtr sub);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
NodePtr m_sub;
};

class BoolNode : public LogicalNode
{
public:
BoolNode(NodeType type, NodePtr left, NodePtr right);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
NodePtr m_left;
NodePtr m_right;
};

class CompareNode : public LogicalNode
{
public:
CompareNode(NodeType type, NodePtr left, NodePtr right);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
NodePtr m_left;
NodePtr m_right;
};

class ConstValueNode : public ValueNode
{
public:
ConstValueNode(double d);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef&) const;

double value() const;

private:
double m_val;
};

class ConstLogicalNode : public LogicalNode
{
public:
ConstLogicalNode(bool b);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef&) const;

bool value() const;

private:
bool m_val;
};

class VarNode : public ValueNode
{
public:
VarNode(const std::string& s);

virtual std::string print() const;
virtual Utils::StatusWithReason prepare(PointLayoutPtr l);
virtual Result eval(PointRef& p) const;

private:
std::string m_name;
Dimension::Id m_id;
};

class Expression
{
public:
Expression();
Expression(const Expression& expr);
Expression& operator=(const Expression& expr);
~Expression();

void clear();
bool parse(const std::string& s);
std::string error() const;
std::string print() const;
NodePtr popNode();
void pushNode(NodePtr node);
Utils::StatusWithReason prepare(PointLayoutPtr layout);
bool eval(PointRef& p) const;

private:
std::string m_error;
std::stack<NodePtr> m_nodes;

friend std::ostream& operator<<(std::ostream& out, const Expression& expr);
};

} // namespace expr

namespace Utils
{

template<>
inline StatusWithReason fromString(const std::string& from,
pdal::expr::Expression& expr)
{
bool ok = expr.parse(from);
return { ok ? 0 : -1, expr.error() };
}

} // namespace Util

} // namespace pdal

0 comments on commit f6ed2d3

Please sign in to comment.