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