-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathmain.cpp
More file actions
213 lines (174 loc) · 5.61 KB
/
main.cpp
File metadata and controls
213 lines (174 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* _
_ __ ___ ___ | | __ _
| '_ ` _ \ / _ \| |/ _` | Modular Optimization framework for
| | | | | | (_) | | (_| | Localization and mApping (MOLA)
|_| |_| |_|\___/|_|\__,_| https://github.com/MOLAorg/mola
A repertory of multi primitive-to-primitive (MP2P) ICP algorithms
and map building tools. mp2p_icp is part of MOLA.
Copyright (C) 2018-2026 Jose Luis Blanco, University of Almeria,
and individual contributors.
SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file mm-georef/main.cpp
* @brief CLI tool to manipulate geo-referencing information
* @author Jose Luis Blanco Claraco
* @date Feb 17, 2025
*/
#include <mp2p_icp/metricmap.h>
#include <mrpt/3rdparty/tclap/CmdLine.h>
#include <mrpt/containers/yaml.h>
#include <mrpt/io/CFileGZInputStream.h>
#include <mrpt/io/CFileGZOutputStream.h>
#include <mrpt/serialization/CArchive.h>
#include <mrpt/system/filesystem.h>
#include <mrpt/system/os.h>
#include <fstream>
#include <stdexcept>
namespace
{
bool is_binary_file(const std::string& fil)
{
return mrpt::system::extractFileExtension(fil) == "georef";
}
// CLI flags:
struct Cli
{
TCLAP::CmdLine cmd{"mm-georef"};
TCLAP::ValueArg<std::string> argMap{
"m", "mao", "Input/Output .mm file to operate on", true, "theMap.mm", "theMap.mm", cmd};
TCLAP::ValueArg<std::string> argGeoRef{
"g",
"georef",
"Input/Output file with geo-referencing metadata, in binary format (`*.georef`) or yaml "
"(*.yaml,*.yml) ",
true,
"(myMap.georef|myMap.yaml)",
"(myMap.georef|myMap.yaml)",
cmd};
TCLAP::SwitchArg argExtract{
"", "extract-from-map",
"Reads the geo-referencing data from the map and saves it to a .georef "
"file",
cmd};
TCLAP::SwitchArg argInject{
"", "inject-to-map",
"Reads the geo-referencing data from an input file and stores it into "
"the existing map file."
"file",
cmd};
TCLAP::ValueArg<std::string> arg_plugins{
"l", "load-plugins", "One or more (comma separated) *.so files to load as plugins",
false, "foobar.so", "foobar.so",
cmd};
};
void run_mm_extract(Cli& cli)
{
const auto& filInput = cli.argMap.getValue();
std::cout << "[mm-georef] Reading input map from: '" << filInput << "'..." << std::endl;
mp2p_icp::metric_map_t mm;
mm.load_from_file(filInput);
std::cout << "[mm-georef] Done read map:" << mm.contents_summary() << std::endl;
ASSERT_(!mm.empty());
std::cout << "[mm-georef] Done. Output map: " << mm.contents_summary() << std::endl;
// Save as .georef file:
const auto filOut = cli.argGeoRef.getValue();
std::cout << "[mm-georef] Writing geo-referencing metamap to: '" << filOut << "'..."
<< std::endl;
if (is_binary_file(filOut))
{
mrpt::io::CFileGZOutputStream f(filOut);
auto arch = mrpt::serialization::archiveFrom(f);
arch << mm.georeferencing;
}
else
{
const auto yamlData = mp2p_icp::ToYAML(mm.georeferencing);
std::ofstream of(filOut);
ASSERT_(of.is_open());
of << yamlData;
}
}
void run_mm_inject(Cli& cli)
{
// Load .georef file:
const auto filIn = cli.argGeoRef.getValue();
std::cout << "[mm-georef] Reading geo-referencing metamap from: '" << filIn << "'..."
<< std::endl;
std::optional<mp2p_icp::metric_map_t::Georeferencing> g;
if (is_binary_file(filIn))
{
mrpt::io::CFileGZInputStream f(filIn);
auto arch = mrpt::serialization::archiveFrom(f);
arch >> g;
}
else
{
const auto yamlData = mrpt::containers::yaml::FromFile(filIn);
g = mp2p_icp::FromYAML(yamlData);
}
const auto& filMap = cli.argMap.getValue();
std::cout << "[mm-georef] Reading input map from: '" << filMap << "'..." << std::endl;
mp2p_icp::metric_map_t mm;
bool readOk = mm.load_from_file(filMap);
if (!readOk)
{
THROW_EXCEPTION_FMT("Error reading map file: '%s'", filMap.c_str());
}
std::cout << "[mm-georef] Done read map: " << mm.contents_summary() << std::endl;
// Set geo-ref data:
mm.georeferencing = g;
std::cout << "[mm-georef] Set georeferencing data. Updated map data: " << mm.contents_summary()
<< std::endl;
std::cout << "[mm-georef] Saving updated map to: '" << filMap << "'..." << std::endl;
bool ok = mm.save_to_file(filMap);
if (!ok)
{
THROW_EXCEPTION_FMT("Error saving updated map to file: '%s'", filMap.c_str());
}
}
void run_mm_georef(Cli& cli)
{
// Load plugins:
if (cli.arg_plugins.isSet())
{
std::string errMsg;
const auto plugins = cli.arg_plugins.getValue();
std::cout << "Loading plugin(s): " << plugins << std::endl;
if (!mrpt::system::loadPluginModules(plugins, errMsg))
{
throw std::runtime_error(errMsg);
}
}
if (cli.argExtract.isSet())
{
return run_mm_extract(cli);
}
if (cli.argInject.isSet())
{
return run_mm_inject(cli);
}
THROW_EXCEPTION(
"One of either '--extract-from-map' or '--inject-to-map' flags must be "
"provided.");
}
} // namespace
int main(int argc, char** argv)
{
try
{
Cli cli;
// Parse arguments:
if (!cli.cmd.parse(argc, argv))
{
return 1; // should exit.
}
run_mm_georef(cli);
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}