diff --git a/file/gate.cpp b/file/gate.cpp index 9f1d6b4..6f43c92 100644 --- a/file/gate.cpp +++ b/file/gate.cpp @@ -6,6 +6,17 @@ namespace file { namespace simdata { + Gate::Gate(std::string designator, + double latitude, + double longitude, + std::uint8_t radius) + { + this->designator = designator; + this->center = {geodata::toRadians(latitude), + geodata::toRadians(longitude)}; + this->radius = radius; + } + Gate::Gate(std::string designator, struct geodata::point center, std::uint8_t radius) diff --git a/file/include/simdata/gate.h b/file/include/simdata/gate.h index 65af654..0dac08b 100644 --- a/file/include/simdata/gate.h +++ b/file/include/simdata/gate.h @@ -21,11 +21,9 @@ namespace file { /* * Representation of gate - * Heading in degrees (0...360) + * Center in lat/lon radians * Radius in metres * - * Designator must be null terminated - * * UINT8 | CHAR[] | POINT | UINT8 * -------+------------+--------+------- * STRLEN | DESIGNATOR | CENTER | RADIUS @@ -38,6 +36,12 @@ namespace file std::uint8_t radius; public: + // From X-Plane or MakeRwys + Gate(std::string designator, + double latitude, + double longitude, + std::uint8_t radius); + // From Database Gate(std::string designator, struct geodata::point center, std::uint8_t radius); @@ -48,8 +52,9 @@ namespace file inline const std::string to_string() const { std::ostringstream str; - str << "Gate " << this->designator << " at " << this->center.latitude - << "N " << this->center.longitude << "E, Radius " + str << "Gate " << this->designator << " at " + << geodata::toDegrees(this->center.latitude) << "N " + << geodata::toDegrees(this->center.longitude) << "E, Radius " << (int)this->radius; return str.str(); } diff --git a/file/include/simdata/runway.h b/file/include/simdata/runway.h index 5423be7..3c46e26 100644 --- a/file/include/simdata/runway.h +++ b/file/include/simdata/runway.h @@ -21,24 +21,22 @@ namespace file { /* * Representation of one runway with supplementary information - * Heading in degrees (0...360) true + * Heading in radians true + * Threshold center in lat/lon radians * Width and length in meters * - * Designator must be null terminated - * - * UINT8 | CHAR[] | BOX | UINT8 | UINT16 | UINT16 + * UINT8 | CHAR[] | POINT | UINT8 | UINT16 | DOUBLE * -------+------------+--------+-------+--------+------- - * STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG + * STRLEN | DESIGNATOR | CENTER | WIDTH | LENGTH | TRUHDG */ class Runway { private: std::string designator; - struct geodata::box bounds; + struct geodata::point center; std::uint8_t width; std::uint16_t length; - std::uint16_t trueHeading; - std::vector file; + double trueHeading; public: // From X-Plane or MakeRwys @@ -50,27 +48,22 @@ namespace file double width); // From database Runway(std::string designator, - struct geodata::box bounds, + struct geodata::point center, std::uint8_t width, std::uint16_t length, - std::uint16_t trueHeading); + double trueHeading); void toFile(std::ofstream &out) const; inline const std::string to_string() const { std::ostringstream str; - str << "Runway " << this->designator << " with bounds " - << this->bounds.topLeft.latitude << "N " - << this->bounds.topLeft.longitude << "E, " - << this->bounds.topRight.latitude << "N " - << this->bounds.topRight.longitude << "E, " - << this->bounds.bottomRight.latitude << "N " - << this->bounds.bottomRight.longitude << "E, " - << this->bounds.bottomLeft.latitude << "N " - << this->bounds.bottomLeft.longitude << "E, " - << "Width " << (int)this->width << "m, Length " << this->length - << "m, True Heading " << this->trueHeading << "°"; + str << "Runway " << this->designator << " with threshold center " + << geodata::toDegrees(this->center.latitude) << "N " + << geodata::toDegrees(this->center.longitude) << "E, Width " + << (int)this->width << "m, Length " << this->length + << "m, True Heading " << geodata::toDegrees(this->trueHeading) + << "°"; return str.str(); } diff --git a/file/runway.cpp b/file/runway.cpp index 5fcbc7c..6349094 100644 --- a/file/runway.cpp +++ b/file/runway.cpp @@ -19,25 +19,22 @@ namespace file longitudeStart, latitudeEnd, longitudeEnd); - this->trueHeading = - (std::uint16_t)std::round(geodata::bearingDD(latitudeStart, - longitudeStart, - latitudeEnd, - longitudeEnd)); - this->bounds = geodata::calculateBoxDD({latitudeStart, longitudeStart}, - {latitudeEnd, longitudeEnd}, - this->trueHeading, - this->width); + this->trueHeading = geodata::bearingDR(latitudeStart, + longitudeStart, + latitudeEnd, + longitudeEnd); + this->center = {geodata::toRadians(latitudeStart), + geodata::toRadians(longitudeStart)}; } Runway::Runway(std::string designator, - geodata::box bounds, + geodata::point center, std::uint8_t width, std::uint16_t length, - std::uint16_t trueHeading) + double trueHeading) { this->designator = designator; - this->bounds = bounds; + this->center = center; this->width = width; this->length = length; this->trueHeading = trueHeading; @@ -46,7 +43,7 @@ namespace file void Runway::toFile(std::ofstream &out) const { writeString(out, this->designator); - writebounds)>(out, this->bounds); + writecenter)>(out, this->center); writewidth)>(out, this->width); writelength)>(out, this->length); writetrueHeading)>(out, this->trueHeading); diff --git a/file/simDatabase.cpp b/file/simDatabase.cpp index cf471cc..c2feb91 100644 --- a/file/simDatabase.cpp +++ b/file/simDatabase.cpp @@ -25,6 +25,8 @@ namespace file toLog("Sim Database updated"); } else { this->fromFile(); + + toLog("Sim Database loaded"); } } @@ -65,14 +67,14 @@ namespace file std::uint8_t numRunways = read(in); for (int j = 0; j < numRunways; j++) { std::string designator = readString(in); - // Bounds - struct geodata::box bounds = read(in); + // Center + struct geodata::point center = read(in); std::uint8_t width = read(in); std::uint16_t length = read(in); - std::uint16_t trueHeading = read(in); + double trueHeading = read(in); this->airports[icao].second.emplace_back(designator, - bounds, + center, width, length, trueHeading); diff --git a/file/simdataXP.cpp b/file/simdataXP.cpp index 46454d3..ecefe16 100644 --- a/file/simdataXP.cpp +++ b/file/simdataXP.cpp @@ -153,10 +153,10 @@ namespace file } gateName += fields.back(); gateName = std::regex_replace(gateName, std::regex{","}, "0"); - struct geodata::point pt { - std::stod(fields[1]), std::stod(fields[2]) - }; - gates.emplace_back(gateName, pt, 40); + gates.emplace_back(gateName, + std::stod(fields[1]), + std::stod(fields[2]), + 40); } void makeRunway(std::vector &runways, @@ -186,10 +186,10 @@ namespace file gateName += fields.back(); gateName = std::regex_replace(gateName, std::regex{","}, "0"); - struct geodata::point pt { - std::stod(fields[1]), std::stod(fields[2]) - }; - gates.emplace_back(gateName, pt, 40); + gates.emplace_back(gateName, + std::stod(fields[1]), + std::stod(fields[2]), + 40); } } // namespace simdata } // namespace file diff --git a/utilities/include/geodata.hpp b/utilities/include/geodata.hpp index a08a8e5..9b7c706 100644 --- a/utilities/include/geodata.hpp +++ b/utilities/include/geodata.hpp @@ -41,11 +41,16 @@ namespace geodata static inline double toRadians(double value) { return value * M_PI / 180; } - static inline double normalize(double value) + static inline double normalizeD(double value) { return fmod(value + 360, 360); } + static inline double normalizeR(double value) + { + return value < 0 ? 2 * M_PI + value : value; + } + // Input and Output in degrees static inline double bearingDD(double fromLatitude, double fromLongitude, @@ -58,7 +63,22 @@ namespace geodata sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) * cos(toRadians(toLongitude) - toRadians(fromLongitude)); - return normalize(toDegrees(atan2(y, x))); + return normalizeD(toDegrees(atan2(y, x))); + } + + // Input in degrees, Output in radians + static inline double bearingDR(double fromLatitude, + double fromLongitude, + double toLatitude, + double toLongitude) + { + double y = sin(toRadians(toLongitude) - toRadians(fromLongitude)) * + cos(toRadians(toLatitude)); + double x = cos(toRadians(fromLatitude)) * sin(toRadians(toLatitude)) - + sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) * + cos(toRadians(toLongitude) - toRadians(fromLongitude)); + + return normalizeR(atan2(y, x)); } // Input in degrees, Output in metres diff --git a/xplugin/main.cpp b/xplugin/main.cpp index aa0454a..0cd7b3d 100644 --- a/xplugin/main.cpp +++ b/xplugin/main.cpp @@ -130,6 +130,19 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc) toLog); } + toLog("Readback test of sim database using EDDF"); + auto ap = (*database)["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"); + auto ap2 = (*database)["XXXX"]; + ap2.first.size() == 0 ? toLog(" SUCCESS") : toLog(" ERROR"); + + // Thread for sending data to websocket serverThread = std::thread(&serverWorker); recordingThread = std::thread(&recordingWorker);