1 /******************************************************************************
2  * Copyright (c) 2014, Hobu Inc.
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following
8  * conditions are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided
15  *       with the distribution.
16  *     * Neither the name of the Martin Isenburg or Iowa Department
17  *       of Natural Resources nor the names of its contributors may be
18  *       used to endorse or promote products derived from this software
19  *       without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32  * OF SUCH DAMAGE.
33  ****************************************************************************/
34 
35 #pragma once
36 
37 #include <pdal/Metadata.hpp>
38 #include <pdal/Dimension.hpp>
39 #include <pdal/pdal_export.hpp>
40 #include <pdal/util/Bounds.hpp>
41 #include <pdal/util/Inserter.hpp>
42 #include <pdal/util/Extractor.hpp>
43 
44 #ifndef _WIN32
45 #include <fcntl.h>
46 #include <unistd.h>
47 #endif
48 
49 
50 namespace pdal
51 {
52 class Options;
53 class PointView;
54 
55 typedef std::shared_ptr<PointView> PointViewPtr;
56 
57 namespace Utils
58 {
59 
printError(const std::string & s)60 inline void printError(const std::string& s)
61 {
62     std::cerr << "PDAL: " << s << std::endl;
63     std::cerr << std::endl;
64 }
65 
toDouble(const Everything & e,Dimension::Type type)66 inline double toDouble(const Everything& e, Dimension::Type type)
67 {
68     using Type = Dimension::Type;
69 
70     double d = 0;
71     switch (type)
72     {
73     case Type::Unsigned8:
74         d = e.u8;
75         break;
76     case Type::Unsigned16:
77         d = e.u16;
78         break;
79     case Type::Unsigned32:
80         d = e.u32;
81         break;
82     case Type::Unsigned64:
83         d = (double)e.u64;
84         break;
85     case Type::Signed8:
86         d = e.s8;
87         break;
88     case Type::Signed16:
89         d = e.s16;
90         break;
91     case Type::Signed32:
92         d = e.s32;
93         break;
94     case Type::Signed64:
95         d = (double)e.s64;
96         break;
97     case Type::Float:
98         d = e.f;
99         break;
100     case Type::Double:
101         d = e.d;
102         break;
103     default:
104         break;
105     }
106     return d;
107 }
108 
109 template<typename INPUT>
extractDim(INPUT & ext,Dimension::Type type)110 inline Everything extractDim(INPUT& ext, Dimension::Type type)
111 {
112     using Type = Dimension::Type;
113 
114 	Everything e;
115     switch (type)
116     {
117         case Type::Unsigned8:
118             ext >> e.u8;
119             break;
120         case Type::Unsigned16:
121             ext >> e.u16;
122             break;
123         case Type::Unsigned32:
124             ext >> e.u32;
125             break;
126         case Type::Unsigned64:
127             ext >> e.u64;
128             break;
129         case Type::Signed8:
130             ext >> e.s8;
131             break;
132         case Type::Signed16:
133             ext >> e.s16;
134             break;
135         case Type::Signed32:
136             ext >> e.s32;
137             break;
138         case Type::Signed64:
139             ext >> e.s64;
140             break;
141         case Type::Float:
142             ext >> e.f;
143             break;
144         case Type::Double:
145             ext >> e.d;
146             break;
147         case Type::None:
148             break;
149     }
150     return e;
151 }
152 
153 
154 template<typename OUTPUT>
insertDim(OUTPUT & ins,Dimension::Type type,const Everything & e)155 inline void insertDim(OUTPUT& ins, Dimension::Type type, const Everything& e)
156 {
157     using Type = Dimension::Type;
158 
159     switch (type)
160     {
161         case Type::Unsigned8:
162             ins << e.u8;
163             break;
164         case Type::Unsigned16:
165             ins << e.u16;
166             break;
167         case Type::Unsigned32:
168             ins << e.u32;
169             break;
170         case Type::Unsigned64:
171             ins << e.u64;
172             break;
173         case Type::Signed8:
174             ins << e.s8;
175             break;
176         case Type::Signed16:
177             ins << e.s16;
178             break;
179         case Type::Signed32:
180             ins << e.s32;
181             break;
182         case Type::Signed64:
183             ins << e.s64;
184             break;
185         case Type::Float:
186             ins << e.f;
187             break;
188         case Type::Double:
189             ins << e.d;
190             break;
191         case Type::None:
192             break;
193     }
194 }
195 
196 
toMetadata(const BOX2D & bounds)197 inline MetadataNode toMetadata(const BOX2D& bounds)
198 {
199     MetadataNode output("bbox");
200     output.add("minx", bounds.minx);
201     output.add("miny", bounds.miny);
202     output.add("maxx", bounds.maxx);
203     output.add("maxy", bounds.maxy);
204     return output;
205 }
206 
toMetadata(const BOX3D & bounds)207 inline MetadataNode toMetadata(const BOX3D& bounds)
208 {
209     MetadataNode output("bbox");
210     output.add("minx", bounds.minx);
211     output.add("miny", bounds.miny);
212     output.add("minz", bounds.minz);
213     output.add("maxx", bounds.maxx);
214     output.add("maxy", bounds.maxy);
215     output.add("maxz", bounds.maxz);
216     return output;
217 }
218 
openProgress(const std::string & filename)219 inline int openProgress(const std::string& filename)
220 {
221 #ifdef _WIN32
222     return -1;
223 #else
224     int fd = open(filename.c_str(), O_WRONLY | O_NONBLOCK);
225     if (fd == -1)
226     {
227         std::string out = "Can't open progress file '";
228         out += filename + "'.";
229         printError(out);
230     }
231     return fd;
232 #endif
233 }
234 
235 
closeProgress(int fd)236 inline void closeProgress(int fd)
237 {
238 #ifdef _WIN32
239 #else
240     if (fd >= 0)
241         close(fd);
242 #endif
243 }
244 
245 
writeProgress(int fd,const std::string & type,const std::string & text)246 inline void writeProgress(int fd, const std::string& type,
247     const std::string& text)
248 {
249 #ifdef _WIN32
250 #else
251 #pragma GCC diagnostic push
252 #pragma GCC diagnostic ignored "-Wunused-result"
253     if (fd >= 0)
254     {
255         std::string out = type + ':' + text + '\n';
256 
257         // This may error, but we don't care.
258         write(fd, out.c_str(), out.length());
259     }
260 #pragma GCC diagnostic pop
261 #endif
262 }
263 
264 std::string dllDir();
265 std::string PDAL_DLL toJSON(const MetadataNode& m);
266 void PDAL_DLL toJSON(const MetadataNode& m, std::ostream& o);
267 uintmax_t PDAL_DLL fileSize(const std::string& path);
268 std::istream PDAL_DLL *openFile(const std::string& path, bool asBinary = true);
269 std::ostream PDAL_DLL *createFile(const std::string& path,
270     bool asBinary = true);
271 void PDAL_DLL closeFile(std::istream *in);
272 void PDAL_DLL closeFile(std::ostream *out);
273 std::string PDAL_DLL fetchRemote(const std::string& path);
274 bool PDAL_DLL isRemote(const std::string& path);
275 bool PDAL_DLL fileExists(const std::string& path);
276 std::vector<std::string> PDAL_DLL maybeGlob(const std::string& path);
277 double PDAL_DLL computeHausdorff(PointViewPtr srcView, PointViewPtr candView);
278 std::pair<double, double> PDAL_DLL computeHausdorffPair(PointViewPtr srcView, PointViewPtr candView);
279 double PDAL_DLL computeChamfer(PointViewPtr srcView, PointViewPtr candView);
280 
281 } // namespace Utils
282 } // namespace pdal
283