1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  libLAS - http://liblas.org - A BSD library for LAS format data.
5  * Purpose:  LAS filter implementation for C++ libLAS
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 #include <liblas/filter.hpp>
43 #include <liblas/classification.hpp>
44 // boost
45 #include <boost/cstdint.hpp>
46 // std
47 #include <vector>
48 
49 using namespace boost;
50 
51 namespace liblas {
52 
ClassificationFilter(std::vector<liblas::Classification> classes)53 ClassificationFilter::ClassificationFilter( std::vector<liblas::Classification> classes )
54     : FilterI(eInclusion)
55     , m_classes(classes)
56 {
57 }
58 
filter(const Point & p)59 bool ClassificationFilter::filter(const Point& p)
60 {
61     Classification c = p.GetClassification();
62 
63     // If the user gave us an empty set of classes to filter
64     // we're going to return true regardless
65     bool output = true;
66     for (class_list_type::const_iterator it = m_classes.begin(); it != m_classes.end(); ++it) {
67         if (c == *it) {
68             if (GetType() == eInclusion) {
69                 output = true;
70             } else {
71                 output = false;
72             }
73             break;
74         } else {
75             output = false;
76         }
77     }
78     return output;
79 }
80 
BoundsFilter(double minx,double miny,double maxx,double maxy)81 BoundsFilter::BoundsFilter( double minx, double miny, double maxx, double maxy ) : FilterI(eInclusion)
82 {
83     bounds = Bounds<double>(minx, miny, maxx, maxy);
84 }
85 
BoundsFilter(double minx,double miny,double minz,double maxx,double maxy,double maxz)86 BoundsFilter::BoundsFilter( double minx, double miny, double minz, double maxx, double maxy, double maxz ) : FilterI(eInclusion)
87 {
88     bounds = Bounds<double>(minx, miny, minz, maxx, maxy, maxz);
89 }
90 
BoundsFilter(Bounds<double> const & b)91 BoundsFilter::BoundsFilter( Bounds<double> const& b) : FilterI(eInclusion)
92 {
93     bounds = b;
94 }
filter(const Point & p)95 bool BoundsFilter::filter(const Point& p)
96 {
97     return bounds.contains(p);
98     // lasinfo --extent 630000.00 4834500.00 46.83 630300 4834600.00 150.00 TO_core_las_zoom.las
99 
100     // lasinfo --minx 630000.00 --miny 4834500.00 --minz 46.83 --maxx 630300 --maxy 4834600.00 --maxz 150.00 TO_core_las_zoom.las
101 
102 }
103 
104 
105 
ThinFilter(uint32_t thin)106 ThinFilter::ThinFilter( uint32_t thin ) :
107  liblas::FilterI(eInclusion)
108 {
109     thin_amount = thin;
110     thin_count = 0;
111 }
112 
113 
114 
filter(const liblas::Point & p)115 bool ThinFilter::filter(const liblas::Point& p)
116 {
117     // FIXME: why p is not used? --mloskot
118     // Because this filter is really just a counter.
119     // It throws out all points that aren't
120     // thin_count % thin_amount == 0. --hobu
121     boost::ignore_unused_variable_warning(p);
122 
123     // If thin_amount == thin_count, we throw this one out.
124     bool output = false;
125     if (thin_amount == thin_count)
126     {
127         output = true;
128         thin_count = 0;
129     }
130 
131     thin_count = thin_count + 1;
132 
133     return output;
134 }
135 
136 
ReturnFilter(return_list_type returns,bool last_only)137 ReturnFilter::ReturnFilter( return_list_type returns, bool last_only )
138     : FilterI(eInclusion)
139     , m_returns(returns), last_only(last_only)
140 {
141 }
142 
filter(const Point & p)143 bool ReturnFilter::filter(const Point& p)
144 {
145 
146     if (last_only) {
147         bool isLast = p.GetReturnNumber() == p.GetNumberOfReturns();
148 
149         // If the type is switched to eExclusion, we'll throw out all last returns.
150         if (GetType() == eExclusion)
151             isLast = false;
152         return isLast;
153     }
154 
155     uint16_t r = p.GetReturnNumber();
156 
157     // If the user gave us an empty set of returns to filter
158     // we're going to return true regardless
159     bool output = true;
160     for (return_list_type::const_iterator it = m_returns.begin(); it != m_returns.end(); ++it) {
161 
162         if (r == *it) {
163             if (GetType() == eInclusion) {
164                 output = true;
165             } else {
166                 output = false;
167             }
168             break;
169         } else {
170             output = false;
171         }
172     }
173     return output;
174 }
175 
ValidationFilter()176 ValidationFilter::ValidationFilter() :
177  liblas::FilterI(eInclusion)
178 {
179 
180 }
181 
182 
183 
filter(const liblas::Point & p)184 bool ValidationFilter::filter(const liblas::Point& p)
185 {
186 
187     bool output = false;
188     if (p.IsValid()){
189         if (GetType() == eInclusion) {
190             output = true;
191         } else {
192             output = false;
193         }
194     }
195 
196     return output;
197 }
198 
199 
ColorFilter(liblas::Color const & low,liblas::Color const & high)200 ColorFilter::ColorFilter(liblas::Color const& low, liblas::Color const& high) :
201  liblas::FilterI(eInclusion), m_low(low), m_high(high)
202 {
203 
204 }
205 
ColorFilter(liblas::Color::value_type low_red,liblas::Color::value_type high_red,liblas::Color::value_type low_blue,liblas::Color::value_type high_blue,liblas::Color::value_type low_green,liblas::Color::value_type high_green)206 ColorFilter::ColorFilter(liblas::Color::value_type low_red,
207                 liblas::Color::value_type high_red,
208                 liblas::Color::value_type low_blue,
209                 liblas::Color::value_type high_blue,
210                 liblas::Color::value_type low_green,
211                 liblas::Color::value_type high_green) :
212  liblas::FilterI(eInclusion), m_low(low_red, low_green, low_blue), m_high(high_red, high_blue, high_green)
213 {
214 
215 }
216 
DoExclude()217 bool ColorFilter::DoExclude()
218 {
219     if (GetType() == eInclusion) {
220         return true;
221     } else {
222         return false;
223     }
224 }
225 
226 
filter(const liblas::Point & p)227 bool ColorFilter::filter(const liblas::Point& p)
228 {
229 
230     liblas::Color const& c = p.GetColor();
231 
232     if (c.GetRed() < m_low.GetRed())
233         return !DoExclude();
234 
235     if (c.GetRed() > m_high.GetRed())
236         return !DoExclude();
237 
238     if (c.GetBlue() < m_low.GetBlue())
239         return !DoExclude();
240 
241     if (c.GetBlue() > m_high.GetBlue())
242         return !DoExclude();
243 
244     if (c.GetGreen() < m_low.GetGreen())
245         return !DoExclude();
246 
247     if (c.GetGreen() > m_high.GetGreen())
248         return !DoExclude();
249 
250     return DoExclude();
251 }
252 
253 } // namespace liblas
254