diff --git a/file/gate.cpp b/file/gate.cpp index 818eb6c..34fa46a 100644 --- a/file/gate.cpp +++ b/file/gate.cpp @@ -21,6 +21,12 @@ namespace file writecenter)>(out, this->center); writeradius)>(out, this->radius); } + + bool Gate::contains(germanairlinesva::geodata::point coordinates) const + { + return germanairlinesva::geodata::distanceEarthP(this->center, + coordinates); + } } // namespace simdata } // namespace file } // namespace germanairlinesva \ No newline at end of file diff --git a/file/include/recording/recordingEntry.h b/file/include/recording/recordingEntry.h index e0c2145..2fb1f5e 100644 --- a/file/include/recording/recordingEntry.h +++ b/file/include/recording/recordingEntry.h @@ -24,9 +24,9 @@ namespace file { private: std::uint32_t time; - std::uint16_t altitude; - std::uint16_t groundSpeed; - struct germanairlinesva::geodata::point coordinates; + std::uint16_t altitude = 0; + std::uint16_t groundSpeed = 0; + struct germanairlinesva::geodata::point coordinates{NAN, NAN}; public: RecordingEntry() = default; diff --git a/file/include/simdata/gate.h b/file/include/simdata/gate.h index d6034b2..a839535 100644 --- a/file/include/simdata/gate.h +++ b/file/include/simdata/gate.h @@ -43,6 +43,7 @@ namespace file std::uint8_t radius); void toFile(std::ofstream &out) const; + bool contains(germanairlinesva::geodata::point coordinates) const; inline const std::string to_string() const { diff --git a/file/include/simdata/simDatabase.h b/file/include/simdata/simDatabase.h new file mode 100644 index 0000000..8062bef --- /dev/null +++ b/file/include/simdata/simDatabase.h @@ -0,0 +1,61 @@ +#ifndef GERMANAIRLINESVA_FILE_SIMDATABASE_H +#define GERMANAIRLINESVA_FILE_SIMDATABASE_H + +#include +#include +#include +#include +#include + +#include "geodata.hpp" +#include "helpers.hpp" +#include "simdata/gate.h" +#include "simdata/runway.h" + +namespace germanairlinesva +{ +namespace file +{ + namespace simdata + { + class SimDatabase + { + private: + std::map, std::vector>> + airports; + + public: + void toFile(std::ofstream &out) const; + + const Gate *checkGate( + const std::string icao, + const struct germanairlinesva::geodata::point coordinates) const; + + inline std::size_t numAirports() const { return this->airports.size(); } + inline const std::pair, std::vector> & + getAirport(std::string icao) const + { + return this->airports.at(icao); + } + inline void addAirport(std::string icao, + std::vector &gates, + std::vector &runways) + { + this->airports[icao] = std::make_pair(gates, runways); + } + template + inline void addGate(std::string icao, Args &&...args) + { + this->airports[icao].first.emplace_back(std::forward(args)...); + } + template + inline void addRunway(std::string icao, Args &&...args) + { + this->airports[icao].second.emplace_back(std::forward(args)...); + } + }; + } // namespace simdata +} // namespace file +} // namespace germanairlinesva + +#endif \ No newline at end of file diff --git a/file/include/simdata/simdataXP.h b/file/include/simdata/simdataXP.h index fc3fe0f..6f3ef00 100644 --- a/file/include/simdata/simdataXP.h +++ b/file/include/simdata/simdataXP.h @@ -7,6 +7,7 @@ #include "simdata/gate.h" #include "simdata/runway.h" +#include "simdata/simDatabase.h" #include "util.hpp" namespace germanairlinesva @@ -15,19 +16,15 @@ namespace file { namespace simdata { - int scan( - const std::string defaultFile, - const std::string sceneryPack, - const std::string logFile, - std::map, std::vector>> - &airports); + int scan(const std::string defaultFile, + const std::string sceneryPack, + const std::string logFile, + SimDatabase &airports); - void makeAirport( - const std::string &kind, - std::ifstream &infile, - std::map, std::vector>> - &airports, - std::ofstream &logfile); + void makeAirport(const std::string &kind, + std::ifstream &infile, + SimDatabase &airports, + std::ofstream &logfile); void makeGate15(std::vector &gates, const std::vector &fields); void makeRunway(std::vector &runways, diff --git a/file/include/simdata/simulatorDatabase.hpp b/file/include/simdata/simulatorDatabase.hpp index 86dcc37..dd977b0 100644 --- a/file/include/simdata/simulatorDatabase.hpp +++ b/file/include/simdata/simulatorDatabase.hpp @@ -11,6 +11,7 @@ #include "simdata/gate.h" #include "simdata/runway.h" +#include "simdata/simDatabase.h" /* * Header @@ -33,92 +34,41 @@ namespace file { namespace simdata { - static inline void toFile( - std::map< - std::string, - std::pair, - std::vector>> - &airports, - const std::string &file) + static inline void toFile(const SimDatabase &database, + const std::string &file) { - std::uint8_t null = 0; std::ofstream out(file, std::fstream::binary); // File Header, Last member is version std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1}; out.write(reinterpret_cast(header), 6); - // Num Airports - std::uint16_t numAirports = airports.size(); - out.write(reinterpret_cast(&numAirports), - sizeof(numAirports)); - // Airport - for (const std::pair< - const std::string, - std::pair, - std::vector>> - &airport : airports) { - std::string icao = airport.first; - std::vector gates = - airport.second.first; - std::vector runways = - airport.second.second; - // ICAO - std::uint8_t icaoLength = icao.length(); - out.write(reinterpret_cast(&icaoLength), - sizeof(icaoLength)); - out.write(icao.c_str(), icaoLength); - out.write(reinterpret_cast(&null), sizeof(null)); - // Gates - std::uint16_t numGates = gates.size(); - out.write(reinterpret_cast(&numGates), sizeof(numGates)); - for (germanairlinesva::file::simdata::Gate &gate : gates) { - gate.toFile(out); - } - // Runways - std::uint8_t numRunways = runways.size(); - out.write(reinterpret_cast(&numRunways), - sizeof(numRunways)); - for (germanairlinesva::file::simdata::Runway &runway : runways) { - runway.toFile(out); - } - } + + database.toFile(out); + out.close(); } - static inline std::map< - std::string, - std::pair, - std::vector>> - readVersion1(std::ifstream &in) + static inline const SimDatabase readVersion1(std::ifstream &in) { - std::map, - std::vector>> - airports; + SimDatabase database; - std::uint16_t numAirports; - in.read(reinterpret_cast(&numAirports), sizeof(numAirports)); + std::uint16_t numAirports = read(in); for (int i = 0; i < numAirports; i++) { // ICAO - std::uint8_t icaoLength; - in.read(reinterpret_cast(&icaoLength), sizeof(icaoLength)); - char *icao = static_cast(calloc(icaoLength + 1, sizeof(char))); - in.read(icao, icaoLength + 1); + std::string icao = readString(in); // Gates - std::uint16_t numGates; - in.read(reinterpret_cast(&numGates), sizeof(numGates)); + std::uint16_t numGates = read(in); for (int j = 0; j < numGates; j++) { std::string designator = readString(in); struct germanairlinesva::geodata::point center = read(in); std::uint8_t radius = read(in); - airports[icao].first.emplace_back(designator, center, radius); + database.addGate(icao, designator, center, radius); } // Runways - std::uint8_t numRunways; - in.read(reinterpret_cast(&numRunways), sizeof(numRunways)); + std::uint8_t numRunways = read(in); for (int j = 0; j < numRunways; j++) { std::string designator = readString(in); // Bounds @@ -128,29 +78,18 @@ namespace file std::uint16_t length = read(in); std::uint16_t trueHeading = read(in); - airports[icao].second.emplace_back(designator, - bounds, - width, - length, - trueHeading); + database + .addRunway(icao, designator, bounds, width, length, trueHeading); } } in.close(); - return airports; + return database; } - static inline std::map< - std::string, - std::pair, - std::vector>> - fromFile(const std::string &file) + static inline const SimDatabase fromFile(const std::string &file) { - std::map, - std::vector>> - airports; std::ifstream in(file, std::ifstream::binary); // File Header @@ -159,13 +98,14 @@ namespace file if (strcmp(ident, "VGAS") != 0) { throw std::invalid_argument("Wrong file"); } - std::uint8_t version; - in.read(reinterpret_cast(&version), 1); + std::uint8_t version = read(in); if (version == 1) { return readVersion1(in); } - return airports; + + in.close(); + return SimDatabase(); } } // namespace simdata } // namespace file diff --git a/file/simDatabase.cpp b/file/simDatabase.cpp new file mode 100644 index 0000000..275d754 --- /dev/null +++ b/file/simDatabase.cpp @@ -0,0 +1,39 @@ +#include "simdata/simDatabase.h" + +namespace germanairlinesva +{ +namespace file +{ + namespace simdata + { + void SimDatabase::toFile(std::ofstream &out) const + { + write(out, this->airports.size()); + for (const auto &airport : this->airports) { + writeString(out, airport.first); + write(out, airport.second.first.size()); + for (const Gate &gate : airport.second.first) { + gate.toFile(out); + } + write(out, airport.second.second.size()); + for (const Runway &runway : airport.second.second) { + runway.toFile(out); + } + } + } + + const Gate *SimDatabase::checkGate( + const std::string icao, + const struct germanairlinesva::geodata::point coordinates) const + { + auto airport = this->getAirport(icao); + for (const Gate &gate : airport.first) { + if (gate.contains(coordinates)) { + return &gate; + } + } + return nullptr; + } + } // namespace simdata +} // namespace file +} // namespace germanairlinesva \ No newline at end of file diff --git a/file/simdataXP.cpp b/file/simdataXP.cpp index dfdd8d4..76df09b 100644 --- a/file/simdataXP.cpp +++ b/file/simdataXP.cpp @@ -6,12 +6,10 @@ namespace file { namespace simdata { - int scan( - const std::string defaultFile, - const std::string sceneryPack, - const std::string logFile, - std::map, std::vector>> - &airports) + int scan(const std::string defaultFile, + const std::string sceneryPack, + const std::string logFile, + SimDatabase &database) { std::ifstream base(defaultFile); if (!base.good()) { @@ -31,7 +29,7 @@ namespace file // Default logfile << " " << defaultFile << std::endl; - makeAirport("DEFAULT", base, airports, logfile); + makeAirport("DEFAULT", base, database, logfile); base.close(); std::string line; @@ -51,7 +49,7 @@ namespace file std::ifstream pack(path); if (pack.good()) { logfile << " " << path << std::endl; - makeAirport("CUSTOM", pack, airports, logfile); + makeAirport("CUSTOM", pack, database, logfile); pack.close(); } else { pack.close(); @@ -61,19 +59,18 @@ namespace file } logfile << std::endl - << " Total airports: " << airports.size() << std::endl; + << " Total airports: " << database.numAirports() + << std::endl; custom.close(); logfile.close(); return 0; } - void makeAirport( - const std::string &kind, - std::ifstream &infile, - std::map, std::vector>> - &airports, - std::ofstream &logfile) + void makeAirport(const std::string &kind, + std::ifstream &infile, + SimDatabase &database, + std::ofstream &logfile) { std::string line; std::string *currentIcao = nullptr; @@ -96,7 +93,7 @@ namespace file // Write to file if ICAO is valid, and we have gates and runways if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) { - airports[*currentIcao] = {tmpGates, tmpRunways}; + database.addAirport(*currentIcao, tmpGates, tmpRunways); validCount += 1; logfile << "\t " << *currentIcao << " committed" << std::endl; @@ -116,7 +113,7 @@ namespace file // Write to file if ICAO is valid, and we have gates and runways if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) { - airports[*currentIcao] = {tmpGates, tmpRunways}; + database.addAirport(*currentIcao, tmpGates, tmpRunways); validCount += 1; logfile << "\t " << *currentIcao << " committed" << std::endl; @@ -138,7 +135,7 @@ namespace file } if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) { - airports[*currentIcao] = {tmpGates, tmpRunways}; + database.addAirport(*currentIcao, tmpGates, tmpRunways); validCount += 1; logfile << "\t " << *currentIcao << " committed" << std::endl; } diff --git a/utilities/include/geodata.hpp b/utilities/include/geodata.hpp index 4787428..a08a8e5 100644 --- a/utilities/include/geodata.hpp +++ b/utilities/include/geodata.hpp @@ -77,6 +77,19 @@ namespace geodata return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v)); } + // Input in degrees, Output in metres + static inline double distanceEarthP(point from, point to) + { + double lat1r, lon1r, lat2r, lon2r, u, v; + lat1r = toRadians(from.latitude); + lon1r = toRadians(from.longitude); + lat2r = toRadians(to.latitude); + lon2r = toRadians(to.longitude); + u = sin((lat2r - lat1r) / 2); + v = sin((lon2r - lon1r) / 2); + return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v)); + } + // Input and Output in degrees static inline struct point calculatePointDD(struct point coordinates, double bearing, diff --git a/websocket/websocket.cpp b/websocket/websocket.cpp index 31a5504..c4ad940 100644 --- a/websocket/websocket.cpp +++ b/websocket/websocket.cpp @@ -49,7 +49,7 @@ void Websocket::onClientMessageCallback(const ix::WebSocketMessagePtr &msg) this->webSocket->send("MASTER:" + user); this->toLog("Connecting as " + user); } else if (msg->type == ix::WebSocketMessageType::Close) { - if (msg->closeInfo.reason.compare("DUPLICATE")) { + if (msg->closeInfo.reason.compare("DUPLICATE") == 0) { this->webSocket->disableAutomaticReconnection(); this->toLog("Disconnected due to beeing a duplicate simualtor"); diff --git a/xplugin/main.cpp b/xplugin/main.cpp index d73862d..ac851b5 100644 --- a/xplugin/main.cpp +++ b/xplugin/main.cpp @@ -11,10 +11,7 @@ std::thread recordingThread; std::atomic wantsExit; germanairlinesva::file::config::Config configuration; -std::map, - std::vector>> - airports; +germanairlinesva::file::simdata::SimDatabase database; germanairlinesva_websocket::Websocket *connector; int xplaneVersion; @@ -116,18 +113,18 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc) configuration = germanairlinesva::file::config::Config(); toLog("Config loaded"); - - try { - connector = new germanairlinesva_websocket::Websocket( - "wss://ws.hofmannnet.myhome-server.de:8000", - configuration.getUser(), - toLog); - } catch (const std::invalid_argument &e) { - toLog(e.what()); - return 0; - } - toLog("WebSocket started"); - + /* + try { + connector = new germanairlinesva_websocket::Websocket( + "wss://ws.hofmannnet.myhome-server.de:8000", + configuration.getUser(), + toLog); + } catch (const std::invalid_argument &e) { + toLog(e.what()); + return 0; + } + toLog("WebSocket started"); + */ char hash[2 * MD5LEN + 1] = ""; if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) == 0) { @@ -139,32 +136,42 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc) : XPLANE12_BASE_SCENERY, XPLANE_CUSTOM_SCENERY, XPLANE_PLUGIN_DIRECTORY "log.txt", - airports); + database); germanairlinesva::file::simdata::toFile( - airports, + database, XPLANE_PLUGIN_DIRECTORY SIMDATABASE); configuration.updateScenery(hash); toLog("Sim Database updated"); } else { - airports = germanairlinesva::file::simdata::fromFile( + database = germanairlinesva::file::simdata::fromFile( XPLANE_PLUGIN_DIRECTORY SIMDATABASE); toLog("Sim Database loaded"); } + toLog("Binary readback test"); + germanairlinesva::file::simdata::toFile(database, + XPLANE_PLUGIN_DIRECTORY "sim2.bin"); toLog("Readback test of sim database using EDDF"); - auto ap = airports["EDDF"]; + auto ap = database.getAirport("EDDF"); for (const auto &it : ap.first) { toLog(" " + it.to_string()); } for (const auto &it : ap.second) { toLog(" " + it.to_string()); } + toLog("Readback test of sim database using XXXX"); + try { + ap = database.getAirport("XXXX"); + toLog(" Return was non null ! ERROR"); + } catch (std::out_of_range) { + toLog(" Return was null"); + } } // Thread for sending data to websocket - serverThread = std::thread(&serverWorker); - recordingThread = std::thread(&recordingWorker); + // serverThread = std::thread(&serverWorker); + // recordingThread = std::thread(&recordingWorker); toLog("Workers started"); toLog("Logbook Test"); @@ -209,11 +216,13 @@ PLUGIN_API void XPluginStop(void) XPLMUnregisterFlightLoopCallback(flightLoop, nullptr); /* End threads */ wantsExit = true; - delete connector; - serverThread.join(); - recordingThread.join(); + // serverThread.join(); + // recordingThread.join(); + // delete connector; p.toFile("flight.rec"); + + toLog("Plugin stopped"); } PLUGIN_API void XPluginDisable(void) {} @@ -286,6 +295,8 @@ void serverWorker() std::this_thread::sleep_for(std::chrono::milliseconds(250)); } + + toLog("Server thread stopped"); } void recordingWorker() @@ -318,6 +329,8 @@ void recordingWorker() std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } + + toLog("Recording thread stopped"); } void toLog(const std::string &message)