15 #include <mrpt/3rdparty/tclap/CmdLine.h>
16 #include <mrpt/maps/CColouredPointsMap.h>
17 #include <mrpt/maps/CPointsMapXYZI.h>
18 #include <mrpt/maps/CPointsMapXYZIRT.h>
19 #include <mrpt/maps/CSimplePointsMap.h>
20 #include <mrpt/math/CMatrixDynamic.h>
21 #include <mrpt/obs/CObservationPointCloud.h>
22 #include <mrpt/system/filesystem.h>
26 using namespace std::string_literals;
31 TCLAP::CmdLine
cmd{
"txt2mm"};
33 TCLAP::ValueArg<std::string>
argInput{
36 "Path to input TXT or CSV file. One point per row. Columns separated "
38 "spaces or commas. See docs for supported formats.",
45 "o",
"output",
"Output file to write to.",
true,
"out.mm",
48 TCLAP::ValueArg<std::string> argFormat{
51 "Point cloud format. Mandatory flag.\n"s
60 "l",
"layer",
"Target layer name (Default: \"raw\").",
false,
"raw",
63 TCLAP::ValueArg<int> argIndexXYZ{
66 "Column index for the X coordinate in the input data (Default: 0).",
72 TCLAP::ValueArg<int> argIndexI{
75 "Column index for the Intensity channel in the input data (Default: "
82 TCLAP::ValueArg<int> argIndexR{
85 "Column index for the Ring channel in the input data (Default: 4).",
91 TCLAP::ValueArg<int> argIndexT{
94 "Column index for the Timestamp channel in the input data (Default: "
102 "",
"id",
"Metric map numeric ID (Default: none).",
false, 0,
106 "",
"label",
"Metric map label string (Default: none).",
107 false,
"label",
"[label]",
111 int main(
int argc,
char** argv)
118 if (!
cli.cmd.parse(argc, argv))
return 1;
120 const auto&
f =
cli.argInput.getValue();
121 ASSERT_FILE_EXISTS_(
f);
123 std::cout <<
"Reading data from '" <<
f <<
"'..." << std::endl;
125 mrpt::math::CMatrixFloat data;
126 data.loadFromTextFile(
f);
128 const size_t nRows = data.size().at(0), nCols = data.size().at(1);
130 std::cout <<
"Done: " << nRows <<
" rows, " << nCols <<
" columns."
133 mrpt::maps::CPointsMap::Ptr pc;
134 const auto format =
cli.argFormat.getValue();
136 const auto idxX =
cli.argIndexXYZ.getValue();
137 const auto idxI =
cli.argIndexI.getValue();
138 const auto idxR =
cli.argIndexR.getValue();
139 const auto idxT =
cli.argIndexT.getValue();
143 ASSERT_GE_(nCols, 3U);
144 pc = mrpt::maps::CSimplePointsMap::Create();
147 std::cout <<
"Warning: Only the first 3 columns from the file "
148 "will be used for the output format 'xyz'"
151 for (
size_t i = 0; i < nRows; i++)
153 data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
155 else if (format ==
"xyzi")
157 ASSERT_GE_(nCols, 4U);
158 auto pts = mrpt::maps::CPointsMapXYZI::Create();
161 std::cout <<
"Warning: Only the first 4 columns from the file "
162 "will be used for the output format 'xyzi'"
165 for (
size_t i = 0; i < nRows; i++)
167 pts->insertPointFast(
168 data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
169 pts->insertPointField_Intensity(data(i, idxI));
174 else if (format ==
"xyzirt")
176 ASSERT_GE_(nCols, 6U);
177 auto pts = mrpt::maps::CPointsMapXYZI::Create();
180 std::cout <<
"Warning: Only the first 6 columns from the file "
181 "will be used for the output format 'xyzirt'"
184 for (
size_t i = 0; i < nRows; i++)
186 pts->insertPointFast(
187 data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
188 pts->insertPointField_Intensity(data(i, idxI));
189 pts->insertPointField_Ring(data(i, idxR));
190 pts->insertPointField_Timestamp(data(i, idxT));
195 else if (format ==
"xyzrgb")
197 ASSERT_GE_(nCols, 6U);
198 auto pts = mrpt::maps::CColouredPointsMap::Create();
201 std::cout <<
"Warning: Only the first 6 columns from the file "
202 "will be used for the output format 'xyzrgb'"
205 const size_t idxRed = 3, idxGreen = 4, idxBlue = 5;
207 for (
size_t i = 0; i < nRows; i++)
209 pts->insertPointFast(
210 data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
211 pts->insertPointField_color_R(mrpt::u8tof(data(i, idxRed)));
212 pts->insertPointField_color_G(mrpt::u8tof(data(i, idxGreen)));
213 pts->insertPointField_color_B(mrpt::u8tof(data(i, idxBlue)));
221 "Invalid --format set to '%s'. Valid values: %s",
227 mm.
layers[
"raw"] = std::move(pc);
229 if (
cli.argID.isSet()) mm.
id =
cli.argID.getValue();
230 if (
cli.argLabel.isSet()) mm.
label =
cli.argLabel.getValue();
233 std::cout <<
"Saving map to: " <<
cli.argOutput.getValue() << std::endl;
237 "Error writing to target file '%s'",
238 cli.argOutput.getValue().c_str());
240 catch (
const std::exception& e)
242 std::cerr << mrpt::exception_to_str(e);