1
/******************************************************************************
4
* Project: libLAS - http://liblas.org - A BSD library for LAS format data.
5
* Purpose: LAS filter class
6
* Author: Howard Butler, hobu.inc@gmail.com
8
******************************************************************************
9
* Copyright (c) 2010, Howard Butler
11
* All rights reserved.
13
* Redistribution and use in source and binary forms, with or without
14
* modification, are permitted provided that the following
17
* * Redistributions of source code must retain the above copyright
18
* notice, this list of conditions and the following disclaimer.
19
* * Redistributions in binary form must reproduce the above copyright
20
* notice, this list of conditions and the following disclaimer in
21
* the documentation and/or other materials provided
22
* with the distribution.
23
* * Neither the name of the Martin Isenburg or Iowa Department
24
* of Natural Resources nor the names of its contributors may be
25
* used to endorse or promote products derived from this software
26
* without specific prior written permission.
28
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
35
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
36
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
38
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40
****************************************************************************/
42
#ifndef LIBLAS_LASFILTER_HPP_INCLUDED
43
#define LIBLAS_LASFILTER_HPP_INCLUDED
45
#include <liblas/version.hpp>
46
#include <liblas/header.hpp>
47
#include <liblas/point.hpp>
48
#include <liblas/detail/fwd.hpp>
49
#include <liblas/export.hpp>
51
#include <boost/cstdint.hpp>
52
#include <boost/function.hpp>
53
#include <boost/lexical_cast.hpp>
54
#include <boost/shared_ptr.hpp>
62
/// Defines public interface to LAS filter implementation.
67
/// Determines whether or not the filter keeps or rejects points that meet
68
/// filtering criteria
71
eExclusion = 0, ///< Filter removes point that meet the criteria of filter(const Point& point)
72
eInclusion = 1 ///< Filter keeps point that meet the criteria of filter(const Point& point)
75
/// Function called by liblas::Reader::ReadNextPoint to apply the (list)
76
/// of filter to the point. If the function returns true, the point
77
/// passes the filter and is kept.
78
virtual bool filter(const Point& point) = 0;
80
/// Sets whether the filter is one that keeps data that matches
81
/// construction criteria or rejects them.
82
void SetType(FilterType t) {m_type = t;}
84
/// Gets the type of filter.
85
FilterType GetType() const {return m_type; }
89
/// Base constructor. Initializes the FilterType
90
FilterI(FilterType t) : m_type(t) {}
94
FilterI(FilterI const& other);
95
FilterI& operator=(FilterI const& rhs);
100
typedef boost::shared_ptr<FilterI> FilterPtr;
102
/// A filter for keeping or rejecting points that fall within a
103
/// specified bounds.
104
class LAS_DLL BoundsFilter: public FilterI
108
BoundsFilter(double minx, double miny, double maxx, double maxy);
109
BoundsFilter(double minx, double miny, double minz, double maxx, double maxy, double maxz);
110
BoundsFilter(Bounds<double> const& b);
111
bool filter(const Point& point);
115
liblas::Bounds<double> bounds;
117
BoundsFilter(BoundsFilter const& other);
118
BoundsFilter& operator=(BoundsFilter const& rhs);
121
/// A filter for keeping or rejecting a list of classification ids
122
class LAS_DLL ClassificationFilter: public FilterI
126
typedef std::vector<liblas::Classification> class_list_type;
128
ClassificationFilter(class_list_type classes);
129
bool filter(const Point& point);
133
class_list_type m_classes;
135
ClassificationFilter(ClassificationFilter const& other);
136
ClassificationFilter& operator=(ClassificationFilter const& rhs);
139
/// A filter simple decimation
140
class LAS_DLL ThinFilter: public liblas::FilterI
144
/// Default constructor. Keep every thin'th point.
145
ThinFilter(boost::uint32_t thin);
146
bool filter(const liblas::Point& point);
151
ThinFilter(ThinFilter const& other);
152
ThinFilter& operator=(ThinFilter const& rhs);
154
boost::uint32_t thin_amount;
155
boost::uint32_t thin_count;
159
/// A filter for keeping or rejecting a list of return ids.
160
class LAS_DLL ReturnFilter: public FilterI
164
typedef std::vector<boost::uint16_t> return_list_type;
166
ReturnFilter(return_list_type returns, bool last_only);
167
bool filter(const Point& point);
171
return_list_type m_returns;
174
ReturnFilter(ReturnFilter const& other);
175
ReturnFilter& operator=(ReturnFilter const& rhs);
179
class LAS_DLL ValidationFilter: public FilterI
184
bool filter(const Point& point);
188
ValidationFilter(ValidationFilter const& other);
189
ValidationFilter& operator=(ValidationFilter const& rhs);
193
/// A templated class that allows you
194
/// to create complex filters using functions that are callable
195
/// from the liblas::Point class. See laskernel.cpp for examples
196
/// how to use it for filtering intensity and time values.
197
template <typename T>
198
class LAS_DLL ContinuousValueFilter: public FilterI
204
typedef boost::function<T (const Point*)> filter_func;
205
typedef boost::function<bool(T, T)> compare_func;
207
/// Construct the filter with a filter_func, a comparison value,
208
/// and a compare_func. To use this we must take in a filtering function that returns
209
/// us a value from the point, and a binary_predicate comparator
210
/// (ie, std::less, std::greater, std::equal_to, etc).
211
/// \param f - The function to compare with from the liblas::Point. It
212
/// must be one of the functions that returns an integer type or double type
213
/// \param value - The value to use for one-way comparison
214
/// \param c - the std::binary_predicate to use for comparison
216
/// To use this we must take in a filtering function that returns
217
/// us a value from the point, and a binary_predicate comparator
218
/// (ie, std::less, std::greater, std::equal_to, etc).
221
/// GetIntensity returns a uint16_t, so we use that for our template
222
/// value. This filter would keep all points with intensities that are
225
/// liblas::ContinuousValueFilter<uint16_t>::compare_func c = std::less<uint16_t>();
226
/// liblas::ContinuousValueFilter<uint16_t>::filter_func f = &liblas::Point::GetIntensity;
227
/// liblas::ContinuousValueFilter<uint16_t>* intensity_filter = new liblas::ContinuousValueFilter<uint16_t>(f, 100, c);
228
/// intensity_filter->SetType(liblas::FilterI::eInclusion);
229
ContinuousValueFilter(filter_func f, T value, compare_func c)
230
: liblas::FilterI(eInclusion), f(f), c(c),value(value)
234
/// Construct the filter with a filter_func and a simple
236
/// \param f - The function to compare with from the liblas::Point. It
237
/// must be one of the functions that returns an integer type or double type
238
/// \param filter_string - A string to use for the filter. Supports taking
239
/// in a simple expression and turning it into
240
/// a comparator we can use. We support dead simple stuff:
247
/// We don't strip whitespace, and we don't support complex
248
/// comparisons (ie, two function 10<x<300)
250
/// In addition to explicitly setting your comparator function, you can
251
/// also use the constructor that takes in a simple expression string
252
/// and constructs the basic comparators. See the source code or las2las2
253
/// help output for the forms that are supported. This may be
254
/// improved in the future.
256
/// std::string intensities("<100")
257
/// liblas::ContinuousValueFilter<uint16_t>::filter_func f = &liblas::Point::GetIntensity;
258
/// liblas::ContinuousValueFilter<uint16_t>* intensity_filter = new liblas::ContinuousValueFilter<uint16_t>(f, intensities);
259
/// intensity_filter->SetType(liblas::FilterI::eInclusion);
261
ContinuousValueFilter(filter_func f, std::string const& filter_string)
262
: liblas::FilterI(eInclusion), f(f)
264
compare_func compare;
266
bool gt = HasPredicate(filter_string, ">");
267
bool gte = HasPredicate(filter_string, ">=");
268
bool lt = HasPredicate(filter_string, "<");
269
bool lte = HasPredicate(filter_string, "<=");
270
bool eq = HasPredicate(filter_string, "==");
272
std::string::size_type pos=0;
277
// std::cout<<"have gte!" << std::endl;
278
c = std::greater_equal<T>();
279
pos = filter_string.find_first_of("=") + 1;
283
// std::cout<<"have gt!" << std::endl;
284
c = std::greater<T>();
285
pos = filter_string.find_first_of(">") + 1;
289
// std::cout<<"have lte!" << std::endl;
290
c = std::less_equal<T>();
291
pos = filter_string.find_first_of("=") +1;
295
// std::cout<<"have le!" << std::endl;
297
pos = filter_string.find_first_of("<") + 1;
301
// std::cout<<"have eq!" << std::endl;
302
c = std::equal_to<T>();
303
pos = filter_string.find_last_of("=") + 1;
307
out = filter_string.substr(pos, filter_string.size());
309
value = boost::lexical_cast<T>(out);
310
// std::cout << "Value is: " << value << " pos " << pos << " out " << out << std::endl;
313
bool filter(const liblas::Point& p)
318
// std::cout << std::endl<< "Checking c(v, value) v: " << v << " value: " << value;
320
// std::cout<< " ... succeeded "<<std::endl;
321
if (GetType() == eInclusion) {
324
// std::cout << "Filter type is eExclusion and test passed" << std::endl;
328
// std::cout<<" ... failed" <<std::endl;
329
if (GetType() == eInclusion) {
332
// std::cout << "Filter type is eExclusion and test failed" << std::endl;
336
// std::cout << " returning " << output << std::endl;
342
ContinuousValueFilter(ContinuousValueFilter const& other);
343
ContinuousValueFilter& operator=(ContinuousValueFilter const& rhs);
348
bool HasPredicate(std::string const& parse_string, std::string predicate)
350
// Check if the given string contains all of the characters of predicate
351
// For example, does '>=300' have both > and = (as given in the predicate string)
353
// We must have all of the characters in the predicate to return true
354
for (std::string::const_iterator i = predicate.begin(); i!=predicate.end(); ++i) {
355
std::string::size_type pred = parse_string.find_first_of(*i);
356
if (pred != std::string::npos) {
368
/// A filter for color ranges
369
class LAS_DLL ColorFilter: public FilterI
373
ColorFilter(liblas::Color const& low,
374
liblas::Color const& high);
376
ColorFilter(liblas::Color::value_type low_red,
377
liblas::Color::value_type high_red,
378
liblas::Color::value_type low_blue,
379
liblas::Color::value_type high_blue,
380
liblas::Color::value_type low_green,
381
liblas::Color::value_type high_green);
382
bool filter(const Point& point);
387
liblas::Color m_high;
389
ColorFilter(ColorFilter const& other);
390
ColorFilter& operator=(ColorFilter const& rhs);
394
} // namespace liblas
396
#endif // ndef LIBLAS_LASFILTER_HPP_INCLUDED