1 /******************************************************************************
2 * Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
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 Hobu, Inc. or Flaxen Geo Consulting nor the
17 * names of its contributors may be used to endorse or promote
18 * products derived from this software without specific prior
19 * 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 #include "SplitKernel.hpp"
36
37 #include <io/BufferReader.hpp>
38 #include <pdal/StageFactory.hpp>
39 #include <pdal/util/Utils.hpp>
40
41 namespace pdal
42 {
43
44 static StaticPluginInfo const s_info
45 {
46 "kernels.split",
47 "Split Kernel",
48 "http://pdal.io/apps/split.html"
49 };
50
CREATE_STATIC_KERNEL(SplitKernel,s_info)51 CREATE_STATIC_KERNEL(SplitKernel, s_info)
52
53 std::string SplitKernel::getName() const
54 {
55 return s_info.name;
56 }
57
58
addSwitches(ProgramArgs & args)59 void SplitKernel::addSwitches(ProgramArgs& args)
60 {
61 args.add("input,i", "Input filename", m_inputFile).setPositional();
62 args.add("output,o", "Output filename", m_outputFile).setPositional();
63 args.add("length", "Edge length for splitter cells", m_length, 0.0);
64 args.add("capacity", "Point capacity of chipper cells", m_capacity);
65 args.add("origin_x", "Origin in X axis for splitter cells", m_xOrigin,
66 std::numeric_limits<double>::quiet_NaN());
67 args.add("origin_y", "Origin in Y axis for splitter cells", m_yOrigin,
68 std::numeric_limits<double>::quiet_NaN());
69 }
70
71
validateSwitches(ProgramArgs & args)72 void SplitKernel::validateSwitches(ProgramArgs& args)
73 {
74 if (m_length && m_capacity)
75 throw pdal_error("Can't specify both length and capacity.");
76 if (!m_length && !m_capacity)
77 m_capacity = 100000;
78 if (m_outputFile.back() == Utils::dirSeparator)
79 m_outputFile += m_inputFile;
80 }
81
82
83 namespace
84 {
makeFilename(const std::string & s,int i)85 std::string makeFilename(const std::string& s, int i)
86 {
87 std::string out = s;
88 auto pos = out.find_last_of('.');
89 if (pos == out.npos)
90 pos = out.length();
91 out.insert(pos, std::string("_") + std::to_string(i));
92 return out;
93 }
94 }
95
96
execute()97 int SplitKernel::execute()
98 {
99 Stage& reader = makeReader(m_inputFile, m_driverOverride);
100
101 Options filterOpts;
102 std::string driver = (m_length ? "filters.splitter" : "filters.chipper");
103 if (m_length)
104 {
105 filterOpts.add("length", m_length);
106 filterOpts.add("origin_x", m_xOrigin);
107 filterOpts.add("origin_y", m_yOrigin);
108 }
109 else
110 {
111 filterOpts.add("capacity", m_capacity);
112 }
113 Stage& f = makeFilter(driver, reader, filterOpts);
114
115 ColumnPointTable table;
116 f.prepare(table);
117 PointViewSet pvSet = f.execute(table);
118
119 int filenum = 1;
120 for (auto& pvp : pvSet)
121 {
122 BufferReader reader;
123 reader.addView(pvp);
124
125 std::string filename = makeFilename(m_outputFile, filenum++);
126 Stage& writer = makeWriter(filename, reader, "");
127
128 writer.prepare(table);
129 writer.execute(table);
130 }
131 return 0;
132 }
133
134 } // namespace pdal
135