Skip to content

Commit

Permalink
Allow negation of ranges.
Browse files Browse the repository at this point in the history
Close #1001
  • Loading branch information
abellgithub committed Oct 21, 2015
1 parent dddc40a commit 37cce0c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
7 changes: 7 additions & 0 deletions doc/stages/filters.range.rst
Expand Up @@ -78,3 +78,10 @@ limits
.. code-block:: bash
Classification[2:2]
Any range can be negated by prefacing with the '~' character. The following
will select all classifications that aren't equal to the value 2.
.. code-block:: bash
Classification~[2:2]
12 changes: 10 additions & 2 deletions filters/range/RangeFilter.cpp
Expand Up @@ -64,6 +64,7 @@ RangeFilter::Range parseRange(const std::string& r)
std::string::size_type pos, count;
bool ilb = true;
bool iub = true;
bool negate = false;
const char *start;
char *end;
std::string name;
Expand All @@ -82,6 +83,12 @@ RangeFilter::Range parseRange(const std::string& r)
name = r.substr(pos, count);
pos += count;

if (r[pos] == '~')
{
negate = true;
pos++;
}

if (r[pos] == '(')
ilb = false;
else if (r[pos] != '[')
Expand Down Expand Up @@ -129,7 +136,7 @@ RangeFilter::Range parseRange(const std::string& r)
oss << "filters.range: invalid 'limits' option: '" << r << "': " << s;
throw pdal_error(oss.str());
}
return RangeFilter::Range(name, lb, ub, ilb, iub);
return RangeFilter::Range(name, lb, ub, ilb, iub, negate);
}

}
Expand Down Expand Up @@ -199,7 +206,8 @@ PointViewSet RangeFilter::run(PointViewPtr inView)
if (v >= d.second.m_upper_bound)
keep_point = false;
}

if (d.second.m_negate)
keep_point = !keep_point;
if (keep_point)
break;
}
Expand Down
7 changes: 5 additions & 2 deletions filters/range/RangeFilter.hpp
Expand Up @@ -58,11 +58,13 @@ class PDAL_DLL RangeFilter : public pdal::Filter
double lower_bound,
double upper_bound,
bool inclusive_lower_bound,
bool inclusive_upper_bound) :
bool inclusive_upper_bound,
bool negate) :
m_name(name), m_lower_bound(lower_bound),
m_upper_bound(upper_bound),
m_inclusive_lower_bound(inclusive_lower_bound),
m_inclusive_upper_bound(inclusive_upper_bound)
m_inclusive_upper_bound(inclusive_upper_bound),
m_negate(negate)
{}

Range()
Expand All @@ -73,6 +75,7 @@ class PDAL_DLL RangeFilter : public pdal::Filter
double m_upper_bound;
bool m_inclusive_lower_bound;
bool m_inclusive_upper_bound;
bool m_negate;
};

RangeFilter() : Filter()
Expand Down
35 changes: 35 additions & 0 deletions test/unit/filters/RangeFilterTest.cpp
Expand Up @@ -189,6 +189,41 @@ TEST(RangeFilterTest, onlyMax)
EXPECT_FLOAT_EQ(5.0, view->getFieldAs<double>(Dimension::Id::Z, 4));
}

TEST(RangeFilterTest, negation)
{
BOX3D srcBounds(0.0, 0.0, 1.0, 0.0, 0.0, 10.0);

Options ops;
ops.add("bounds", srcBounds);
ops.add("mode", "ramp");
ops.add("num_points", 10);

StageFactory f;
FauxReader reader;
reader.setOptions(ops);

Options rangeOps;
rangeOps.add("limits", "Z~[2:5]");

RangeFilter filter;
filter.setOptions(rangeOps);
filter.setInput(reader);

PointTable table;
filter.prepare(table);
PointViewSet viewSet = filter.execute(table);
PointViewPtr view = *viewSet.begin();

EXPECT_EQ(1u, viewSet.size());
EXPECT_EQ(6u, view->size());
EXPECT_FLOAT_EQ(1.0, view->getFieldAs<double>(Dimension::Id::Z, 0));
EXPECT_FLOAT_EQ(6.0, view->getFieldAs<double>(Dimension::Id::Z, 1));
EXPECT_FLOAT_EQ(7.0, view->getFieldAs<double>(Dimension::Id::Z, 2));
EXPECT_FLOAT_EQ(8.0, view->getFieldAs<double>(Dimension::Id::Z, 3));
EXPECT_FLOAT_EQ(9.0, view->getFieldAs<double>(Dimension::Id::Z, 4));
EXPECT_FLOAT_EQ(10.0, view->getFieldAs<double>(Dimension::Id::Z, 5));
}

TEST(RangeFilterTest, equals)
{
BOX3D srcBounds(0.0, 0.0, 1.0, 0.0, 0.0, 10.0);
Expand Down

0 comments on commit 37cce0c

Please sign in to comment.