#ifndef GERMANAIRLINESVA_FILE_RUNWAY_H #define GERMANAIRLINESVA_FILE_RUNWAY_H #include #include #include #include #include #include #include #include "geodata.hpp" #include "helpers.hpp" #include "util.hpp" namespace germanairlinesva { namespace file { namespace simdata { /* * Representation of one runway with supplementary information * Heading in degrees true * Threshold center in lat/lon degrees * Width and length in metres * * UINT8 | CHAR[] | BOX | UINT8 | UINT16 | DOUBLE * -------+------------+--------+-------+--------+------- * STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG */ class Runway { private: std::string designator; struct geodata::box bounds; std::uint8_t width; std::uint16_t length; double trueHeading; public: // From X-Plane or MakeRwys inline Runway(std::string designator, double latitudeStart, double longitudeStart, double latitudeEnd, double longitudeEnd, double width) : designator(designator), width(width) { this->length = geodata::distanceEarthD(latitudeStart, longitudeStart, latitudeEnd, longitudeEnd); this->trueHeading = geodata::bearingDD(latitudeStart, longitudeStart, latitudeEnd, longitudeEnd); this->bounds = geodata::calculateBoxDD({latitudeStart, longitudeStart}, {latitudeEnd, longitudeEnd}, this->trueHeading, this->width); }; // From database inline Runway(std::string designator, struct geodata::box bounds, std::uint8_t width, std::uint16_t length, double trueHeading) : designator(designator), bounds(bounds), width(width), length(length), trueHeading(trueHeading){}; inline bool containsPoint(geodata::point point) { bool flag = false; double udegrees1 = this->bounds.topRight.latitude + 90; double udegrees2 = this->bounds.bottomLeft.latitude + 90; double udegrees3 = this->bounds.topLeft.latitude + 90; double udegrees4 = this->bounds.bottomRight.latitude + 90; double udegrees5 = this->bounds.topRight.longitude + 180; double udegrees6 = this->bounds.bottomLeft.longitude + 180; double udegrees7 = this->bounds.topLeft.longitude + 180; double udegrees8 = this->bounds.bottomRight.longitude + 180; double udegrees9 = point.longitude + 180; double udegrees10 = point.latitude + 90; if (udegrees9 > udegrees5 + (udegrees6 - udegrees5) / (udegrees1 - udegrees2) * (udegrees1 - udegrees10) && udegrees9 < udegrees8 + (udegrees7 - udegrees8) / (udegrees4 - udegrees3) * (udegrees4 - udegrees10) && udegrees10 > udegrees2 + (udegrees3 - udegrees2) / (udegrees7 - udegrees6) * (udegrees9 - udegrees6)) flag = udegrees10 < udegrees1 + (udegrees4 - udegrees1) / (udegrees8 - udegrees5) * (udegrees9 - udegrees5); return flag; } inline void toFile(std::ofstream &out) const { writeString(out, this->designator); writebounds)>(out, this->bounds); writewidth)>(out, this->width); writelength)>(out, this->length); writetrueHeading)>(out, this->trueHeading); } 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 << "°"; return str.str(); } friend inline std::ostream &operator<<(std::ostream &os, const Runway &runway) { return os << runway.to_string(); } }; } // namespace simdata } // namespace file } // namespace germanairlinesva #endif