0.4.1
Loading...
Searching...
No Matches
KmlLogger.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#include "KmlLogger.hpp"
10
11#include <imgui.h>
12#include <implot_internal.h>
13
16#include "NodeData/NodeData.hpp"
17
19#include "internal/Node/Pin.hpp"
20#include "util/Logger.hpp"
21
22#include <algorithm>
23#include <iomanip> // std::setprecision
24#include <memory>
25
27namespace nm = NAV::NodeManager;
29#include "NodeRegistry.hpp"
30
32 : Node(typeStatic())
33{
34 LOG_TRACE("{}: called", name);
35
37
38 _hasConfig = true;
39 _guiConfigDefaultWindowSize = { 380, 70 };
40}
41
43{
44 LOG_TRACE("{}: called", nameId());
45}
46
48{
49 return "KmlLogger";
50}
51
52std::string NAV::KmlLogger::type() const
53{
54 return typeStatic();
55}
56
58{
59 return "Data Logger";
60}
61
63{
64 if (FileWriter::guiConfig(".kml", { ".kml" }, size_t(id), nameId()))
65 {
68 }
69 if (_dynamicInputPins.ShowGuiWidgets(size_t(id), inputPins, this))
70 {
72 }
73}
74
75[[nodiscard]] json NAV::KmlLogger::save() const
76{
77 LOG_TRACE("{}: called", nameId());
78
79 json j;
80
81 j["dynamicInputPins"] = _dynamicInputPins;
82 j["FileWriter"] = FileWriter::save();
83
84 return j;
85}
86
88{
89 LOG_TRACE("{}: called", nameId());
90
91 if (j.contains("dynamicInputPins"))
92 {
93 NAV::gui::widgets::from_json(j.at("dynamicInputPins"), _dynamicInputPins, this);
94 }
95 if (j.contains("FileWriter"))
96 {
97 FileWriter::restore(j.at("FileWriter"));
98 }
99}
100
102{
103 // See https://developers.google.com/kml/documentation/kml_tut#paths
104 LOG_DEBUG("{}: Received all data. Writing file now...", nameId());
105 _filestream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
106 "<kml xmlns=\"http://earth.google.com/kml/2.2\">\n"
107 "<Document>\n"
108 "<Style id=\"P0\">\n"
109 " <IconStyle>\n"
110 " <color>ffffffff</color>\n"
111 " <scale>0.3</scale>\n"
112 " <Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>\n"
113 " </IconStyle>\n"
114 "</Style>\n"
115 "<Style id=\"P2\">\n"
116 " <IconStyle>\n"
117 " <color>ff00aaff</color>\n"
118 " <scale>0.2</scale>\n"
119 " <Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>\n"
120 " </IconStyle>\n"
121 "</Style>\n";
122
123 ImPlotContext& gp = *ImPlot::GetCurrentContext();
124 int cmap = gp.Style.Colormap; // Current selected colormap
125 int nColors = gp.ColormapData.GetKeyCount(cmap);
126
127 for (size_t i = 0; i < _positionData.size(); i++)
128 {
129 int cidx = static_cast<int>(i) % nColors;
130 ImColor color(gp.ColormapData.GetKeyColor(cmap, cidx));
131 _filestream << "<Style id=\"line" << i << "\">\n"
132 << " <LineStyle>\n"
133 " <color>" // ff00aaff
134 << fmt::format("{:02x}{:02x}{:02x}{:02x}",
135 static_cast<int>(color.Value.w * 255.0F),
136 static_cast<int>(color.Value.z * 255.0F),
137 static_cast<int>(color.Value.y * 255.0F),
138 static_cast<int>(color.Value.x * 255.0F))
139 << "</color>\n"
140 " <width>1</width>\n"
141 " </LineStyle>\n"
142 "</Style>\n";
143 }
144
145 for (size_t i = 0; i < _positionData.size(); i++)
146 {
147 const auto& posData = _positionData.at(i);
148 if (posData.empty()) { continue; }
149
150 if (posData.size() > 1) // Track
151 {
152 _filestream << "<Placemark>\n"
153 << "<name>" << inputPins.at(i).name << " Track</name>\n"
154 << "<styleUrl>#line" << i << "</styleUrl>\n"
155 << "<LineString>\n"
156 << "<altitudeMode>absolute</altitudeMode>\n"
157 "<coordinates>\n";
158 for (const auto& lla : posData)
159 {
160 fmt::print(_filestream, "{:.9f},{:.9f},{:.3f}\n", lla.y(), lla.x(), lla.z());
161 }
162
163 _filestream << "</coordinates>\n"
164 "</LineString>\n"
165 "</Placemark>\n";
166 }
167
168 // Position
169 {
170 if (posData.size() > 1)
171 {
172 _filestream << "<Folder>\n"
173 << "<name>" << inputPins.at(i).name << " Position</name>\n"
174 << "<visibility>0</visibility>";
175 }
176 for (const auto& lla : posData)
177 {
178 _filestream << "<Placemark>\n";
179 if (posData.size() > 1)
180 {
181 _filestream << "<styleUrl>#P2</styleUrl>\n";
182 }
183 else
184 {
185 _filestream << "<name>" << inputPins.at(i).name << " Position</name>\n";
186 _filestream << "<styleUrl>#P0</styleUrl>\n";
187 }
188 _filestream << "<Point>\n"
189 "<extrude>1</extrude>\n"
190 "<altitudeMode>absolute</altitudeMode>\n"
191 << "<coordinates>";
192 fmt::print(_filestream, "{:.9f},{:.9f},{:.3f}", lla.y(), lla.x(), lla.z()); //
193 _filestream << "</coordinates>\n"
194 "</Point>\n"
195 "</Placemark>\n";
196 }
197 if (posData.size() > 1)
198 {
199 _filestream << "</Folder>\n";
200 }
201 }
202 }
203
204 _filestream << "</Document>\n"
205 << "</kml>\n";
206 _filestream.flush();
207}
208
210{
211 LOG_TRACE("{}: called", nameId());
212
214 {
215 return false;
216 }
217
218 for (auto& posData : _positionData)
219 {
220 posData.clear();
221 }
222
223 return true;
224}
225
227{
228 LOG_TRACE("{}: called", nameId());
229
231}
232
234{
235 auto* kmlNode = static_cast<KmlLogger*>(node); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
236
237 nm::CreateInputPin(node, fmt::format("Pin {}", node->inputPins.size() + 1).c_str(), Pin::Type::Flow,
238 { Pos::type() },
240
241 kmlNode->_positionData.emplace_back();
242}
243
244void NAV::KmlLogger::pinDeleteCallback(Node* node, size_t pinIdx)
245{
246 auto* kmlNode = static_cast<KmlLogger*>(node); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
247
248 kmlNode->_positionData.erase(std::next(kmlNode->_positionData.begin(), static_cast<int64_t>(pinIdx)));
249
250 nm::DeleteInputPin(node->inputPins.at(pinIdx));
251}
252
254{
255 auto obs = std::static_pointer_cast<const Pos>(queue.extract_front());
256 LOG_DATA("{}: [{}] Received data {}", nameId(), obs->insTime.toYMDHMS(GPST), egm96_compute_altitude_offset(obs->latitude(), obs->longitude()));
257
258 _positionData.at(pinIdx).emplace_back(rad2deg(obs->latitude()),
259 rad2deg(obs->longitude()),
260 obs->altitude() - egm96_compute_altitude_offset(obs->latitude(), obs->longitude()));
261}
EGM96 geoid model.
Save/Load the Nodes.
nlohmann::json json
json namespace
Data Logger for Pos data as KML (Keyhole Markup Language) files (input for Google Earth)
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Definition Logger.hpp:65
Abstract NodeData Class.
Manages all Nodes.
Utility class which specifies available nodes.
Pin class.
Position Storage Class.
@ ASCII
Ascii text data.
FileType _fileType
File Type.
void deinitialize()
Deinitialize the file reader.
bool guiConfig(const char *vFilters, const std::vector< std::string > &extensions, size_t id, const std::string &nameId)
ImGui config.
void restore(const json &j)
Restores the node from a json object.
json save() const
Saves the node into a json object.
bool initialize()
Initialize the file reader.
std::ofstream _filestream
File stream to write the file.
TsDeque< std::shared_ptr< const NAV::NodeData > > NodeDataQueue
Node data queue type.
Definition Pin.hpp:707
~KmlLogger() override
Destructor.
Definition KmlLogger.cpp:42
void restore(const json &j) override
Restores the node from a json object.
Definition KmlLogger.cpp:87
std::string type() const override
String representation of the Class Type.
Definition KmlLogger.cpp:52
json save() const override
Saves the node into a json object.
Definition KmlLogger.cpp:75
static void pinDeleteCallback(Node *node, size_t pinIdx)
Function to call to delete a pin.
static std::string typeStatic()
String representation of the Class Type.
Definition KmlLogger.cpp:47
static std::string category()
String representation of the Class Category.
Definition KmlLogger.cpp:57
static void pinAddCallback(Node *node)
Function to call to add a new pin.
gui::widgets::DynamicInputPins _dynamicInputPins
Dynamic input pins.
Definition KmlLogger.hpp:91
void guiConfig() override
ImGui config window which is shown on double click.
Definition KmlLogger.cpp:62
std::vector< std::vector< Eigen::Vector3d > > _positionData
One data set of positions for each pin in Latitude [deg], Longitude [deg], Height above Mean Sea Leve...
Definition KmlLogger.hpp:82
void deinitialize() override
Deinitialize the node.
bool initialize() override
Initialize the node.
void flush() override
Function called by the flow executer after finishing to flush out remaining data.
KmlLogger()
Default constructor.
Definition KmlLogger.cpp:31
void writeObservation(InputPin::NodeDataQueue &queue, size_t pinIdx)
Write Observation to the file.
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
Definition Node.cpp:395
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:410
Node(std::string name)
Constructor.
Definition Node.cpp:30
std::vector< InputPin > inputPins
List of input pins.
Definition Node.hpp:397
std::string nameId() const
Node name and id.
Definition Node.cpp:253
std::string name
Name of the Node.
Definition Node.hpp:395
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:413
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
Definition TsDeque.hpp:494
bool DeleteInputPin(InputPin &pin)
Deletes the input pin. Invalidates the pin reference given.
InputPin * CreateInputPin(Node *node, const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier={}, InputPin::Callback callback=static_cast< InputPin::FlowFirableCallbackFunc >(nullptr), InputPin::FlowFirableCheckFunc firable=nullptr, int priority=0, int idx=-1)
Create an Input Pin object.
void ApplyChanges()
Signals that there have been changes to the flow.
void from_json(const json &j, DynamicInputPins &obj, Node *node)
Converts the provided json object into a node object.
@ GPST
GPS Time.
double egm96_compute_altitude_offset(double lat, double lon)
Compute the geoid undulation from the EGM96 potential coefficient model to The WGS84 ellipsoid.
Definition EGM96.cpp:272
constexpr auto rad2deg(const T &rad)
Convert Radians to Degree.
Definition Units.hpp:39
@ Flow
NodeData Trigger.
Definition Pin.hpp:52