0.5.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
27#include "NodeRegistry.hpp"
28
30 : Node(typeStatic())
31{
32 LOG_TRACE("{}: called", name);
33
35
36 _hasConfig = true;
37 _guiConfigDefaultWindowSize = { 380, 70 };
38}
39
41{
42 LOG_TRACE("{}: called", nameId());
43}
44
46{
47 return "KmlLogger";
48}
49
50std::string NAV::KmlLogger::type() const
51{
52 return typeStatic();
53}
54
56{
57 return "Data Logger";
58}
59
61{
62 if (FileWriter::guiConfig(".kml", { ".kml" }, size_t(id), nameId()))
63 {
66 }
67 if (_dynamicInputPins.ShowGuiWidgets(size_t(id), inputPins, this))
68 {
70 }
71}
72
73[[nodiscard]] json NAV::KmlLogger::save() const
74{
75 LOG_TRACE("{}: called", nameId());
76
77 json j;
78
79 j["dynamicInputPins"] = _dynamicInputPins;
80 j["FileWriter"] = FileWriter::save();
81
82 return j;
83}
84
86{
87 LOG_TRACE("{}: called", nameId());
88
89 if (j.contains("dynamicInputPins"))
90 {
91 NAV::gui::widgets::from_json(j.at("dynamicInputPins"), _dynamicInputPins, this);
92 }
93 if (j.contains("FileWriter"))
94 {
95 FileWriter::restore(j.at("FileWriter"));
96 }
97}
98
100{
101 // See https://developers.google.com/kml/documentation/kml_tut#paths
102 LOG_DEBUG("{}: Received all data. Writing file now...", nameId());
103 _filestream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
104 "<kml xmlns=\"http://earth.google.com/kml/2.2\">\n"
105 "<Document>\n"
106 "<Style id=\"P0\">\n"
107 " <IconStyle>\n"
108 " <color>ffffffff</color>\n"
109 " <scale>0.3</scale>\n"
110 " <Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>\n"
111 " </IconStyle>\n"
112 "</Style>\n"
113 "<Style id=\"P2\">\n"
114 " <IconStyle>\n"
115 " <color>ff00aaff</color>\n"
116 " <scale>0.2</scale>\n"
117 " <Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>\n"
118 " </IconStyle>\n"
119 "</Style>\n";
120
121 ImPlotContext& gp = *ImPlot::GetCurrentContext();
122 int cmap = gp.Style.Colormap; // Current selected colormap
123 int nColors = gp.ColormapData.GetKeyCount(cmap);
124
125 for (size_t i = 0; i < _positionData.size(); i++)
126 {
127 int cidx = static_cast<int>(i) % nColors;
128 ImColor color(gp.ColormapData.GetKeyColor(cmap, cidx));
129 _filestream << "<Style id=\"line" << i << "\">\n"
130 << " <LineStyle>\n"
131 " <color>" // ff00aaff
132 << fmt::format("{:02x}{:02x}{:02x}{:02x}",
133 static_cast<int>(color.Value.w * 255.0F),
134 static_cast<int>(color.Value.z * 255.0F),
135 static_cast<int>(color.Value.y * 255.0F),
136 static_cast<int>(color.Value.x * 255.0F))
137 << "</color>\n"
138 " <width>1</width>\n"
139 " </LineStyle>\n"
140 "</Style>\n";
141 }
142
143 for (size_t i = 0; i < _positionData.size(); i++)
144 {
145 const auto& posData = _positionData.at(i);
146 if (posData.empty()) { continue; }
147
148 if (posData.size() > 1) // Track
149 {
150 _filestream << "<Placemark>\n"
151 << "<name>" << inputPins.at(i).name << " Track</name>\n"
152 << "<styleUrl>#line" << i << "</styleUrl>\n"
153 << "<LineString>\n"
154 << "<altitudeMode>absolute</altitudeMode>\n"
155 "<coordinates>\n";
156 for (const auto& lla : posData)
157 {
158 fmt::print(_filestream, "{:.9f},{:.9f},{:.3f}\n", lla.y(), lla.x(), lla.z());
159 }
160
161 _filestream << "</coordinates>\n"
162 "</LineString>\n"
163 "</Placemark>\n";
164 }
165
166 // Position
167 {
168 if (posData.size() > 1)
169 {
170 _filestream << "<Folder>\n"
171 << "<name>" << inputPins.at(i).name << " Position</name>\n"
172 << "<visibility>0</visibility>";
173 }
174 for (const auto& lla : posData)
175 {
176 _filestream << "<Placemark>\n";
177 if (posData.size() > 1)
178 {
179 _filestream << "<styleUrl>#P2</styleUrl>\n";
180 }
181 else
182 {
183 _filestream << "<name>" << inputPins.at(i).name << " Position</name>\n";
184 _filestream << "<styleUrl>#P0</styleUrl>\n";
185 }
186 _filestream << "<Point>\n"
187 "<extrude>1</extrude>\n"
188 "<altitudeMode>absolute</altitudeMode>\n"
189 << "<coordinates>";
190 fmt::print(_filestream, "{:.9f},{:.9f},{:.3f}", lla.y(), lla.x(), lla.z()); //
191 _filestream << "</coordinates>\n"
192 "</Point>\n"
193 "</Placemark>\n";
194 }
195 if (posData.size() > 1)
196 {
197 _filestream << "</Folder>\n";
198 }
199 }
200 }
201
202 _filestream << "</Document>\n"
203 << "</kml>\n";
204 _filestream.flush();
205}
206
208{
209 LOG_TRACE("{}: called", nameId());
210
212 {
213 return false;
214 }
215
216 for (auto& posData : _positionData)
217 {
218 posData.clear();
219 }
220
221 return true;
222}
223
225{
226 LOG_TRACE("{}: called", nameId());
227
229}
230
232{
233 auto* kmlNode = static_cast<KmlLogger*>(node); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
234
235 node->CreateInputPin(fmt::format("Pin {}", node->inputPins.size() + 1).c_str(), Pin::Type::Flow,
236 { Pos::type() },
238
239 kmlNode->_positionData.emplace_back();
240}
241
242void NAV::KmlLogger::pinDeleteCallback(Node* node, size_t pinIdx)
243{
244 auto* kmlNode = static_cast<KmlLogger*>(node); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
245
246 kmlNode->_positionData.erase(std::next(kmlNode->_positionData.begin(), static_cast<int64_t>(pinIdx)));
247
248 node->DeleteInputPin(pinIdx);
249}
250
252{
253 auto obs = std::static_pointer_cast<const Pos>(queue.extract_front());
254 LOG_DATA("{}: [{}] Received data {}", nameId(), obs->insTime.toYMDHMS(GPST), egm96_compute_altitude_offset(obs->latitude(), obs->longitude()));
255
256 _positionData.at(pinIdx).emplace_back(rad2deg(obs->latitude()),
257 rad2deg(obs->longitude()),
258 obs->altitude() - egm96_compute_altitude_offset(obs->latitude(), obs->longitude()));
259}
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.
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:40
void restore(const json &j) override
Restores the node from a json object.
Definition KmlLogger.cpp:85
std::string type() const override
String representation of the Class Type.
Definition KmlLogger.cpp:50
json save() const override
Saves the node into a json object.
Definition KmlLogger.cpp:73
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:45
static std::string category()
String representation of the Class Category.
Definition KmlLogger.cpp:55
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:60
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.
Definition KmlLogger.cpp:99
KmlLogger()
Default constructor.
Definition KmlLogger.cpp:29
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:465
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:522
Node(std::string name)
Constructor.
Definition Node.cpp:29
std::vector< InputPin > inputPins
List of input pins.
Definition Node.hpp:509
std::string nameId() const
Node name and id.
Definition Node.cpp:323
std::string name
Name of the Node.
Definition Node.hpp:507
InputPin * CreateInputPin(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.
Definition Node.cpp:252
bool DeleteInputPin(size_t pinIndex)
Deletes the input pin. Invalidates the pin reference given.
Definition Node.cpp:310
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:525
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
Definition TsDeque.hpp:494
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