~ubuntu-branches/ubuntu/trusty/liblas/trusty-proposed

« back to all changes in this revision

Viewing changes to include/liblas/filter.hpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-01-05 17:00:29 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140105170029-ddtp0j63x5jvck2u
Tags: 1.7.0+dfsg-2
Fixed missing linking of system boost component.
(closes: #733282)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id$
 
3
 *
 
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
 
7
 *
 
8
 ******************************************************************************
 
9
 * Copyright (c) 2010, Howard Butler
 
10
 *
 
11
 * All rights reserved.
 
12
 * 
 
13
 * Redistribution and use in source and binary forms, with or without 
 
14
 * modification, are permitted provided that the following 
 
15
 * conditions are met:
 
16
 * 
 
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.
 
27
 * 
 
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 
 
39
 * OF SUCH DAMAGE.
 
40
 ****************************************************************************/
 
41
 
 
42
#ifndef LIBLAS_LASFILTER_HPP_INCLUDED
 
43
#define LIBLAS_LASFILTER_HPP_INCLUDED
 
44
 
 
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>
 
50
// boost
 
51
#include <boost/cstdint.hpp>
 
52
#include <boost/function.hpp>
 
53
#include <boost/lexical_cast.hpp>
 
54
#include <boost/shared_ptr.hpp>
 
55
// std
 
56
#include <vector>
 
57
#include <functional>
 
58
#include <string>
 
59
 
 
60
namespace liblas {
 
61
 
 
62
/// Defines public interface to LAS filter implementation.
 
63
class LAS_DLL FilterI
 
64
{
 
65
public:
 
66
    
 
67
    /// Determines whether or not the filter keeps or rejects points that meet 
 
68
    /// filtering criteria
 
69
    enum FilterType
 
70
    {
 
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)
 
73
    };
 
74
    
 
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;
 
79
    
 
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;}
 
83
 
 
84
    /// Gets the type of filter.
 
85
    FilterType GetType() const {return m_type; }
 
86
 
 
87
    virtual ~FilterI() {}
 
88
 
 
89
    /// Base constructor.  Initializes the FilterType
 
90
    FilterI(FilterType t) : m_type(t) {}
 
91
    
 
92
private:
 
93
 
 
94
    FilterI(FilterI const& other);
 
95
    FilterI& operator=(FilterI const& rhs);
 
96
 
 
97
    FilterType m_type;
 
98
};
 
99
 
 
100
typedef boost::shared_ptr<FilterI> FilterPtr;
 
101
 
 
102
/// A filter for keeping or rejecting points that fall within a 
 
103
/// specified bounds.
 
104
class LAS_DLL BoundsFilter: public FilterI
 
105
{
 
106
public:
 
107
    
 
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);
 
112
 
 
113
private:
 
114
    
 
115
    liblas::Bounds<double> bounds;
 
116
 
 
117
    BoundsFilter(BoundsFilter const& other);
 
118
    BoundsFilter& operator=(BoundsFilter const& rhs);
 
119
};
 
120
 
 
121
/// A filter for keeping or rejecting a list of classification ids
 
122
class LAS_DLL ClassificationFilter: public FilterI
 
123
{
 
124
public:
 
125
    
 
126
    typedef std::vector<liblas::Classification> class_list_type;
 
127
 
 
128
    ClassificationFilter(class_list_type classes);
 
129
    bool filter(const Point& point);
 
130
    
 
131
private:
 
132
 
 
133
    class_list_type m_classes;
 
134
 
 
135
    ClassificationFilter(ClassificationFilter const& other);
 
136
    ClassificationFilter& operator=(ClassificationFilter const& rhs);
 
137
};
 
138
 
 
139
/// A filter simple decimation
 
140
class LAS_DLL ThinFilter: public liblas::FilterI
 
141
{
 
142
public:
 
143
    
 
144
    /// Default constructor.  Keep every thin'th point.
 
145
    ThinFilter(boost::uint32_t thin);
 
146
    bool filter(const liblas::Point& point);
 
147
 
 
148
 
 
149
private:
 
150
 
 
151
    ThinFilter(ThinFilter const& other);
 
152
    ThinFilter& operator=(ThinFilter const& rhs);
 
153
    
 
154
    boost::uint32_t thin_amount;
 
155
    boost::uint32_t thin_count;
 
156
};
 
157
 
 
158
 
 
159
/// A filter for keeping or rejecting a list of return ids.
 
160
class LAS_DLL ReturnFilter: public FilterI
 
161
{
 
162
public:
 
163
    
 
164
    typedef std::vector<boost::uint16_t> return_list_type;
 
165
 
 
166
    ReturnFilter(return_list_type returns, bool last_only);
 
167
    bool filter(const Point& point);
 
168
    
 
169
private:
 
170
 
 
171
    return_list_type m_returns;
 
172
    bool last_only;
 
173
 
 
174
    ReturnFilter(ReturnFilter const& other);
 
175
    ReturnFilter& operator=(ReturnFilter const& rhs);
 
176
};
 
177
 
 
178
 
 
179
class LAS_DLL ValidationFilter: public FilterI
 
180
{
 
181
public:
 
182
 
 
183
    ValidationFilter();
 
184
    bool filter(const Point& point);
 
185
    
 
186
private:
 
187
 
 
188
    ValidationFilter(ValidationFilter const& other);
 
189
    ValidationFilter& operator=(ValidationFilter const& rhs);
 
190
};
 
191
 
 
192
 
 
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
 
199
{
 
200
    
 
201
 
 
202
    // 
 
203
public:
 
204
    typedef boost::function<T (const Point*)> filter_func;
 
205
    typedef boost::function<bool(T, T)> compare_func;
 
206
 
 
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
 
215
 
 
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).  
 
219
    
 
220
    /// Example:
 
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 
 
223
    /// less than 100.
 
224
    
 
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)
 
231
    {}
 
232
 
 
233
        
 
234
    /// Construct the filter with a filter_func and a simple 
 
235
    /// expression.  
 
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:
 
241
    /// >200
 
242
    /// ==150
 
243
    /// >=32
 
244
    /// <=150
 
245
    /// <100
 
246
    
 
247
    /// We don't strip whitespace, and we don't support complex 
 
248
    /// comparisons (ie, two function  10<x<300)
 
249
    
 
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.
 
255
    
 
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);
 
260
    
 
261
    ContinuousValueFilter(filter_func f, std::string const& filter_string)
 
262
        : liblas::FilterI(eInclusion), f(f)
 
263
    {
 
264
        compare_func compare;
 
265
 
 
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, "==");
 
271
 
 
272
        std::string::size_type pos=0;
 
273
        std::string out;
 
274
 
 
275
        if (gte) // >=
 
276
        {
 
277
            // std::cout<<"have gte!" << std::endl;
 
278
            c = std::greater_equal<T>();
 
279
            pos = filter_string.find_first_of("=") + 1;
 
280
        }
 
281
        else if (gt) // .
 
282
        {
 
283
            // std::cout<<"have gt!" << std::endl;
 
284
            c = std::greater<T>();
 
285
            pos = filter_string.find_first_of(">") + 1;
 
286
        }
 
287
        else if (lte) // <=
 
288
        {
 
289
            // std::cout<<"have lte!" << std::endl;
 
290
            c = std::less_equal<T>();
 
291
            pos = filter_string.find_first_of("=") +1;
 
292
        }
 
293
        else if (lt) // <
 
294
        {
 
295
            // std::cout<<"have le!" << std::endl;
 
296
            c = std::less<T>();    
 
297
            pos = filter_string.find_first_of("<") + 1;
 
298
        }
 
299
        else if (eq) // ==
 
300
        {
 
301
            // std::cout<<"have eq!" << std::endl;
 
302
            c = std::equal_to<T>();
 
303
            pos = filter_string.find_last_of("=") + 1;
 
304
    
 
305
        }
 
306
 
 
307
        out = filter_string.substr(pos, filter_string.size());
 
308
        
 
309
        value =  boost::lexical_cast<T>(out);
 
310
        // std::cout << "Value is: " << value << " pos " << pos << " out " << out << std::endl;
 
311
    }
 
312
            
 
313
    bool filter(const liblas::Point& p)
 
314
    {
 
315
        bool output = false;
 
316
 
 
317
        T v = f(&p);
 
318
        // std::cout << std::endl<< "Checking c(v, value) v: " << v << " value: " << value;
 
319
        if (c(v, value)){
 
320
            // std::cout<< " ... succeeded "<<std::endl;
 
321
            if (GetType() == eInclusion) {
 
322
                output = true;
 
323
            } else {
 
324
                // std::cout << "Filter type is eExclusion and test passed" << std::endl;
 
325
                output = false;
 
326
            }    
 
327
        } else {
 
328
            // std::cout<<" ... failed" <<std::endl;
 
329
            if (GetType() == eInclusion) {
 
330
                output = false;
 
331
            } else {
 
332
                // std::cout << "Filter type is eExclusion and test failed" << std::endl;
 
333
                output = true;
 
334
            }    
 
335
        }
 
336
        // std::cout << " returning " << output << std::endl;
 
337
        return output;
 
338
    }
 
339
    
 
340
private:
 
341
 
 
342
    ContinuousValueFilter(ContinuousValueFilter const& other);
 
343
    ContinuousValueFilter& operator=(ContinuousValueFilter const& rhs);
 
344
    filter_func f;
 
345
    compare_func c;
 
346
    T value;
 
347
 
 
348
    bool HasPredicate(std::string const& parse_string, std::string predicate)
 
349
    {
 
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)
 
352
        bool output = false;
 
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) {
 
357
                output = true;
 
358
            } else {
 
359
                return false;
 
360
            }
 
361
        }
 
362
        return output;
 
363
    }
 
364
 
 
365
 
 
366
};
 
367
 
 
368
/// A filter for color ranges
 
369
class LAS_DLL ColorFilter: public FilterI
 
370
{
 
371
public:
 
372
 
 
373
    ColorFilter(liblas::Color const& low, 
 
374
                liblas::Color const& high);
 
375
                
 
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);
 
383
    
 
384
private:
 
385
    
 
386
    liblas::Color m_low;
 
387
    liblas::Color m_high;
 
388
 
 
389
    ColorFilter(ColorFilter const& other);
 
390
    ColorFilter& operator=(ColorFilter const& rhs);
 
391
    bool DoExclude();
 
392
};
 
393
 
 
394
} // namespace liblas
 
395
 
 
396
#endif // ndef LIBLAS_LASFILTER_HPP_INCLUDED