Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92159b0669 | |||
| 115e4d9265 | |||
| 07487e9e51 | |||
| 46a0607b55 | |||
| de8b282ab1 | |||
| 6027095c38 | |||
| 2cf03d2933 |
Vendored
+23
-1
@@ -63,6 +63,28 @@
|
|||||||
"thread": "cpp",
|
"thread": "cpp",
|
||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"valarray": "cpp"
|
"valarray": "cpp",
|
||||||
|
"__threading_support": "cpp",
|
||||||
|
"__bit_reference": "cpp",
|
||||||
|
"__bits": "cpp",
|
||||||
|
"__config": "cpp",
|
||||||
|
"__debug": "cpp",
|
||||||
|
"__errc": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__locale": "cpp",
|
||||||
|
"__mutex_base": "cpp",
|
||||||
|
"__node_handle": "cpp",
|
||||||
|
"__nullptr": "cpp",
|
||||||
|
"__split_buffer": "cpp",
|
||||||
|
"__string": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"__tuple": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"locale": "cpp",
|
||||||
|
"queue": "cpp",
|
||||||
|
"stack": "cpp",
|
||||||
|
"variant": "cpp"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,2 @@
|
|||||||
- Reverse engineer FSUIPC .NET onRunway Check
|
|
||||||
- Update OSXCross Docker image to SDK 11
|
- Update OSXCross Docker image to SDK 11
|
||||||
- Implement ARM64 arch for Plugin
|
- Implement ARM64 arch for Plugin
|
||||||
- Refactor SimDatabase to be a class
|
|
||||||
- Requires new Airport class
|
|
||||||
@@ -17,11 +17,15 @@ case $1 in
|
|||||||
;;
|
;;
|
||||||
"win32")
|
"win32")
|
||||||
cmake -DDEBUG=$DEBUG -DBIT=32 -DCMAKE_TOOLCHAIN_FILE=../toolchain-win-32.cmake ..
|
cmake -DDEBUG=$DEBUG -DBIT=32 -DCMAKE_TOOLCHAIN_FILE=../toolchain-win-32.cmake ..
|
||||||
|
\cp -rf ../openSSL/win32/*.dll ESP/GAConnector/
|
||||||
|
\cp -rf /opt/llvm-mingw/i686-w64-mingw32/bin/libc++.dll ESP/GAConnector/
|
||||||
|
\cp -rf /opt/llvm-mingw/i686-w64-mingw32/bin/libunwind.dll ESP/GAConnector/
|
||||||
;;
|
;;
|
||||||
"win64")
|
"win64")
|
||||||
cmake -DDEBUG=$DEBUG -DBIT=64 -DCMAKE_TOOLCHAIN_FILE=../toolchain-win-64.cmake ..
|
cmake -DDEBUG=$DEBUG -DBIT=64 -DCMAKE_TOOLCHAIN_FILE=../toolchain-win-64.cmake ..
|
||||||
\cp -rf ../openSSL/win64/*.dll X-Plane/GAConnector/64/
|
\cp -rf ../openSSL/win64/*.dll X-Plane/GAConnector/64/
|
||||||
\cp -rf ../openSSL/win64/*.dll ESP/GAConnector/
|
\cp -rf /opt/llvm-mingw/x86_64-w64-mingw32/bin/libc++.dll X-Plane/GAConnector/64
|
||||||
|
\cp -rf /opt/llvm-mingw/x86_64-w64-mingw32/bin/libunwind.dll X-Plane/GAConnector/64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
@@ -81,8 +81,4 @@ elseif(WIN32)
|
|||||||
-Wl,-pdb=
|
-Wl,-pdb=
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
target_link_options(file PRIVATE
|
|
||||||
-static-libgcc
|
|
||||||
-static-libstdc++
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
+3
-4
@@ -20,11 +20,10 @@ namespace file
|
|||||||
std::ifstream in(XPLANE_PLUGIN_DIRECTORY CONFIG);
|
std::ifstream in(XPLANE_PLUGIN_DIRECTORY CONFIG);
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(in, line)) {
|
while (std::getline(in, line)) {
|
||||||
std::vector<std::string> fields =
|
std::vector<std::string> fields = util::split(line, '=');
|
||||||
germanairlinesva::util::split(line, '=');
|
|
||||||
if (fields.size() >= 2) {
|
if (fields.size() >= 2) {
|
||||||
germanairlinesva::util::trim(fields[0]);
|
util::trim(fields[0]);
|
||||||
germanairlinesva::util::trim(fields[1]);
|
util::trim(fields[1]);
|
||||||
if (fields[0] == "scenery") {
|
if (fields[0] == "scenery") {
|
||||||
this->scenery = fields[1];
|
this->scenery = fields[1];
|
||||||
} else if (fields[0] == "user") {
|
} else if (fields[0] == "user") {
|
||||||
|
|||||||
+14
-4
@@ -7,7 +7,18 @@ namespace file
|
|||||||
namespace simdata
|
namespace simdata
|
||||||
{
|
{
|
||||||
Gate::Gate(std::string designator,
|
Gate::Gate(std::string designator,
|
||||||
struct germanairlinesva::geodata::point center,
|
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)
|
std::uint8_t radius)
|
||||||
{
|
{
|
||||||
this->designator = designator;
|
this->designator = designator;
|
||||||
@@ -22,10 +33,9 @@ namespace file
|
|||||||
write<decltype(this->radius)>(out, this->radius);
|
write<decltype(this->radius)>(out, this->radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gate::contains(germanairlinesva::geodata::point coordinates) const
|
bool Gate::contains(geodata::point coordinates) const
|
||||||
{
|
{
|
||||||
return germanairlinesva::geodata::distanceEarthP(this->center,
|
return geodata::distanceEarthP(this->center, coordinates);
|
||||||
coordinates);
|
|
||||||
}
|
}
|
||||||
} // namespace simdata
|
} // namespace simdata
|
||||||
} // namespace file
|
} // namespace file
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSGEODATA_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSGEODATA_H
|
||||||
|
|
||||||
|
#include "FsLatLonPoint.h"
|
||||||
|
#include "FsLatLonQuadrilateral.h"
|
||||||
|
#include "FsLatitude.h"
|
||||||
|
#include "FsLatitudeSpan.h"
|
||||||
|
#include "FsLongitude.h"
|
||||||
|
#include "FsLongitudeSpan.h"
|
||||||
|
|
||||||
|
#include "FsLatLonPointImpl.h"
|
||||||
|
#include "FsLatLonQuadrilateralImpl.h"
|
||||||
|
#include "FsLatitudeImpl.h"
|
||||||
|
#include "FsLatitudeSpanImpl.h"
|
||||||
|
#include "FsLongitudeImpl.h"
|
||||||
|
#include "FsLongitudeSpanImpl.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONPOINT_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONPOINT_H
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "FsLatitude.h"
|
||||||
|
#include "FsLatitudeSpan.h"
|
||||||
|
#include "FsLongitude.h"
|
||||||
|
#include "FsLongitudeSpan.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLatLonPoint
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FsLatitude lat;
|
||||||
|
FsLongitude lon;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLatLonPoint();
|
||||||
|
inline FsLatLonPoint(FsLatitude Latitude, FsLongitude Longitude);
|
||||||
|
|
||||||
|
inline const FsLongitude Longitude() const;
|
||||||
|
inline const FsLatitude Latitude() const;
|
||||||
|
|
||||||
|
inline double DistanceFromInFeet(const FsLatLonPoint &Point) const;
|
||||||
|
inline double
|
||||||
|
DistanceFromInNauticalMiles(const FsLatLonPoint &Point) const;
|
||||||
|
inline double DistanceFromInMetres(const FsLatLonPoint &Point) const;
|
||||||
|
|
||||||
|
inline double BearingTo(const FsLatLonPoint &Point) const;
|
||||||
|
inline double BearingFrom(const FsLatLonPoint &Point) const;
|
||||||
|
|
||||||
|
inline FsLatLonPoint OffsetByFeet(double Bearing,
|
||||||
|
double Distance) const;
|
||||||
|
inline FsLatLonPoint OffsetByMetres(double Bearing,
|
||||||
|
double Distance) const;
|
||||||
|
inline FsLatLonPoint OffsetByNauticalMiles(double Bearing,
|
||||||
|
double Distance) const;
|
||||||
|
|
||||||
|
inline const std::string to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const;
|
||||||
|
inline const std::string to_string() const;
|
||||||
|
};
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONPOINTIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONPOINTIMPL_H
|
||||||
|
|
||||||
|
#include "FsLatLonPoint.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLatLonPoint::FsLatLonPoint() = default;
|
||||||
|
inline FsLatLonPoint::FsLatLonPoint(FsLatitude Latitude,
|
||||||
|
FsLongitude Longitude)
|
||||||
|
{
|
||||||
|
this->lon = Longitude;
|
||||||
|
this->lat = Latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const FsLongitude FsLatLonPoint::Longitude() const
|
||||||
|
{
|
||||||
|
return this->lon;
|
||||||
|
}
|
||||||
|
inline const FsLatitude FsLatLonPoint::Latitude() const
|
||||||
|
{
|
||||||
|
return this->lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
FsLatLonPoint::DistanceFromInFeet(const FsLatLonPoint &Point) const
|
||||||
|
{
|
||||||
|
FsLongitudeSpan fsLongitudeSpan =
|
||||||
|
FsLongitudeSpan::BetweenTwoLongitudes(Point.Longitude(), this->lon);
|
||||||
|
double num = (fsLongitudeSpan.ToFeet(this->lat) +
|
||||||
|
fsLongitudeSpan.ToFeet(Point.lat)) /
|
||||||
|
2.0;
|
||||||
|
double feet = FsLatitudeSpan(Point.Latitude().DecimalDegrees() -
|
||||||
|
this->lat.DecimalDegrees())
|
||||||
|
.ToFeet();
|
||||||
|
return sqrt(num * num + feet * feet);
|
||||||
|
}
|
||||||
|
inline double FsLatLonPoint::DistanceFromInNauticalMiles(
|
||||||
|
const FsLatLonPoint &Point) const
|
||||||
|
{
|
||||||
|
return this->DistanceFromInFeet(Point) / 6076.1155;
|
||||||
|
}
|
||||||
|
inline double
|
||||||
|
FsLatLonPoint::DistanceFromInMetres(const FsLatLonPoint &Point) const
|
||||||
|
{
|
||||||
|
return this->DistanceFromInFeet(Point) / 3.2808;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatLonPoint::BearingTo(const FsLatLonPoint &Point) const
|
||||||
|
{
|
||||||
|
double num1 = 0.0;
|
||||||
|
double num2 = abs(FsLatitudeSpan(this->lat.DecimalDegrees() -
|
||||||
|
Point.Latitude().DecimalDegrees())
|
||||||
|
.ToFeet());
|
||||||
|
double num3 = abs((FsLongitudeSpan(Point.Longitude().DecimalDegrees() -
|
||||||
|
this->lon.DecimalDegrees())
|
||||||
|
.ToFeet(this->lat) +
|
||||||
|
FsLongitudeSpan(Point.Longitude().DecimalDegrees() -
|
||||||
|
this->lon.DecimalDegrees())
|
||||||
|
.ToFeet(Point.lat)) /
|
||||||
|
2.0);
|
||||||
|
if (num2 == 0.0)
|
||||||
|
num1 = this->lon.DecimalDegrees() > Point.Longitude().DecimalDegrees()
|
||||||
|
? 270.0
|
||||||
|
: 90.0;
|
||||||
|
else if (this->lat.DecimalDegrees() < Point.Latitude().DecimalDegrees() &&
|
||||||
|
this->lon.DecimalDegrees() < Point.Longitude().DecimalDegrees())
|
||||||
|
num1 = atan(num3 / num2) * 180.0 / M_PI;
|
||||||
|
else if (this->lat.DecimalDegrees() > Point.Latitude().DecimalDegrees() &&
|
||||||
|
this->lon.DecimalDegrees() < Point.Longitude().DecimalDegrees())
|
||||||
|
num1 = atan(num2 / num3) * 180.0 / M_PI + 90.0;
|
||||||
|
else if (this->lat.DecimalDegrees() > Point.Latitude().DecimalDegrees() &&
|
||||||
|
this->lon.DecimalDegrees() > Point.Longitude().DecimalDegrees())
|
||||||
|
num1 = atan(num3 / num2) * 180.0 / M_PI + 180.0;
|
||||||
|
else if (this->lat.DecimalDegrees() < Point.Latitude().DecimalDegrees() &&
|
||||||
|
this->lon.DecimalDegrees() > Point.Longitude().DecimalDegrees())
|
||||||
|
num1 = atan(num2 / num3) * 180.0 / M_PI + 270.0;
|
||||||
|
return num1;
|
||||||
|
}
|
||||||
|
inline double FsLatLonPoint::BearingFrom(const FsLatLonPoint &Point) const
|
||||||
|
{
|
||||||
|
double num = 180.0 + this->BearingTo(Point);
|
||||||
|
if (num >= 360.0)
|
||||||
|
num -= 360.0;
|
||||||
|
if (num < 0.0)
|
||||||
|
num += 360.0;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatLonPoint FsLatLonPoint::OffsetByFeet(double Bearing,
|
||||||
|
double Distance) const
|
||||||
|
{
|
||||||
|
double Feet1 = sin(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
double Feet2 = cos(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
FsLatLonPoint fsLatLonPoint = FsLatLonPoint();
|
||||||
|
fsLatLonPoint.lat = this->lat.Add(FsLatitudeSpan::FromFeet(Feet2));
|
||||||
|
fsLatLonPoint.lon =
|
||||||
|
this->lon.Add(FsLongitudeSpan::FromFeet(Feet1, fsLatLonPoint.lat));
|
||||||
|
return fsLatLonPoint;
|
||||||
|
}
|
||||||
|
inline FsLatLonPoint FsLatLonPoint::OffsetByMetres(double Bearing,
|
||||||
|
double Distance) const
|
||||||
|
{
|
||||||
|
double Metres1 = sin(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
double Metres2 = cos(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
FsLatLonPoint fsLatLonPoint = FsLatLonPoint();
|
||||||
|
fsLatLonPoint.lat = this->lat.Add(FsLatitudeSpan::FromMetres(Metres2));
|
||||||
|
fsLatLonPoint.lon = this->lon.Add(
|
||||||
|
FsLongitudeSpan::FromMetres(Metres1, fsLatLonPoint.lat));
|
||||||
|
return fsLatLonPoint;
|
||||||
|
}
|
||||||
|
inline FsLatLonPoint
|
||||||
|
FsLatLonPoint::OffsetByNauticalMiles(double Bearing,
|
||||||
|
double Distance) const
|
||||||
|
{
|
||||||
|
double NauticalMiles1 = sin(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
double NauticalMiles2 = cos(M_PI * Bearing / 180.0) * Distance;
|
||||||
|
FsLatLonPoint fsLatLonPoint = FsLatLonPoint();
|
||||||
|
fsLatLonPoint.lat =
|
||||||
|
this->lat.Add(FsLatitudeSpan::FromNauticalMiles(NauticalMiles2));
|
||||||
|
fsLatLonPoint.lon =
|
||||||
|
this->lon.Add(FsLongitudeSpan::FromNauticalMiles(NauticalMiles1,
|
||||||
|
fsLatLonPoint.lat));
|
||||||
|
return fsLatLonPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::string FsLatLonPoint::to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const
|
||||||
|
{
|
||||||
|
return this->lat.to_string(HemisphereAsText, DetailLevel) + ", " +
|
||||||
|
this->lon.to_string(HemisphereAsText, DetailLevel);
|
||||||
|
}
|
||||||
|
inline const std::string FsLatLonPoint::to_string() const
|
||||||
|
{
|
||||||
|
return this->to_string(true, 'm');
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONQUADRILATERAL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONQUADRILATERAL_H
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLatitude;
|
||||||
|
class FsLatitudeSpan;
|
||||||
|
class FsLongitude;
|
||||||
|
class FsLongitudeSpan;
|
||||||
|
class FsLatLonPoint;
|
||||||
|
class FsLatLonQuadrilateral
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FsLatLonPoint ne;
|
||||||
|
FsLatLonPoint se;
|
||||||
|
FsLatLonPoint sw;
|
||||||
|
FsLatLonPoint nw;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLatLonQuadrilateral();
|
||||||
|
inline FsLatLonQuadrilateral(FsLatLonPoint P0,
|
||||||
|
FsLatLonPoint P1,
|
||||||
|
FsLatLonPoint P2,
|
||||||
|
FsLatLonPoint P3);
|
||||||
|
|
||||||
|
inline FsLatLonPoint NE() const;
|
||||||
|
inline FsLatLonPoint SE() const;
|
||||||
|
inline FsLatLonPoint SW() const;
|
||||||
|
inline FsLatLonPoint NW() const;
|
||||||
|
|
||||||
|
inline bool ContainsPoint(FsLatLonPoint point) const;
|
||||||
|
|
||||||
|
inline const std::string to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const;
|
||||||
|
inline const std::string to_string() const;
|
||||||
|
|
||||||
|
inline static FsLatLonQuadrilateral
|
||||||
|
ForRunway(FsLatLonPoint &ThresholdCentre,
|
||||||
|
double HeadingTrue,
|
||||||
|
double WidthInFeet,
|
||||||
|
double LengthInFeet);
|
||||||
|
};
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONQUADRILATERALIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATLONQUADRILATERALIMPL_H
|
||||||
|
|
||||||
|
#include "FsLatLonQuadrilateral.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLatLonQuadrilateral::FsLatLonQuadrilateral() = default;
|
||||||
|
inline FsLatLonQuadrilateral::FsLatLonQuadrilateral(FsLatLonPoint P0,
|
||||||
|
FsLatLonPoint P1,
|
||||||
|
FsLatLonPoint P2,
|
||||||
|
FsLatLonPoint P3)
|
||||||
|
{
|
||||||
|
std::vector<FsLatLonPoint> fsLatLonPointList1;
|
||||||
|
std::vector<FsLatLonPoint> fsLatLonPointList2;
|
||||||
|
fsLatLonPointList1.push_back(P0);
|
||||||
|
fsLatLonPointList1.push_back(P1);
|
||||||
|
fsLatLonPointList1.push_back(P2);
|
||||||
|
fsLatLonPointList1.push_back(P3);
|
||||||
|
for (int index1 = 0; index1 < 3; ++index1) {
|
||||||
|
double num = 0.0;
|
||||||
|
int index2 = 0;
|
||||||
|
for (size_t index3 = 0; index3 < fsLatLonPointList1.size(); ++index3) {
|
||||||
|
if (fsLatLonPointList1[index3].Latitude().UDegrees() > num) {
|
||||||
|
num = fsLatLonPointList1[index3].Latitude().UDegrees();
|
||||||
|
index2 = index3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fsLatLonPointList2.push_back(fsLatLonPointList1[index2]);
|
||||||
|
fsLatLonPointList1.erase(fsLatLonPointList1.begin() + index2);
|
||||||
|
}
|
||||||
|
fsLatLonPointList2.push_back(fsLatLonPointList1[0]);
|
||||||
|
if (fsLatLonPointList2[1].Longitude().UDegrees() >
|
||||||
|
fsLatLonPointList2[0].Longitude().UDegrees()) {
|
||||||
|
this->ne = fsLatLonPointList2[1];
|
||||||
|
this->nw = fsLatLonPointList2[0];
|
||||||
|
} else {
|
||||||
|
this->ne = fsLatLonPointList2[0];
|
||||||
|
this->nw = fsLatLonPointList2[1];
|
||||||
|
}
|
||||||
|
if (fsLatLonPointList2[3].Longitude().UDegrees() >
|
||||||
|
fsLatLonPointList2[2].Longitude().UDegrees()) {
|
||||||
|
this->se = fsLatLonPointList2[3];
|
||||||
|
this->sw = fsLatLonPointList2[2];
|
||||||
|
} else {
|
||||||
|
this->se = fsLatLonPointList2[2];
|
||||||
|
this->sw = fsLatLonPointList2[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatLonPoint FsLatLonQuadrilateral::NE() const { return this->ne; }
|
||||||
|
inline FsLatLonPoint FsLatLonQuadrilateral::SE() const { return this->se; }
|
||||||
|
inline FsLatLonPoint FsLatLonQuadrilateral::SW() const { return this->sw; }
|
||||||
|
inline FsLatLonPoint FsLatLonQuadrilateral::NW() const { return this->nw; }
|
||||||
|
|
||||||
|
inline bool FsLatLonQuadrilateral::ContainsPoint(FsLatLonPoint point) const
|
||||||
|
{
|
||||||
|
bool flag = false;
|
||||||
|
double udegrees1 = this->nw.Latitude().UDegrees();
|
||||||
|
double udegrees2 = this->sw.Latitude().UDegrees();
|
||||||
|
double udegrees3 = this->se.Latitude().UDegrees();
|
||||||
|
double udegrees4 = this->ne.Latitude().UDegrees();
|
||||||
|
double udegrees5 = this->nw.Longitude().UDegrees();
|
||||||
|
double udegrees6 = this->sw.Longitude().UDegrees();
|
||||||
|
double udegrees7 = this->se.Longitude().UDegrees();
|
||||||
|
double udegrees8 = this->ne.Longitude().UDegrees();
|
||||||
|
double udegrees9 = point.Longitude().UDegrees();
|
||||||
|
double udegrees10 = point.Latitude().UDegrees();
|
||||||
|
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 const std::string
|
||||||
|
FsLatLonQuadrilateral::to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const
|
||||||
|
{
|
||||||
|
return this->ne.to_string(HemisphereAsText, DetailLevel) + ", " +
|
||||||
|
this->nw.to_string(HemisphereAsText, DetailLevel) + ", " +
|
||||||
|
this->sw.to_string(HemisphereAsText, DetailLevel) + ", " +
|
||||||
|
this->se.to_string(HemisphereAsText, DetailLevel);
|
||||||
|
}
|
||||||
|
inline const std::string FsLatLonQuadrilateral::to_string() const
|
||||||
|
{
|
||||||
|
return this->to_string(true, 'm');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatLonQuadrilateral
|
||||||
|
FsLatLonQuadrilateral::ForRunway(FsLatLonPoint &ThresholdCentre,
|
||||||
|
double HeadingTrue,
|
||||||
|
double WidthInFeet,
|
||||||
|
double LengthInFeet)
|
||||||
|
{
|
||||||
|
double num = M_PI * HeadingTrue / 180.0;
|
||||||
|
double Feet = cos(num) * WidthInFeet / 2.0;
|
||||||
|
|
||||||
|
double decimalDegrees1 =
|
||||||
|
FsLatitudeSpan::FromFeet(sin(num) * WidthInFeet / 2.0)
|
||||||
|
.DecimalDegrees();
|
||||||
|
FsLatitude fsLatitude1 = FsLatitude(
|
||||||
|
ThresholdCentre.Latitude().DecimalDegrees() - decimalDegrees1);
|
||||||
|
|
||||||
|
double decimalDegrees2 =
|
||||||
|
FsLongitudeSpan::FromFeet(Feet, fsLatitude1).DecimalDegrees();
|
||||||
|
FsLongitude Longitude1 = FsLongitude(
|
||||||
|
ThresholdCentre.Longitude().DecimalDegrees() + decimalDegrees2);
|
||||||
|
FsLatLonPoint P1 = FsLatLonPoint(fsLatitude1, Longitude1);
|
||||||
|
fsLatitude1 = FsLatitude(ThresholdCentre.Latitude().DecimalDegrees() +
|
||||||
|
decimalDegrees1);
|
||||||
|
|
||||||
|
double decimalDegrees3 =
|
||||||
|
FsLongitudeSpan::FromFeet(Feet, fsLatitude1).DecimalDegrees();
|
||||||
|
Longitude1 = FsLongitude(ThresholdCentre.Longitude().DecimalDegrees() -
|
||||||
|
decimalDegrees3);
|
||||||
|
FsLatLonPoint P0 = FsLatLonPoint(fsLatitude1, Longitude1);
|
||||||
|
|
||||||
|
double decimalDegrees4 =
|
||||||
|
FsLatitudeSpan::FromFeet(cos(num) * LengthInFeet).DecimalDegrees();
|
||||||
|
FsLatitude fsLatitude2 = FsLatitude(
|
||||||
|
ThresholdCentre.Latitude().DecimalDegrees() + decimalDegrees4);
|
||||||
|
|
||||||
|
double decimalDegrees5 =
|
||||||
|
FsLongitudeSpan ::FromFeet(sin(num) * LengthInFeet, fsLatitude2)
|
||||||
|
.DecimalDegrees();
|
||||||
|
FsLongitude Longitude2 = FsLongitude(
|
||||||
|
ThresholdCentre.Longitude().DecimalDegrees() + decimalDegrees5);
|
||||||
|
FsLatLonPoint fsLatLonPoint = FsLatLonPoint(fsLatitude2, Longitude2);
|
||||||
|
fsLatitude1 = FsLatitude(fsLatLonPoint.Latitude().DecimalDegrees() -
|
||||||
|
decimalDegrees1);
|
||||||
|
|
||||||
|
double decimalDegrees6 =
|
||||||
|
FsLongitudeSpan::FromFeet(Feet, fsLatitude1).DecimalDegrees();
|
||||||
|
Longitude1 = FsLongitude(fsLatLonPoint.Longitude().DecimalDegrees() +
|
||||||
|
decimalDegrees6);
|
||||||
|
FsLatLonPoint P3 = FsLatLonPoint(fsLatitude1, Longitude1);
|
||||||
|
fsLatitude1 = FsLatitude(fsLatLonPoint.Latitude().DecimalDegrees() +
|
||||||
|
decimalDegrees1);
|
||||||
|
|
||||||
|
double decimalDegrees7 =
|
||||||
|
FsLongitudeSpan::FromFeet(Feet, fsLatitude1).DecimalDegrees();
|
||||||
|
Longitude1 = FsLongitude(fsLatLonPoint.Longitude().DecimalDegrees() -
|
||||||
|
decimalDegrees7);
|
||||||
|
FsLatLonPoint P2 = FsLatLonPoint(fsLatitude1, Longitude1);
|
||||||
|
|
||||||
|
return FsLatLonQuadrilateral(P0, P1, P2, P3);
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDE_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDE_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLatitudeSpan;
|
||||||
|
class FsLatitude
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLatitude();
|
||||||
|
inline FsLatitude(double DecimalDegrees);
|
||||||
|
inline FsLatitude(std::int64_t FSUnits);
|
||||||
|
inline FsLatitude(std::int32_t FSUnits);
|
||||||
|
inline FsLatitude(std::int32_t Degrees, double DecimalMinutes);
|
||||||
|
inline FsLatitude(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds);
|
||||||
|
|
||||||
|
inline std::int64_t ToFSUnits8() const;
|
||||||
|
inline std::int32_t ToFSUnits4() const;
|
||||||
|
|
||||||
|
inline double DecimalDegrees() const;
|
||||||
|
inline double DecimalMinutes() const;
|
||||||
|
inline double DecimalSeconds() const;
|
||||||
|
|
||||||
|
inline std::int32_t Degree() const;
|
||||||
|
inline std::int32_t Minute() const;
|
||||||
|
inline std::int32_t Second() const;
|
||||||
|
|
||||||
|
inline double UDegrees() const;
|
||||||
|
|
||||||
|
inline const std::string to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const;
|
||||||
|
inline const std::string to_string() const;
|
||||||
|
|
||||||
|
inline FsLatitude Add(const FsLatitudeSpan &Distance) const;
|
||||||
|
inline FsLatitude Subtract(const FsLatitudeSpan &Distance) const;
|
||||||
|
|
||||||
|
inline FsLatitude AddDegrees(double Degrees) const;
|
||||||
|
inline FsLatitude AddMinutes(double Minutes) const;
|
||||||
|
inline FsLatitude AddSeconds(double Seconds) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDEIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDEIMPL_H
|
||||||
|
|
||||||
|
#include "FsLatitude.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLatitude::FsLatitude() = default;
|
||||||
|
inline FsLatitude::FsLatitude(double DecimalDegrees)
|
||||||
|
{
|
||||||
|
this->pos = DecimalDegrees;
|
||||||
|
while (this->pos > 90.0 || this->pos < -90.0) {
|
||||||
|
if (this->pos > 90.0)
|
||||||
|
this->pos = 180.0 - this->pos;
|
||||||
|
if (this->pos < -90.0)
|
||||||
|
this->pos = -180.0 - this->pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatitude::FsLatitude(std::int64_t FSUnits)
|
||||||
|
: FsLatitude(FSUnits * 90.0 / 4.2957189152768E+16)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLatitude::FsLatitude(std::int32_t FSUnits)
|
||||||
|
: FsLatitude(FSUnits * 90.0 / 10001750.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLatitude::FsLatitude(std::int32_t Degrees, double DecimalMinutes)
|
||||||
|
: FsLatitude(Degrees + DecimalMinutes / 60.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLatitude::FsLatitude(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds)
|
||||||
|
: FsLatitude(Degrees + Minutes / 60.0 + DecimalSeconds / 3600.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::int64_t FsLatitude::ToFSUnits8() const
|
||||||
|
{
|
||||||
|
return this->pos * 4.2957189152768E+16 / 90.0;
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLatitude::ToFSUnits4() const
|
||||||
|
{
|
||||||
|
return this->pos * 10001750.0 / 90.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatitude::DecimalDegrees() const { return this->pos; }
|
||||||
|
inline double FsLatitude::DecimalMinutes() const
|
||||||
|
{
|
||||||
|
return (this->pos - trunc(this->pos)) * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLatitude::DecimalSeconds() const
|
||||||
|
{
|
||||||
|
double decimalMinutes = this->DecimalMinutes();
|
||||||
|
return (decimalMinutes - trunc(decimalMinutes)) * 60.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::int32_t FsLatitude::Degree() const { return trunc(this->pos); }
|
||||||
|
inline std::int32_t FsLatitude::Minute() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalMinutes());
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLatitude::Second() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatitude::UDegrees() const { return this->pos + 90.0; }
|
||||||
|
|
||||||
|
inline const std::string FsLatitude::to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
if (!HemisphereAsText) {
|
||||||
|
str << (this->pos < 0.0 ? "-" : "");
|
||||||
|
} else {
|
||||||
|
str << (this->pos < 0.0 ? "S" : "N");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DetailLevel) {
|
||||||
|
case 'm':
|
||||||
|
str << this->Degree() << "° " << this->DecimalMinutes() << "'";
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
str << this->Degree() << "° " << this->Minute() << "' "
|
||||||
|
<< this->DecimalSeconds() << "\"";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str << this->pos << "*";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
inline const std::string FsLatitude::to_string() const
|
||||||
|
{
|
||||||
|
return this->to_string(true, 'm');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatitude FsLatitude::Add(const FsLatitudeSpan &Distance) const
|
||||||
|
{
|
||||||
|
return FsLatitude(this->pos + Distance.DecimalDegrees());
|
||||||
|
}
|
||||||
|
inline FsLatitude FsLatitude::Subtract(const FsLatitudeSpan &Distance) const
|
||||||
|
{
|
||||||
|
return FsLatitude(this->pos - Distance.DecimalDegrees());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatitude FsLatitude::AddDegrees(double Degrees) const
|
||||||
|
{
|
||||||
|
return FsLatitude(this->pos + Degrees);
|
||||||
|
}
|
||||||
|
inline FsLatitude FsLatitude::AddMinutes(double Minutes) const
|
||||||
|
{
|
||||||
|
return FsLatitude(this->pos + Minutes / 60.0);
|
||||||
|
}
|
||||||
|
inline FsLatitude FsLatitude::AddSeconds(double Seconds) const
|
||||||
|
{
|
||||||
|
return FsLatitude(this->pos + Seconds / 3600.0);
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDESPAN_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDESPAN_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLatitude;
|
||||||
|
class FsLatitudeSpan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double span;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLatitudeSpan();
|
||||||
|
inline FsLatitudeSpan(double DecimalDegrees);
|
||||||
|
inline FsLatitudeSpan(std::int32_t Degrees, double DecimalMinutes);
|
||||||
|
inline FsLatitudeSpan(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds);
|
||||||
|
|
||||||
|
inline static FsLatitudeSpan FromFeet(double Feet);
|
||||||
|
inline static FsLatitudeSpan FromNauticalMiles(double NauticalMiles);
|
||||||
|
inline static FsLatitudeSpan FromMetres(double Metres);
|
||||||
|
inline static FsLatitudeSpan
|
||||||
|
BetweenTwoLatitides(const FsLatitude &Lat1, const FsLatitude &Lat2);
|
||||||
|
|
||||||
|
inline double DecimalDegrees() const;
|
||||||
|
inline double DecimalMinutes() const;
|
||||||
|
inline double DecimalSeconds() const;
|
||||||
|
|
||||||
|
inline std::int32_t Degrees() const;
|
||||||
|
inline std::int32_t Minutes() const;
|
||||||
|
inline std::int32_t Seconds() const;
|
||||||
|
|
||||||
|
inline double TotalMinutes() const;
|
||||||
|
inline double TotalSeconds() const;
|
||||||
|
|
||||||
|
inline double ToFeet() const;
|
||||||
|
inline double ToNauticalMiles() const;
|
||||||
|
inline double ToMetres() const;
|
||||||
|
|
||||||
|
inline const std::string to_string(char DetailLevel) const;
|
||||||
|
inline const std::string to_string();
|
||||||
|
};
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
|
||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDESPANIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLATITUDESPANIMPL_H
|
||||||
|
|
||||||
|
#include "FsLatitudeSpan.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLatitudeSpan::FsLatitudeSpan() = default;
|
||||||
|
inline FsLatitudeSpan::FsLatitudeSpan(double DecimalDegrees)
|
||||||
|
{
|
||||||
|
this->span = DecimalDegrees;
|
||||||
|
}
|
||||||
|
inline FsLatitudeSpan::FsLatitudeSpan(std::int32_t Degrees,
|
||||||
|
double DecimalMinutes)
|
||||||
|
: FsLatitudeSpan(Degrees + DecimalMinutes / 60.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLatitudeSpan::FsLatitudeSpan(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds)
|
||||||
|
: FsLatitudeSpan(Degrees + Minutes / 60.0 + DecimalSeconds / 3600.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLatitudeSpan FsLatitudeSpan::FromFeet(double Feet)
|
||||||
|
{
|
||||||
|
return FsLatitudeSpan(Feet / 364601.4567);
|
||||||
|
}
|
||||||
|
inline FsLatitudeSpan
|
||||||
|
FsLatitudeSpan::FromNauticalMiles(double NauticalMiles)
|
||||||
|
{
|
||||||
|
return FsLatitudeSpan::FromFeet(NauticalMiles * 6076.1155);
|
||||||
|
}
|
||||||
|
inline FsLatitudeSpan FsLatitudeSpan::FromMetres(double Metres)
|
||||||
|
{
|
||||||
|
return FsLatitudeSpan::FromFeet(Metres * 3.2808);
|
||||||
|
}
|
||||||
|
inline FsLatitudeSpan
|
||||||
|
FsLatitudeSpan::BetweenTwoLatitides(const FsLatitude &Lat1,
|
||||||
|
const FsLatitude &Lat2)
|
||||||
|
{
|
||||||
|
return FsLatitudeSpan(abs(Lat2.UDegrees() - Lat1.UDegrees()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatitudeSpan::DecimalDegrees() const { return this->span; }
|
||||||
|
inline double FsLatitudeSpan::DecimalMinutes() const
|
||||||
|
{
|
||||||
|
return (this->span - trunc(this->span)) * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLatitudeSpan::DecimalSeconds() const
|
||||||
|
{
|
||||||
|
double decimalMinutes = this->DecimalMinutes();
|
||||||
|
return (decimalMinutes - trunc(decimalMinutes)) * 60.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::int32_t FsLatitudeSpan::Degrees() const
|
||||||
|
{
|
||||||
|
return trunc(this->span);
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLatitudeSpan::Minutes() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalMinutes());
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLatitudeSpan::Seconds() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatitudeSpan::TotalMinutes() const
|
||||||
|
{
|
||||||
|
return this->span * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLatitudeSpan::TotalSeconds() const
|
||||||
|
{
|
||||||
|
return this->span * 3600.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLatitudeSpan::ToFeet() const
|
||||||
|
{
|
||||||
|
return 364601.4567 * this->span;
|
||||||
|
}
|
||||||
|
inline double FsLatitudeSpan::ToNauticalMiles() const
|
||||||
|
{
|
||||||
|
return this->ToFeet() / 6076.1155;
|
||||||
|
}
|
||||||
|
inline double FsLatitudeSpan::ToMetres() const
|
||||||
|
{
|
||||||
|
return this->ToFeet() / 3.2808;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::string FsLatitudeSpan::to_string(char DetailLevel) const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
switch (DetailLevel) {
|
||||||
|
case 'm':
|
||||||
|
str << this->Degrees() << "* " << this->DecimalMinutes() << "'";
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
str << this->Degrees() << "* " << this->Minutes() << "' "
|
||||||
|
<< this->DecimalSeconds() << "\"";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str << this->span << "*";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
inline const std::string FsLatitudeSpan::to_string()
|
||||||
|
{
|
||||||
|
return this->to_string('m');
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDE_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDE_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLongitudeSpan;
|
||||||
|
class FsLongitude
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLongitude();
|
||||||
|
inline FsLongitude(double DecimalDegrees);
|
||||||
|
inline FsLongitude(std::int64_t FSUnits);
|
||||||
|
inline FsLongitude(std::int32_t FSUnits);
|
||||||
|
inline FsLongitude(std::int32_t Degrees, double DecimalMinutes);
|
||||||
|
inline FsLongitude(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds);
|
||||||
|
|
||||||
|
inline long ToFSUnits8() const;
|
||||||
|
inline std::int32_t ToFSUnits4() const;
|
||||||
|
|
||||||
|
inline double DecimalDegrees() const;
|
||||||
|
|
||||||
|
inline double DecimalMinutes() const;
|
||||||
|
inline double DecimalSeconds() const;
|
||||||
|
|
||||||
|
inline std::int32_t Degree() const;
|
||||||
|
inline std::int32_t Minute() const;
|
||||||
|
inline std::int32_t Second() const;
|
||||||
|
|
||||||
|
inline double UDegrees() const;
|
||||||
|
|
||||||
|
inline const std::string to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const;
|
||||||
|
inline const std::string to_string() const;
|
||||||
|
inline FsLongitude Add(const FsLongitudeSpan &Distance) const;
|
||||||
|
inline FsLongitude Subtract(const FsLongitudeSpan &Distance) const;
|
||||||
|
|
||||||
|
inline FsLongitude AddDegrees(double Degrees) const;
|
||||||
|
inline FsLongitude AddMinutes(double Minutes) const;
|
||||||
|
inline FsLongitude AddSeconds(double Seconds) const;
|
||||||
|
};
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDEIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDEIMPL_H
|
||||||
|
|
||||||
|
#include "FsLongitude.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLongitude::FsLongitude() = default;
|
||||||
|
inline FsLongitude::FsLongitude(double DecimalDegrees)
|
||||||
|
{
|
||||||
|
this->pos = DecimalDegrees;
|
||||||
|
while (this->pos < -180.0 || this->pos > 180.0) {
|
||||||
|
if (this->pos > 180.0)
|
||||||
|
this->pos -= 360.0;
|
||||||
|
if (this->pos < -180.0)
|
||||||
|
this->pos += 360.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline FsLongitude::FsLongitude(std::int64_t FSUnits)
|
||||||
|
: FsLongitude(FSUnits * 360.0 / 1.8446744073709552E+19)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLongitude::FsLongitude(std::int32_t FSUnits)
|
||||||
|
: FsLongitude(FSUnits * 360.0 / 4294967296.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLongitude::FsLongitude(std::int32_t Degrees, double DecimalMinutes)
|
||||||
|
: FsLongitude(Degrees + DecimalMinutes / 60.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLongitude::FsLongitude(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds)
|
||||||
|
: FsLongitude(Degrees + Minutes / 60.0 + DecimalSeconds / 3600.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long FsLongitude::ToFSUnits8() const
|
||||||
|
{
|
||||||
|
return this->pos * 1.8446744073709552E+19 / 360.0;
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLongitude::ToFSUnits4() const
|
||||||
|
{
|
||||||
|
return this->pos * 4294967296.0 / 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLongitude::DecimalDegrees() const { return this->pos; }
|
||||||
|
|
||||||
|
inline double FsLongitude::DecimalMinutes() const
|
||||||
|
{
|
||||||
|
return (this->pos - trunc(this->pos)) * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLongitude::DecimalSeconds() const
|
||||||
|
{
|
||||||
|
double decimalMinutes = this->DecimalMinutes();
|
||||||
|
return (decimalMinutes - trunc(decimalMinutes)) * 60.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::int32_t FsLongitude::Degree() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalDegrees());
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLongitude::Minute() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalMinutes());
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLongitude::Second() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLongitude::UDegrees() const { return this->pos + 180.0; }
|
||||||
|
|
||||||
|
inline const std::string FsLongitude::to_string(bool HemisphereAsText,
|
||||||
|
char DetailLevel) const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
if (!HemisphereAsText) {
|
||||||
|
str << (this->pos < 0.0 ? "-" : "");
|
||||||
|
} else {
|
||||||
|
str << (this->pos < 0.0 ? "W" : "E");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DetailLevel) {
|
||||||
|
case 'm':
|
||||||
|
str << this->Degree() << "° " << this->DecimalMinutes() << "'";
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
str << this->Degree() << "° " << this->Minute() << "' "
|
||||||
|
<< this->DecimalSeconds() << "\"";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str << this->pos << "*";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
inline const std::string FsLongitude::to_string() const
|
||||||
|
{
|
||||||
|
return this->to_string(true, 'm');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLongitude FsLongitude::Add(const FsLongitudeSpan &Distance) const
|
||||||
|
{
|
||||||
|
return FsLongitude(this->pos + Distance.DecimalDegrees());
|
||||||
|
}
|
||||||
|
inline FsLongitude
|
||||||
|
FsLongitude::Subtract(const FsLongitudeSpan &Distance) const
|
||||||
|
{
|
||||||
|
return FsLongitude(this->pos - Distance.DecimalDegrees());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLongitude FsLongitude::AddDegrees(double Degrees) const
|
||||||
|
{
|
||||||
|
return FsLongitude(this->pos + Degrees);
|
||||||
|
}
|
||||||
|
inline FsLongitude FsLongitude::AddMinutes(double Minutes) const
|
||||||
|
{
|
||||||
|
return FsLongitude(this->pos + Minutes / 60.0);
|
||||||
|
}
|
||||||
|
inline FsLongitude FsLongitude::AddSeconds(double Seconds) const
|
||||||
|
{
|
||||||
|
return FsLongitude(this->pos + Seconds / 3600.0);
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDESPAN_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDESPAN_H
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
class FsLongitude;
|
||||||
|
class FsLatitude;
|
||||||
|
class FsLongitudeSpan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double span;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline FsLongitudeSpan();
|
||||||
|
inline FsLongitudeSpan(double DecimalDegrees);
|
||||||
|
inline FsLongitudeSpan(std::int32_t Degrees, double DecimalMinutes);
|
||||||
|
inline FsLongitudeSpan(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds);
|
||||||
|
inline static FsLongitudeSpan FromFeet(double Feet,
|
||||||
|
const FsLatitude &AtLatitude);
|
||||||
|
inline static FsLongitudeSpan
|
||||||
|
FromNauticalMiles(double NauticalMiles,
|
||||||
|
const FsLatitude &AtLatitude);
|
||||||
|
inline static FsLongitudeSpan FromMetres(double Metres,
|
||||||
|
const FsLatitude &AtLatitude);
|
||||||
|
inline static FsLongitudeSpan
|
||||||
|
BetweenTwoLongitudes(const FsLongitude &Lon1,
|
||||||
|
const FsLongitude &Lon2);
|
||||||
|
|
||||||
|
inline double DecimalDegrees() const;
|
||||||
|
inline double DecimalMinutes() const;
|
||||||
|
inline double DecimalSeconds() const;
|
||||||
|
|
||||||
|
inline std::int32_t Degrees() const;
|
||||||
|
inline std::int32_t Minutes() const;
|
||||||
|
inline std::int32_t Seconds() const;
|
||||||
|
|
||||||
|
inline double TotalMinutes() const;
|
||||||
|
inline double TotalSeconds() const;
|
||||||
|
|
||||||
|
inline double ToFeet(const FsLatitude &AtLatitude) const;
|
||||||
|
inline double ToNauticalMiles(const FsLatitude &AtLatitude) const;
|
||||||
|
inline double ToMetres(const FsLatitude &AtLatitude) const;
|
||||||
|
|
||||||
|
inline const std::string to_string(char DetailLevel) const;
|
||||||
|
inline const std::string to_string();
|
||||||
|
};
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
#ifndef GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDESPANIMPL_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_FSUIPC_FSLONGITUDESPANIMPL_H
|
||||||
|
|
||||||
|
#include "FsLongitudeSpan.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace FSUIPC
|
||||||
|
{
|
||||||
|
inline FsLongitudeSpan::FsLongitudeSpan() = default;
|
||||||
|
inline FsLongitudeSpan::FsLongitudeSpan(double DecimalDegrees)
|
||||||
|
{
|
||||||
|
this->span = DecimalDegrees;
|
||||||
|
}
|
||||||
|
inline FsLongitudeSpan::FsLongitudeSpan(std::int32_t Degrees,
|
||||||
|
double DecimalMinutes)
|
||||||
|
: FsLongitudeSpan(Degrees + DecimalMinutes / 60.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline FsLongitudeSpan::FsLongitudeSpan(std::int32_t Degrees,
|
||||||
|
std::int32_t Minutes,
|
||||||
|
double DecimalSeconds)
|
||||||
|
: FsLongitudeSpan(Degrees + Minutes / 60.0 + DecimalSeconds / 3600.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FsLongitudeSpan
|
||||||
|
FsLongitudeSpan::FromFeet(double Feet, const FsLatitude &AtLatitude)
|
||||||
|
{
|
||||||
|
double num =
|
||||||
|
cos(M_PI * AtLatitude.DecimalDegrees() / 180.0) * 131479672.3 / 360.0;
|
||||||
|
return FsLongitudeSpan(Feet / num);
|
||||||
|
}
|
||||||
|
inline FsLongitudeSpan
|
||||||
|
FsLongitudeSpan::FromNauticalMiles(double NauticalMiles,
|
||||||
|
const FsLatitude &AtLatitude)
|
||||||
|
{
|
||||||
|
return FsLongitudeSpan::FromFeet(NauticalMiles * 6076.1155, AtLatitude);
|
||||||
|
}
|
||||||
|
inline FsLongitudeSpan
|
||||||
|
FsLongitudeSpan::FromMetres(double Metres, const FsLatitude &AtLatitude)
|
||||||
|
{
|
||||||
|
return FsLongitudeSpan::FromFeet(Metres * 3.2808, AtLatitude);
|
||||||
|
}
|
||||||
|
inline FsLongitudeSpan
|
||||||
|
FsLongitudeSpan::BetweenTwoLongitudes(const FsLongitude &Lon1,
|
||||||
|
const FsLongitude &Lon2)
|
||||||
|
{
|
||||||
|
return fmod(Lon2.UDegrees() - Lon1.UDegrees(), 360.0) <
|
||||||
|
fmod(Lon1.UDegrees() - Lon2.UDegrees(), 360.0)
|
||||||
|
? FsLongitudeSpan(
|
||||||
|
fmod(Lon2.UDegrees() - Lon1.UDegrees(), 360.0))
|
||||||
|
: FsLongitudeSpan(
|
||||||
|
fmod(Lon1.UDegrees() - Lon2.UDegrees(), 360.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLongitudeSpan::DecimalDegrees() const { return this->span; }
|
||||||
|
inline double FsLongitudeSpan::DecimalMinutes() const
|
||||||
|
{
|
||||||
|
return (this->span - trunc(this->span)) * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLongitudeSpan::DecimalSeconds() const
|
||||||
|
{
|
||||||
|
double decimalMinutes = this->DecimalMinutes();
|
||||||
|
return (decimalMinutes - trunc(decimalMinutes)) * 60.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::int32_t FsLongitudeSpan::Degrees() const
|
||||||
|
{
|
||||||
|
return trunc(this->span);
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLongitudeSpan::Minutes() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalMinutes());
|
||||||
|
}
|
||||||
|
inline std::int32_t FsLongitudeSpan::Seconds() const
|
||||||
|
{
|
||||||
|
return trunc(this->DecimalSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLongitudeSpan::TotalMinutes() const
|
||||||
|
{
|
||||||
|
return this->span * 60.0;
|
||||||
|
}
|
||||||
|
inline double FsLongitudeSpan::TotalSeconds() const
|
||||||
|
{
|
||||||
|
return this->span * 3600.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double FsLongitudeSpan::ToFeet(const FsLatitude &AtLatitude) const
|
||||||
|
{
|
||||||
|
return cos(M_PI * AtLatitude.DecimalDegrees() / 180.0) * 131479672.3 /
|
||||||
|
360.0 * this->span;
|
||||||
|
}
|
||||||
|
inline double
|
||||||
|
FsLongitudeSpan::ToNauticalMiles(const FsLatitude &AtLatitude) const
|
||||||
|
{
|
||||||
|
return this->ToFeet(AtLatitude) / 6076.1155;
|
||||||
|
}
|
||||||
|
inline double FsLongitudeSpan::ToMetres(const FsLatitude &AtLatitude) const
|
||||||
|
{
|
||||||
|
return this->ToFeet(AtLatitude) / 3.2808;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::string FsLongitudeSpan::to_string(char DetailLevel) const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
switch (DetailLevel) {
|
||||||
|
case 'm':
|
||||||
|
str << this->Degrees() << "* " << this->DecimalMinutes() << "'";
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
str << this->Degrees() << "* " << this->Minutes() << "' "
|
||||||
|
<< this->DecimalSeconds() << "\"";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str << this->span << "*";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
inline const std::string FsLongitudeSpan::to_string()
|
||||||
|
{
|
||||||
|
return this->to_string('m');
|
||||||
|
}
|
||||||
|
} // namespace FSUIPC
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#define GERMANAIRLINESVA_FILE_LOGBOOK_H
|
#define GERMANAIRLINESVA_FILE_LOGBOOK_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -33,7 +32,7 @@ namespace file
|
|||||||
private:
|
private:
|
||||||
std::vector<LogbookEntry> entries;
|
std::vector<LogbookEntry> entries;
|
||||||
|
|
||||||
void fromFile(const std::string &file);
|
void fromFile();
|
||||||
void readVersion1(std::ifstream &in);
|
void readVersion1(std::ifstream &in);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -26,14 +26,16 @@ namespace file
|
|||||||
std::uint32_t time;
|
std::uint32_t time;
|
||||||
std::uint16_t altitude = 0;
|
std::uint16_t altitude = 0;
|
||||||
std::uint16_t groundSpeed = 0;
|
std::uint16_t groundSpeed = 0;
|
||||||
struct germanairlinesva::geodata::point coordinates{NAN, NAN};
|
struct geodata::point coordinates {
|
||||||
|
NAN, NAN
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RecordingEntry() = default;
|
RecordingEntry() = default;
|
||||||
RecordingEntry(std::uint32_t time,
|
RecordingEntry(std::uint32_t time,
|
||||||
std::uint16_t altitude,
|
std::uint16_t altitude,
|
||||||
std::uint16_t groundSpeed,
|
std::uint16_t groundSpeed,
|
||||||
struct germanairlinesva::geodata::point coordinates);
|
struct geodata::point coordinates);
|
||||||
|
|
||||||
void toFile(std::ofstream &out) const;
|
void toFile(std::ofstream &out) const;
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,9 @@ namespace file
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Representation of gate
|
* Representation of gate
|
||||||
* Heading in degrees (0...360)
|
* Center in lat/lon radians
|
||||||
* Radius in metres
|
* Radius in metres
|
||||||
*
|
*
|
||||||
* Designator must be null terminated
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | POINT | UINT8
|
* UINT8 | CHAR[] | POINT | UINT8
|
||||||
* -------+------------+--------+-------
|
* -------+------------+--------+-------
|
||||||
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
||||||
@@ -34,22 +32,29 @@ namespace file
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string designator;
|
std::string designator;
|
||||||
struct germanairlinesva::geodata::point center;
|
struct geodata::point center;
|
||||||
std::uint8_t radius;
|
std::uint8_t radius;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// From X-Plane or MakeRwys
|
||||||
Gate(std::string designator,
|
Gate(std::string designator,
|
||||||
struct germanairlinesva::geodata::point center,
|
double latitude,
|
||||||
|
double longitude,
|
||||||
|
std::uint8_t radius);
|
||||||
|
// From Database
|
||||||
|
Gate(std::string designator,
|
||||||
|
struct geodata::point center,
|
||||||
std::uint8_t radius);
|
std::uint8_t radius);
|
||||||
|
|
||||||
void toFile(std::ofstream &out) const;
|
void toFile(std::ofstream &out) const;
|
||||||
bool contains(germanairlinesva::geodata::point coordinates) const;
|
bool contains(geodata::point coordinates) const;
|
||||||
|
|
||||||
inline const std::string to_string() const
|
inline const std::string to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
str << "Gate " << this->designator << " at " << this->center.latitude
|
str << "Gate " << this->designator << " at "
|
||||||
<< "N " << this->center.longitude << "E, Radius "
|
<< geodata::toDegrees(this->center.latitude) << "N "
|
||||||
|
<< geodata::toDegrees(this->center.longitude) << "E, Radius "
|
||||||
<< (int)this->radius;
|
<< (int)this->radius;
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_FILE_RUNWAY_H
|
#ifndef GERMANAIRLINESVA_FILE_SIMDATA_RUNWAY_H
|
||||||
#define GERMANAIRLINESVA_FILE_RUNWAY_H
|
#define GERMANAIRLINESVA_FILE_SIMDATA_RUNWAY_H
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "FSUIPC/FsGeoData.h"
|
||||||
#include "geodata.hpp"
|
#include "geodata.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
@@ -21,56 +22,93 @@ namespace file
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Representation of one runway with supplementary information
|
* Representation of one runway with supplementary information
|
||||||
* Heading in degrees (0...360) true
|
* Heading in degrees true
|
||||||
* Width and length in meters
|
* Threshold center in lat/lon degrees
|
||||||
|
* Width and length in feet
|
||||||
*
|
*
|
||||||
* Designator must be null terminated
|
* UINT8 | CHAR[] | POINT | UINT8 | UINT16 | DOUBLE
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | BOX | UINT8 | UINT16 | UINT16
|
|
||||||
* -------+------------+--------+-------+--------+-------
|
* -------+------------+--------+-------+--------+-------
|
||||||
* STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG
|
* STRLEN | DESIGNATOR | CENTER | WIDTH | LENGTH | TRUHDG
|
||||||
*/
|
*/
|
||||||
class Runway
|
class Runway
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string designator;
|
std::string designator;
|
||||||
struct germanairlinesva::geodata::box bounds;
|
struct geodata::point center;
|
||||||
std::uint8_t width;
|
std::uint8_t width;
|
||||||
std::uint16_t length;
|
std::uint16_t length;
|
||||||
std::uint16_t trueHeading;
|
double trueHeading;
|
||||||
std::vector<std::uint8_t> file;
|
|
||||||
|
// QUAD TEST
|
||||||
|
FSUIPC::FsLatLonQuadrilateral quad;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// From X-Plane or MakeRwys
|
// From X-Plane or MakeRwys
|
||||||
Runway(std::string designator,
|
inline Runway(std::string designator,
|
||||||
double latitudeStart,
|
double latitudeStart,
|
||||||
double longitudeStart,
|
double longitudeStart,
|
||||||
double latitudeEnd,
|
double latitudeEnd,
|
||||||
double longitudeEnd,
|
double longitudeEnd,
|
||||||
double width);
|
double width)
|
||||||
// From database
|
{
|
||||||
Runway(std::string designator,
|
this->designator = designator;
|
||||||
struct germanairlinesva::geodata::box bounds,
|
this->width = width * 33.280839895;
|
||||||
std::uint8_t width,
|
|
||||||
std::uint16_t length,
|
|
||||||
std::uint16_t trueHeading);
|
|
||||||
|
|
||||||
void toFile(std::ofstream &out) const;
|
|
||||||
|
this->length = geodata::distanceEarthD(latitudeStart,
|
||||||
|
longitudeStart,
|
||||||
|
latitudeEnd,
|
||||||
|
longitudeEnd) *
|
||||||
|
3.280839895;
|
||||||
|
this->trueHeading = geodata::bearingDD(latitudeStart,
|
||||||
|
longitudeStart,
|
||||||
|
latitudeEnd,
|
||||||
|
longitudeEnd);
|
||||||
|
this->center = {latitudeStart, longitudeStart};
|
||||||
|
|
||||||
|
FSUIPC::FsLatLonPoint threshold(latitudeStart, longitudeStart);
|
||||||
|
quad = FSUIPC::FsLatLonQuadrilateral::ForRunway(threshold,
|
||||||
|
this->trueHeading,
|
||||||
|
this->width,
|
||||||
|
this->length);
|
||||||
|
}
|
||||||
|
// From database
|
||||||
|
inline Runway(std::string designator,
|
||||||
|
struct geodata::point center,
|
||||||
|
std::uint8_t width,
|
||||||
|
std::uint16_t length,
|
||||||
|
double trueHeading)
|
||||||
|
{
|
||||||
|
this->designator = designator;
|
||||||
|
this->center = center;
|
||||||
|
this->width = width;
|
||||||
|
this->length = length;
|
||||||
|
this->trueHeading = trueHeading;
|
||||||
|
|
||||||
|
FSUIPC::FsLatLonPoint threshold(center.latitude, center.longitude);
|
||||||
|
quad = FSUIPC::FsLatLonQuadrilateral::ForRunway(threshold,
|
||||||
|
trueHeading,
|
||||||
|
width,
|
||||||
|
length);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void toFile(std::ofstream &out) const
|
||||||
|
{
|
||||||
|
writeString(out, this->designator);
|
||||||
|
write<decltype(this->center)>(out, this->center);
|
||||||
|
write<decltype(this->width)>(out, this->width);
|
||||||
|
write<decltype(this->length)>(out, this->length);
|
||||||
|
write<decltype(this->trueHeading)>(out, this->trueHeading);
|
||||||
|
}
|
||||||
|
|
||||||
inline const std::string to_string() const
|
inline const std::string to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
str << "Runway " << this->designator << " with bounds "
|
str << "Runway " << this->designator << " with threshold center "
|
||||||
<< this->bounds.topLeft.latitude << "N "
|
<< this->center.latitude << "N " << this->center.longitude
|
||||||
<< this->bounds.topLeft.longitude << "E, "
|
<< "E, Width " << (int)this->width << "ft, Length "
|
||||||
<< this->bounds.topRight.latitude << "N "
|
<< this->length << "ft, True Heading " << this->trueHeading
|
||||||
<< this->bounds.topRight.longitude << "E, "
|
<< "°, Quad " << quad.to_string(true, ' ');
|
||||||
<< 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();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,36 @@
|
|||||||
#define GERMANAIRLINESVA_FILE_SIMDATABASE_H
|
#define GERMANAIRLINESVA_FILE_SIMDATABASE_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "geodata.hpp"
|
#include "config/config.h"
|
||||||
#include "helpers.hpp"
|
#include "constants.h"
|
||||||
#include "simdata/gate.h"
|
#include "simdata/gate.h"
|
||||||
#include "simdata/runway.h"
|
#include "simdata/runway.h"
|
||||||
|
#include "simdata/simdataXP.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header
|
||||||
|
*
|
||||||
|
* CHAR[5] | UINT8
|
||||||
|
* --------+--------
|
||||||
|
* VGAS | VERSION
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Airport
|
||||||
|
*
|
||||||
|
* UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[]
|
||||||
|
* --------+--------+----------+--------+---------+---------
|
||||||
|
* STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS
|
||||||
|
*/
|
||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
@@ -24,34 +45,28 @@ namespace file
|
|||||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
airports;
|
airports;
|
||||||
|
|
||||||
|
void fromFile();
|
||||||
|
void readVersion1(std::ifstream &in);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void toFile(std::ofstream &out) const;
|
SimDatabase(int xPlaneVersion,
|
||||||
|
const char *hash,
|
||||||
|
std::unique_ptr<config::Config> &configuration,
|
||||||
|
std::function<void(const std::string)> toLog);
|
||||||
|
|
||||||
const Gate *checkGate(
|
void toFile() const;
|
||||||
const std::string icao,
|
|
||||||
const struct germanairlinesva::geodata::point coordinates) const;
|
|
||||||
|
|
||||||
inline std::size_t numAirports() const { return this->airports.size(); }
|
inline std::size_t getCount() const { return this->airports.size(); }
|
||||||
inline const std::pair<std::vector<Gate>, std::vector<Runway>> &
|
inline const std::pair<const std::vector<Gate>,
|
||||||
getAirport(std::string icao) const
|
const std::vector<Runway>>
|
||||||
|
operator[](std::string key)
|
||||||
{
|
{
|
||||||
return this->airports.at(icao);
|
auto it = this->airports.find(key);
|
||||||
}
|
if (it != this->airports.end()) {
|
||||||
inline void addAirport(std::string icao,
|
return this->airports[key];
|
||||||
std::vector<Gate> &gates,
|
} else {
|
||||||
std::vector<Runway> &runways)
|
return std::pair<std::vector<Gate>, std::vector<Runway>>();
|
||||||
{
|
}
|
||||||
this->airports[icao] = std::make_pair(gates, runways);
|
|
||||||
}
|
|
||||||
template <class... Args>
|
|
||||||
inline void addGate(std::string icao, Args &&...args)
|
|
||||||
{
|
|
||||||
this->airports[icao].first.emplace_back(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class... Args>
|
|
||||||
inline void addRunway(std::string icao, Args &&...args)
|
|
||||||
{
|
|
||||||
this->airports[icao].second.emplace_back(std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace simdata
|
} // namespace simdata
|
||||||
|
|||||||
@@ -16,15 +16,19 @@ namespace file
|
|||||||
{
|
{
|
||||||
namespace simdata
|
namespace simdata
|
||||||
{
|
{
|
||||||
int scan(const std::string defaultFile,
|
int scan(
|
||||||
const std::string sceneryPack,
|
const std::string defaultFile,
|
||||||
const std::string logFile,
|
const std::string sceneryPack,
|
||||||
SimDatabase &airports);
|
const std::string logFile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports);
|
||||||
|
|
||||||
void makeAirport(const std::string &kind,
|
void makeAirport(
|
||||||
std::ifstream &infile,
|
const std::string &kind,
|
||||||
SimDatabase &airports,
|
std::ifstream &infile,
|
||||||
std::ofstream &logfile);
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports,
|
||||||
|
std::ofstream &logfile);
|
||||||
void makeGate15(std::vector<Gate> &gates,
|
void makeGate15(std::vector<Gate> &gates,
|
||||||
const std::vector<std::string> &fields);
|
const std::vector<std::string> &fields);
|
||||||
void makeRunway(std::vector<Runway> &runways,
|
void makeRunway(std::vector<Runway> &runways,
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_FILE_SIMULATORDATABASE_H
|
|
||||||
#define GERMANAIRLINESVA_FILE_SIMULATORDATABASE_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "simdata/gate.h"
|
|
||||||
#include "simdata/runway.h"
|
|
||||||
#include "simdata/simDatabase.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Header
|
|
||||||
*
|
|
||||||
* CHAR[5] | UINT8
|
|
||||||
* --------+--------
|
|
||||||
* VGAS | VERSION
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Airport
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[]
|
|
||||||
* --------+--------+----------+--------+---------+---------
|
|
||||||
* STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace germanairlinesva
|
|
||||||
{
|
|
||||||
namespace file
|
|
||||||
{
|
|
||||||
namespace simdata
|
|
||||||
{
|
|
||||||
static inline void toFile(const SimDatabase &database,
|
|
||||||
const std::string &file)
|
|
||||||
{
|
|
||||||
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<const char *>(header), 6);
|
|
||||||
|
|
||||||
database.toFile(out);
|
|
||||||
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const SimDatabase readVersion1(std::ifstream &in)
|
|
||||||
{
|
|
||||||
SimDatabase database;
|
|
||||||
|
|
||||||
std::uint16_t numAirports = read<std::uint16_t>(in);
|
|
||||||
|
|
||||||
for (int i = 0; i < numAirports; i++) {
|
|
||||||
// ICAO
|
|
||||||
std::string icao = readString(in);
|
|
||||||
// Gates
|
|
||||||
std::uint16_t numGates = read<std::uint16_t>(in);
|
|
||||||
for (int j = 0; j < numGates; j++) {
|
|
||||||
std::string designator = readString(in);
|
|
||||||
struct germanairlinesva::geodata::point center =
|
|
||||||
read<struct germanairlinesva::geodata::point>(in);
|
|
||||||
std::uint8_t radius = read<std::uint8_t>(in);
|
|
||||||
|
|
||||||
database.addGate(icao, designator, center, radius);
|
|
||||||
}
|
|
||||||
// Runways
|
|
||||||
std::uint8_t numRunways = read<std::uint8_t>(in);
|
|
||||||
for (int j = 0; j < numRunways; j++) {
|
|
||||||
std::string designator = readString(in);
|
|
||||||
// Bounds
|
|
||||||
struct germanairlinesva::geodata::box bounds =
|
|
||||||
read<struct germanairlinesva::geodata::box>(in);
|
|
||||||
std::uint8_t width = read<std::uint8_t>(in);
|
|
||||||
std::uint16_t length = read<std::uint16_t>(in);
|
|
||||||
std::uint16_t trueHeading = read<std::uint16_t>(in);
|
|
||||||
|
|
||||||
database
|
|
||||||
.addRunway(icao, designator, bounds, width, length, trueHeading);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const SimDatabase fromFile(const std::string &file)
|
|
||||||
{
|
|
||||||
std::ifstream in(file, std::ifstream::binary);
|
|
||||||
|
|
||||||
// File Header
|
|
||||||
char ident[5];
|
|
||||||
in.read(ident, 5);
|
|
||||||
if (strcmp(ident, "VGAS") != 0) {
|
|
||||||
throw std::invalid_argument("Wrong file");
|
|
||||||
}
|
|
||||||
std::uint8_t version = read<std::uint8_t>(in);
|
|
||||||
|
|
||||||
if (version == 1) {
|
|
||||||
return readVersion1(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
return SimDatabase();
|
|
||||||
}
|
|
||||||
} // namespace simdata
|
|
||||||
} // namespace file
|
|
||||||
} // namespace germanairlinesva
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+7
-9
@@ -8,23 +8,21 @@ namespace file
|
|||||||
{
|
{
|
||||||
Logbook::Logbook()
|
Logbook::Logbook()
|
||||||
{
|
{
|
||||||
if (germanairlinesva::util::fileExists(XPLANE_PLUGIN_DIRECTORY LOGBOOK)) {
|
if (util::fileExists(XPLANE_PLUGIN_DIRECTORY LOGBOOK)) {
|
||||||
this->fromFile(XPLANE_PLUGIN_DIRECTORY LOGBOOK);
|
this->fromFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logbook::fromFile(const std::string &file)
|
void Logbook::fromFile()
|
||||||
{
|
{
|
||||||
std::ifstream in(file, std::ifstream::binary);
|
std::ifstream in(XPLANE_PLUGIN_DIRECTORY LOGBOOK, std::ifstream::binary);
|
||||||
|
|
||||||
// File Header
|
// File Header
|
||||||
char ident[5];
|
std::string ident = readString(in, 5);
|
||||||
in.read(ident, 5);
|
if (ident.compare("VGAL") != 0) {
|
||||||
if (strcmp(ident, "VGAL") != 0) {
|
|
||||||
throw std::invalid_argument("Wrong file");
|
throw std::invalid_argument("Wrong file");
|
||||||
}
|
}
|
||||||
std::uint8_t version;
|
std::uint8_t version = read<std::uint8_t>(in);
|
||||||
in.read(reinterpret_cast<char *>(&version), 1);
|
|
||||||
|
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
while (in.peek() != EOF) {
|
while (in.peek() != EOF) {
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ namespace file
|
|||||||
{
|
{
|
||||||
namespace recording
|
namespace recording
|
||||||
{
|
{
|
||||||
RecordingEntry::RecordingEntry(
|
RecordingEntry::RecordingEntry(std::uint32_t time,
|
||||||
std::uint32_t time,
|
std::uint16_t altitude,
|
||||||
std::uint16_t altitude,
|
std::uint16_t groundSpeed,
|
||||||
std::uint16_t groundSpeed,
|
struct geodata::point coordinates)
|
||||||
struct germanairlinesva::geodata::point coordinates)
|
|
||||||
{
|
{
|
||||||
this->time = time;
|
this->time = time;
|
||||||
this->altitude = altitude;
|
this->altitude = altitude;
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
#include "simdata/runway.h"
|
|
||||||
|
|
||||||
namespace germanairlinesva
|
|
||||||
{
|
|
||||||
namespace file
|
|
||||||
{
|
|
||||||
namespace simdata
|
|
||||||
{
|
|
||||||
Runway::Runway(std::string designator,
|
|
||||||
double latitudeStart,
|
|
||||||
double longitudeStart,
|
|
||||||
double latitudeEnd,
|
|
||||||
double longitudeEnd,
|
|
||||||
double width)
|
|
||||||
{
|
|
||||||
this->designator = designator;
|
|
||||||
this->width = width;
|
|
||||||
this->length = germanairlinesva::geodata::distanceEarthD(latitudeStart,
|
|
||||||
longitudeStart,
|
|
||||||
latitudeEnd,
|
|
||||||
longitudeEnd);
|
|
||||||
this->trueHeading = (std::uint16_t)std::round(
|
|
||||||
germanairlinesva::geodata::bearingDD(latitudeStart,
|
|
||||||
longitudeStart,
|
|
||||||
latitudeEnd,
|
|
||||||
longitudeEnd));
|
|
||||||
this->bounds = germanairlinesva::geodata::calculateBoxDD(
|
|
||||||
{latitudeStart, longitudeStart},
|
|
||||||
{latitudeEnd, longitudeEnd},
|
|
||||||
this->trueHeading,
|
|
||||||
this->width);
|
|
||||||
}
|
|
||||||
|
|
||||||
Runway::Runway(std::string designator,
|
|
||||||
germanairlinesva::geodata::box bounds,
|
|
||||||
std::uint8_t width,
|
|
||||||
std::uint16_t length,
|
|
||||||
std::uint16_t trueHeading)
|
|
||||||
{
|
|
||||||
this->designator = designator;
|
|
||||||
this->bounds = bounds;
|
|
||||||
this->width = width;
|
|
||||||
this->length = length;
|
|
||||||
this->trueHeading = trueHeading;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Runway::toFile(std::ofstream &out) const
|
|
||||||
{
|
|
||||||
writeString(out, this->designator);
|
|
||||||
write<decltype(this->bounds)>(out, this->bounds);
|
|
||||||
write<decltype(this->width)>(out, this->width);
|
|
||||||
write<decltype(this->length)>(out, this->length);
|
|
||||||
write<decltype(this->trueHeading)>(out, this->trueHeading);
|
|
||||||
}
|
|
||||||
} // namespace simdata
|
|
||||||
} // namespace file
|
|
||||||
} // namespace germanairlinesva
|
|
||||||
+102
-20
@@ -6,33 +6,115 @@ namespace file
|
|||||||
{
|
{
|
||||||
namespace simdata
|
namespace simdata
|
||||||
{
|
{
|
||||||
void SimDatabase::toFile(std::ofstream &out) const
|
SimDatabase::SimDatabase(int xPlaneVersion,
|
||||||
|
const char *hash,
|
||||||
|
std::unique_ptr<config::Config> &configuration,
|
||||||
|
std::function<void(const std::string)> toLog)
|
||||||
{
|
{
|
||||||
write<std::uint16_t>(out, this->airports.size());
|
if (strcmp(configuration->getScenery().c_str(), hash) != 0 ||
|
||||||
for (const auto &airport : this->airports) {
|
!util::fileExists(XPLANE_PLUGIN_DIRECTORY SIMDATABASE)) {
|
||||||
writeString(out, airport.first);
|
scan(xPlaneVersion < 12000 ? XPLANE11_BASE_SCENERY
|
||||||
write<std::uint16_t>(out, airport.second.first.size());
|
: XPLANE12_BASE_SCENERY,
|
||||||
for (const Gate &gate : airport.second.first) {
|
XPLANE_CUSTOM_SCENERY,
|
||||||
gate.toFile(out);
|
XPLANE_PLUGIN_DIRECTORY "log.txt",
|
||||||
}
|
airports);
|
||||||
write<std::uint8_t>(out, airport.second.second.size());
|
|
||||||
for (const Runway &runway : airport.second.second) {
|
configuration->updateScenery(hash);
|
||||||
runway.toFile(out);
|
this->toFile();
|
||||||
}
|
|
||||||
|
toLog("Sim Database updated");
|
||||||
|
} else {
|
||||||
|
this->fromFile();
|
||||||
|
|
||||||
|
toLog("Sim Database loaded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Gate *SimDatabase::checkGate(
|
void SimDatabase::fromFile()
|
||||||
const std::string icao,
|
|
||||||
const struct germanairlinesva::geodata::point coordinates) const
|
|
||||||
{
|
{
|
||||||
auto airport = this->getAirport(icao);
|
std::ifstream in(XPLANE_PLUGIN_DIRECTORY SIMDATABASE,
|
||||||
for (const Gate &gate : airport.first) {
|
std::ifstream::binary);
|
||||||
if (gate.contains(coordinates)) {
|
|
||||||
return &gate;
|
// File Header
|
||||||
|
std::string ident = readString(in, 5);
|
||||||
|
if (ident.compare("VGAS") != 0) {
|
||||||
|
throw std::invalid_argument("Wrong file");
|
||||||
|
}
|
||||||
|
std::uint8_t version = read<std::uint8_t>(in);
|
||||||
|
|
||||||
|
if (version == 1) {
|
||||||
|
this->readVersion1(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimDatabase::readVersion1(std::ifstream &in)
|
||||||
|
{
|
||||||
|
std::uint16_t numAirports = read<std::uint16_t>(in);
|
||||||
|
|
||||||
|
for (int i = 0; i < numAirports; i++) {
|
||||||
|
// ICAO
|
||||||
|
std::string icao = readString(in);
|
||||||
|
// Gates
|
||||||
|
std::uint16_t numGates = read<std::uint16_t>(in);
|
||||||
|
for (int j = 0; j < numGates; j++) {
|
||||||
|
std::string designator = readString(in);
|
||||||
|
struct geodata::point center = read<struct geodata::point>(in);
|
||||||
|
std::uint8_t radius = read<std::uint8_t>(in);
|
||||||
|
|
||||||
|
this->airports[icao].first.emplace_back(designator, center, radius);
|
||||||
|
}
|
||||||
|
// Runways
|
||||||
|
std::uint8_t numRunways = read<std::uint8_t>(in);
|
||||||
|
for (int j = 0; j < numRunways; j++) {
|
||||||
|
std::string designator = readString(in);
|
||||||
|
// Center
|
||||||
|
struct geodata::point center = read<struct geodata::point>(in);
|
||||||
|
std::uint8_t width = read<std::uint8_t>(in);
|
||||||
|
std::uint16_t length = read<std::uint16_t>(in);
|
||||||
|
double trueHeading = read<double>(in);
|
||||||
|
|
||||||
|
this->airports[icao].second.emplace_back(designator,
|
||||||
|
center,
|
||||||
|
width,
|
||||||
|
length,
|
||||||
|
trueHeading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimDatabase::toFile() const
|
||||||
|
{
|
||||||
|
std::ofstream out(XPLANE_PLUGIN_DIRECTORY SIMDATABASE,
|
||||||
|
std::fstream::binary);
|
||||||
|
|
||||||
|
// File Header, Last member is version
|
||||||
|
std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1};
|
||||||
|
out.write(reinterpret_cast<const char *>(header), 6);
|
||||||
|
// Num Airports
|
||||||
|
write<std::uint16_t>(out, airports.size());
|
||||||
|
// Airport
|
||||||
|
for (const std::pair<const std::string,
|
||||||
|
std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airport : airports) {
|
||||||
|
std::string icao = airport.first;
|
||||||
|
const std::vector<Gate> gates = airport.second.first;
|
||||||
|
const std::vector<Runway> runways = airport.second.second;
|
||||||
|
// ICAO
|
||||||
|
writeString(out, icao);
|
||||||
|
// Gates
|
||||||
|
write<std::uint16_t>(out, gates.size());
|
||||||
|
for (const Gate &gate : gates) {
|
||||||
|
gate.toFile(out);
|
||||||
|
}
|
||||||
|
// Runways
|
||||||
|
write<std::uint8_t>(out, runways.size());
|
||||||
|
for (const Runway &runway : runways) {
|
||||||
|
runway.toFile(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
}
|
}
|
||||||
} // namespace simdata
|
} // namespace simdata
|
||||||
} // namespace file
|
} // namespace file
|
||||||
|
|||||||
+32
-31
@@ -6,10 +6,12 @@ namespace file
|
|||||||
{
|
{
|
||||||
namespace simdata
|
namespace simdata
|
||||||
{
|
{
|
||||||
int scan(const std::string defaultFile,
|
int scan(
|
||||||
const std::string sceneryPack,
|
const std::string defaultFile,
|
||||||
const std::string logFile,
|
const std::string sceneryPack,
|
||||||
SimDatabase &database)
|
const std::string logFile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports)
|
||||||
{
|
{
|
||||||
std::ifstream base(defaultFile);
|
std::ifstream base(defaultFile);
|
||||||
if (!base.good()) {
|
if (!base.good()) {
|
||||||
@@ -29,7 +31,7 @@ namespace file
|
|||||||
|
|
||||||
// Default
|
// Default
|
||||||
logfile << "<FILE> " << defaultFile << std::endl;
|
logfile << "<FILE> " << defaultFile << std::endl;
|
||||||
makeAirport("DEFAULT", base, database, logfile);
|
makeAirport("DEFAULT", base, airports, logfile);
|
||||||
base.close();
|
base.close();
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
@@ -37,9 +39,8 @@ namespace file
|
|||||||
std::vector<std::string> packs;
|
std::vector<std::string> packs;
|
||||||
while (std::getline(custom, line)) {
|
while (std::getline(custom, line)) {
|
||||||
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
||||||
std::string path =
|
std::string path = util::rtrim_copy(line.substr(pos + 13)) +
|
||||||
germanairlinesva::util::rtrim_copy(line.substr(pos + 13)) +
|
"Earth nav data/apt.dat";
|
||||||
"Earth nav data/apt.dat";
|
|
||||||
packs.emplace_back(path);
|
packs.emplace_back(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +50,7 @@ namespace file
|
|||||||
std::ifstream pack(path);
|
std::ifstream pack(path);
|
||||||
if (pack.good()) {
|
if (pack.good()) {
|
||||||
logfile << "<FILE> " << path << std::endl;
|
logfile << "<FILE> " << path << std::endl;
|
||||||
makeAirport("CUSTOM", pack, database, logfile);
|
makeAirport("CUSTOM", pack, airports, logfile);
|
||||||
pack.close();
|
pack.close();
|
||||||
} else {
|
} else {
|
||||||
pack.close();
|
pack.close();
|
||||||
@@ -59,18 +60,19 @@ namespace file
|
|||||||
}
|
}
|
||||||
|
|
||||||
logfile << std::endl
|
logfile << std::endl
|
||||||
<< "<STATUS> Total airports: " << database.numAirports()
|
<< "<STATUS> Total airports: " << airports.size() << std::endl;
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
custom.close();
|
custom.close();
|
||||||
logfile.close();
|
logfile.close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeAirport(const std::string &kind,
|
void makeAirport(
|
||||||
std::ifstream &infile,
|
const std::string &kind,
|
||||||
SimDatabase &database,
|
std::ifstream &infile,
|
||||||
std::ofstream &logfile)
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports,
|
||||||
|
std::ofstream &logfile)
|
||||||
{
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
std::string *currentIcao = nullptr;
|
std::string *currentIcao = nullptr;
|
||||||
@@ -81,11 +83,10 @@ namespace file
|
|||||||
int validCount = 0;
|
int validCount = 0;
|
||||||
|
|
||||||
while (std::getline(infile, line)) {
|
while (std::getline(infile, line)) {
|
||||||
std::vector<std::string> fields =
|
std::vector<std::string> fields = util::split(line, ' ');
|
||||||
germanairlinesva::util::split(line, ' ');
|
fields = util::select_T<std::string>(fields, [](const std::string &s) {
|
||||||
fields = germanairlinesva::util::select_T<std::string>(
|
return s.length() > 0;
|
||||||
fields,
|
});
|
||||||
[](const std::string &s) { return s.length() > 0; });
|
|
||||||
|
|
||||||
if (fields.empty())
|
if (fields.empty())
|
||||||
continue;
|
continue;
|
||||||
@@ -93,7 +94,7 @@ namespace file
|
|||||||
// Write to file if ICAO is valid, and we have gates and runways
|
// Write to file if ICAO is valid, and we have gates and runways
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||||
!tmpGates.empty()) {
|
!tmpGates.empty()) {
|
||||||
database.addAirport(*currentIcao, tmpGates, tmpRunways);
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
validCount += 1;
|
validCount += 1;
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@@ -113,7 +114,7 @@ namespace file
|
|||||||
// Write to file if ICAO is valid, and we have gates and runways
|
// Write to file if ICAO is valid, and we have gates and runways
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||||
!tmpGates.empty()) {
|
!tmpGates.empty()) {
|
||||||
database.addAirport(*currentIcao, tmpGates, tmpRunways);
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
validCount += 1;
|
validCount += 1;
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@@ -135,7 +136,7 @@ namespace file
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
|
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
|
||||||
database.addAirport(*currentIcao, tmpGates, tmpRunways);
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
validCount += 1;
|
validCount += 1;
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
||||||
}
|
}
|
||||||
@@ -152,10 +153,10 @@ namespace file
|
|||||||
}
|
}
|
||||||
gateName += fields.back();
|
gateName += fields.back();
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
struct germanairlinesva::geodata::point pt {
|
gates.emplace_back(gateName,
|
||||||
std::stod(fields[1]), std::stod(fields[2])
|
std::stod(fields[1]),
|
||||||
};
|
std::stod(fields[2]),
|
||||||
gates.emplace_back(gateName, pt, 40);
|
40);
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeRunway(std::vector<Runway> &runways,
|
void makeRunway(std::vector<Runway> &runways,
|
||||||
@@ -185,10 +186,10 @@ namespace file
|
|||||||
gateName += fields.back();
|
gateName += fields.back();
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
|
|
||||||
struct germanairlinesva::geodata::point pt {
|
gates.emplace_back(gateName,
|
||||||
std::stod(fields[1]), std::stod(fields[2])
|
std::stod(fields[1]),
|
||||||
};
|
std::stod(fields[2]),
|
||||||
gates.emplace_back(gateName, pt, 40);
|
40);
|
||||||
}
|
}
|
||||||
} // namespace simdata
|
} // namespace simdata
|
||||||
} // namespace file
|
} // namespace file
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ elseif(UNIX)
|
|||||||
)
|
)
|
||||||
target_link_libraries(ixwebsocket PRIVATE
|
target_link_libraries(ixwebsocket PRIVATE
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
pthread
|
|
||||||
)
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
if (BIT STREQUAL "32")
|
if (BIT STREQUAL "32")
|
||||||
@@ -107,10 +106,6 @@ elseif(WIN32)
|
|||||||
-Wl,-pdb=
|
-Wl,-pdb=
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
target_link_options(ixwebsocket PRIVATE
|
|
||||||
-static-libgcc
|
|
||||||
-static-libstdc++
|
|
||||||
)
|
|
||||||
target_include_directories(ixwebsocket PRIVATE
|
target_include_directories(ixwebsocket PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/openSSL/win${BIT}/include
|
${CMAKE_SOURCE_DIR}/openSSL/win${BIT}/include
|
||||||
)
|
)
|
||||||
@@ -124,4 +119,8 @@ elseif(WIN32)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(ixwebsocket PRIVATE
|
||||||
|
pthread
|
||||||
|
)
|
||||||
|
|
||||||
add_library(ixwebsocket::ixwebsocket ALIAS ixwebsocket)
|
add_library(ixwebsocket::ixwebsocket ALIAS ixwebsocket)
|
||||||
@@ -41,11 +41,16 @@ namespace geodata
|
|||||||
|
|
||||||
static inline double toRadians(double value) { return value * M_PI / 180; }
|
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);
|
return fmod(value + 360, 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double normalizeR(double value)
|
||||||
|
{
|
||||||
|
return value < 0 ? 2 * M_PI + value : value;
|
||||||
|
}
|
||||||
|
|
||||||
// Input and Output in degrees
|
// Input and Output in degrees
|
||||||
static inline double bearingDD(double fromLatitude,
|
static inline double bearingDD(double fromLatitude,
|
||||||
double fromLongitude,
|
double fromLongitude,
|
||||||
@@ -58,7 +63,22 @@ namespace geodata
|
|||||||
sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) *
|
sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) *
|
||||||
cos(toRadians(toLongitude) - toRadians(fromLongitude));
|
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
|
// Input in degrees, Output in metres
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ namespace util
|
|||||||
static inline int
|
static inline int
|
||||||
generateMD5(const char *filepath,
|
generateMD5(const char *filepath,
|
||||||
char *lastHash,
|
char *lastHash,
|
||||||
const std::function<void(const std::string)> &toLog)
|
const std::function<void(const std::string)> toLog)
|
||||||
{
|
{
|
||||||
int file_descript;
|
int file_descript;
|
||||||
unsigned long file_size;
|
unsigned long file_size;
|
||||||
@@ -205,7 +205,7 @@ namespace util
|
|||||||
static inline int
|
static inline int
|
||||||
generateMD5(const char *filepath,
|
generateMD5(const char *filepath,
|
||||||
char *buffer,
|
char *buffer,
|
||||||
const std::function<void(const std::string)> &toLog)
|
const std::function<void(const std::string)> toLog)
|
||||||
{
|
{
|
||||||
int file_descriptor;
|
int file_descriptor;
|
||||||
unsigned long file_size;
|
unsigned long file_size;
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
namespace germanairlinesva_websocket
|
{
|
||||||
|
namespace websocket
|
||||||
{
|
{
|
||||||
#pragma pack(push) /* push current alignment to stack */
|
#pragma pack(push) /* push current alignment to stack */
|
||||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||||
@@ -44,6 +45,7 @@ namespace germanairlinesva_websocket
|
|||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop) /* restore original alignment from stack */
|
#pragma pack(pop) /* restore original alignment from stack */
|
||||||
} // namespace germanairlinesva_websocket
|
} // namespace websocket
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace germanairlinesva_websocket
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace websocket
|
||||||
{
|
{
|
||||||
class Websocket
|
class Websocket
|
||||||
{
|
{
|
||||||
@@ -38,6 +40,7 @@ namespace germanairlinesva_websocket
|
|||||||
void onClientMessageCallback(const ix::WebSocketMessagePtr &msg);
|
void onClientMessageCallback(const ix::WebSocketMessagePtr &msg);
|
||||||
void sendData(data &d);
|
void sendData(data &d);
|
||||||
};
|
};
|
||||||
} // namespace germanairlinesva_websocket
|
} // namespace websocket
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+91
-90
@@ -1,113 +1,114 @@
|
|||||||
#include "include/websocket.h"
|
#include "include/websocket.h"
|
||||||
|
|
||||||
namespace germanairlinesva_websocket
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
Websocket::Websocket(std::string host,
|
namespace websocket
|
||||||
std::string user,
|
|
||||||
std::function<void(const std::string)> toLog)
|
|
||||||
: host(host), user(user), toLog(std::move(toLog))
|
|
||||||
{
|
{
|
||||||
|
Websocket::Websocket(std::string host,
|
||||||
|
std::string user,
|
||||||
|
std::function<void(const std::string)> toLog)
|
||||||
|
: host(host), user(user), toLog(std::move(toLog))
|
||||||
|
{
|
||||||
#ifdef IBM
|
#ifdef IBM
|
||||||
// Required on Windows
|
// Required on Windows
|
||||||
ix::initNetSystem();
|
ix::initNetSystem();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->webSocket = new ix::WebSocket();
|
this->webSocket = new ix::WebSocket();
|
||||||
this->webSocket->enableAutomaticReconnection();
|
this->webSocket->enableAutomaticReconnection();
|
||||||
this->webSocket->setUrl(host);
|
this->webSocket->setUrl(host);
|
||||||
this->webSocket->setOnMessageCallback(
|
this->webSocket->setOnMessageCallback(
|
||||||
[this](const ix::WebSocketMessagePtr &msg) {
|
[this](const ix::WebSocketMessagePtr &msg) {
|
||||||
this->onClientMessageCallback(msg);
|
this->onClientMessageCallback(msg);
|
||||||
});
|
});
|
||||||
this->webSocket->start();
|
this->webSocket->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Websocket::~Websocket()
|
Websocket::~Websocket()
|
||||||
{
|
{
|
||||||
this->webSocket->stop();
|
this->webSocket->stop();
|
||||||
this->toLog("WebSocket stopped");
|
this->toLog("WebSocket stopped");
|
||||||
#ifdef IBM
|
#ifdef IBM
|
||||||
// Required on Windows
|
// Required on Windows
|
||||||
ix::uninitNetSystem();
|
ix::uninitNetSystem();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Websocket::onClientMessageCallback(const ix::WebSocketMessagePtr &msg)
|
void Websocket::onClientMessageCallback(const ix::WebSocketMessagePtr &msg)
|
||||||
{
|
{
|
||||||
if (msg->type == ix::WebSocketMessageType::Open) {
|
if (msg->type == ix::WebSocketMessageType::Open) {
|
||||||
std::stringstream debug_msg;
|
|
||||||
|
|
||||||
debug_msg << std::endl << "New connection" << std::endl;
|
|
||||||
debug_msg << "Uri: " << msg->openInfo.uri << std::endl;
|
|
||||||
debug_msg << "Headers:" << std::endl;
|
|
||||||
for (const auto &it : msg->openInfo.headers) {
|
|
||||||
debug_msg << it.first << ": " << it.second << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->toLog(debug_msg.str());
|
|
||||||
|
|
||||||
this->webSocket->send("MASTER:" + user);
|
|
||||||
this->toLog("Connecting as " + user);
|
|
||||||
} else if (msg->type == ix::WebSocketMessageType::Close) {
|
|
||||||
if (msg->closeInfo.reason.compare("DUPLICATE") == 0) {
|
|
||||||
this->webSocket->disableAutomaticReconnection();
|
|
||||||
|
|
||||||
this->toLog("Disconnected due to beeing a duplicate simualtor");
|
|
||||||
} else {
|
|
||||||
std::stringstream debug_msg;
|
std::stringstream debug_msg;
|
||||||
|
|
||||||
debug_msg << std::endl << "Connection closed" << std::endl;
|
debug_msg << std::endl << "New connection" << std::endl;
|
||||||
debug_msg << "Code: " << msg->closeInfo.code << std::endl;
|
debug_msg << "Uri: " << msg->openInfo.uri << std::endl;
|
||||||
debug_msg << "Reason: " << msg->closeInfo.reason << std::endl;
|
debug_msg << "Headers:" << std::endl;
|
||||||
debug_msg << "Remote: " << msg->closeInfo.remote << std::endl;
|
for (const auto &it : msg->openInfo.headers) {
|
||||||
|
debug_msg << it.first << ": " << it.second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
this->toLog(debug_msg.str());
|
this->toLog(debug_msg.str());
|
||||||
}
|
|
||||||
} else if (msg->type == ix::WebSocketMessageType::Error) {
|
|
||||||
std::stringstream debug_msg;
|
|
||||||
|
|
||||||
debug_msg << std::endl << "Connection error" << std::endl;
|
this->webSocket->send("MASTER:" + user);
|
||||||
debug_msg << "Decompression: " << msg->errorInfo.decompressionError
|
this->toLog("Connecting as " + user);
|
||||||
<< std::endl;
|
} else if (msg->type == ix::WebSocketMessageType::Close) {
|
||||||
debug_msg << "HTTP status: " << msg->errorInfo.http_status << std::endl;
|
if (msg->closeInfo.reason.compare("DUPLICATE") == 0) {
|
||||||
debug_msg << "Reason: " << msg->errorInfo.reason << std::endl;
|
this->webSocket->disableAutomaticReconnection();
|
||||||
debug_msg << "Retries: " << msg->errorInfo.retries << std::endl;
|
|
||||||
debug_msg << "Wait time: " << msg->errorInfo.wait_time << std::endl;
|
|
||||||
|
|
||||||
this->toLog(debug_msg.str());
|
this->toLog("Disconnected due to beeing a duplicate simualtor");
|
||||||
} else if (msg->type == ix::WebSocketMessageType::Message) {
|
} else {
|
||||||
if (!msg->str.empty()) {
|
std::stringstream debug_msg;
|
||||||
this->toLog(msg->str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Websocket::sendData(data &d)
|
debug_msg << std::endl << "Connection closed" << std::endl;
|
||||||
{
|
debug_msg << "Code: " << msg->closeInfo.code << std::endl;
|
||||||
if (strcmp(d.path, this->lastPath) != 0) {
|
debug_msg << "Reason: " << msg->closeInfo.reason << std::endl;
|
||||||
strcpy(this->lastPath, d.path);
|
debug_msg << "Remote: " << msg->closeInfo.remote << std::endl;
|
||||||
if (germanairlinesva::util::generateMD5(d.path,
|
|
||||||
this->lastHash,
|
this->toLog(debug_msg.str());
|
||||||
this->toLog)) {
|
}
|
||||||
strcpy(this->lastHash, "NOT SET");
|
} else if (msg->type == ix::WebSocketMessageType::Error) {
|
||||||
|
std::stringstream debug_msg;
|
||||||
|
|
||||||
|
debug_msg << std::endl << "Connection error" << std::endl;
|
||||||
|
debug_msg << "Decompression: " << msg->errorInfo.decompressionError
|
||||||
|
<< std::endl;
|
||||||
|
debug_msg << "HTTP status: " << msg->errorInfo.http_status << std::endl;
|
||||||
|
debug_msg << "Reason: " << msg->errorInfo.reason << std::endl;
|
||||||
|
debug_msg << "Retries: " << msg->errorInfo.retries << std::endl;
|
||||||
|
debug_msg << "Wait time: " << msg->errorInfo.wait_time << std::endl;
|
||||||
|
|
||||||
|
this->toLog(debug_msg.str());
|
||||||
|
} else if (msg->type == ix::WebSocketMessageType::Message) {
|
||||||
|
if (!msg->str.empty()) {
|
||||||
|
this->toLog(msg->str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json json = {
|
void Websocket::sendData(data &d)
|
||||||
{"altitude", d.alt},
|
{
|
||||||
{"vs", d.vs},
|
if (strcmp(d.path, this->lastPath) != 0) {
|
||||||
{"ias", d.ias},
|
strcpy(this->lastPath, d.path);
|
||||||
{"magHdg", d.magHeading},
|
if (util::generateMD5(d.path, this->lastHash, this->toLog)) {
|
||||||
{"truHdg", d.truHdg},
|
strcpy(this->lastHash, "NOT SET");
|
||||||
{"totFuel", d.totFuelKg},
|
}
|
||||||
{"fuelFlow", d.ff},
|
}
|
||||||
{"hash", this->lastHash},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this->webSocket != nullptr) {
|
nlohmann::json json = {
|
||||||
std::ostringstream msg;
|
{"altitude", d.alt},
|
||||||
msg << "SEND:" << user << ":" << json.dump();
|
{"vs", d.vs},
|
||||||
this->webSocket->send(msg.str(), false);
|
{"ias", d.ias},
|
||||||
|
{"magHdg", d.magHeading},
|
||||||
|
{"truHdg", d.truHdg},
|
||||||
|
{"totFuel", d.totFuelKg},
|
||||||
|
{"fuelFlow", d.ff},
|
||||||
|
{"hash", this->lastHash},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this->webSocket != nullptr) {
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "SEND:" << user << ":" << json.dump();
|
||||||
|
this->webSocket->send(msg.str(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace websocket
|
||||||
} // namespace germanairlinesva_websocket
|
} // namespace germanairlinesva
|
||||||
@@ -80,9 +80,6 @@ elseif(UNIX)
|
|||||||
target_compile_options(germanairlinesva_xplugin PRIVATE
|
target_compile_options(germanairlinesva_xplugin PRIVATE
|
||||||
-nodefaultlibs
|
-nodefaultlibs
|
||||||
)
|
)
|
||||||
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
|
||||||
pthread
|
|
||||||
)
|
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
message("Building for Windows ${BIT} into ${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}")
|
message("Building for Windows ${BIT} into ${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}")
|
||||||
|
|
||||||
@@ -102,12 +99,6 @@ elseif(WIN32)
|
|||||||
-Wl,-pdb=
|
-Wl,-pdb=
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
target_link_options(germanairlinesva_xplugin PRIVATE
|
|
||||||
-static-libgcc
|
|
||||||
-static-libstdc++
|
|
||||||
)
|
|
||||||
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
|
||||||
)
|
|
||||||
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/XPSDK/Libraries/Win/XPLM_64.lib
|
${CMAKE_SOURCE_DIR}/XPSDK/Libraries/Win/XPLM_64.lib
|
||||||
)
|
)
|
||||||
@@ -118,4 +109,5 @@ endif()
|
|||||||
|
|
||||||
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
||||||
ixwebsocket
|
ixwebsocket
|
||||||
|
pthread
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "logbook/logbook.h"
|
#include "logbook/logbook.h"
|
||||||
#include "recording/recording.h"
|
#include "recording/recording.h"
|
||||||
|
#include "simdata/simDatabase.h"
|
||||||
#include "simdata/simdataXP.h"
|
#include "simdata/simdataXP.h"
|
||||||
#include "simdata/simulatorDatabase.hpp"
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "websocket.h"
|
#include "websocket.h"
|
||||||
|
|
||||||
|
|||||||
+43
-66
@@ -10,9 +10,9 @@ std::thread serverThread;
|
|||||||
std::thread recordingThread;
|
std::thread recordingThread;
|
||||||
std::atomic<bool> wantsExit;
|
std::atomic<bool> wantsExit;
|
||||||
|
|
||||||
germanairlinesva::file::config::Config configuration;
|
std::unique_ptr<germanairlinesva::file::config::Config> configuration;
|
||||||
germanairlinesva::file::simdata::SimDatabase database;
|
std::unique_ptr<germanairlinesva::file::simdata::SimDatabase> database;
|
||||||
germanairlinesva_websocket::Websocket *connector;
|
std::unique_ptr<germanairlinesva::websocket::Websocket> connector;
|
||||||
int xplaneVersion;
|
int xplaneVersion;
|
||||||
|
|
||||||
/* Datarefs */
|
/* Datarefs */
|
||||||
@@ -43,7 +43,7 @@ XPLMDataRef pitch;
|
|||||||
XPLMDataRef roll;
|
XPLMDataRef roll;
|
||||||
XPLMDataRef quaternion;
|
XPLMDataRef quaternion;
|
||||||
|
|
||||||
struct germanairlinesva_websocket::data toSend;
|
struct germanairlinesva::websocket::data toSend;
|
||||||
germanairlinesva::file::recording::Recording p;
|
germanairlinesva::file::recording::Recording p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -111,67 +111,41 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
|||||||
roll = XPLMFindDataRef("sim/flightmodel/position/phi"); // FLOAT
|
roll = XPLMFindDataRef("sim/flightmodel/position/phi"); // FLOAT
|
||||||
quaternion = XPLMFindDataRef("sim/flightmodel/position/q"); // FLOAT[4]
|
quaternion = XPLMFindDataRef("sim/flightmodel/position/q"); // FLOAT[4]
|
||||||
|
|
||||||
configuration = germanairlinesva::file::config::Config();
|
configuration = std::make_unique<germanairlinesva::file::config::Config>();
|
||||||
toLog("Config loaded");
|
toLog("Config loaded");
|
||||||
/*
|
|
||||||
try {
|
connector = std::make_unique<germanairlinesva::websocket::Websocket>(
|
||||||
connector = new germanairlinesva_websocket::Websocket(
|
"wss://ws.hofmannnet.myhome-server.de:8000",
|
||||||
"wss://ws.hofmannnet.myhome-server.de:8000",
|
configuration->getUser(),
|
||||||
configuration.getUser(),
|
toLog);
|
||||||
toLog);
|
toLog("WebSocket started");
|
||||||
} catch (const std::invalid_argument &e) {
|
|
||||||
toLog(e.what());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
toLog("WebSocket started");
|
|
||||||
*/
|
|
||||||
char hash[2 * MD5LEN + 1] = "";
|
char hash[2 * MD5LEN + 1] = "";
|
||||||
if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) ==
|
if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) ==
|
||||||
0) {
|
0) {
|
||||||
|
database = std::make_unique<germanairlinesva::file::simdata::SimDatabase>(
|
||||||
if (strcmp(configuration.getScenery().c_str(), hash) != 0 ||
|
xplaneVersion,
|
||||||
!germanairlinesva::util::fileExists(
|
hash,
|
||||||
XPLANE_PLUGIN_DIRECTORY SIMDATABASE)) {
|
configuration,
|
||||||
scan(xplaneVersion < 12000 ? XPLANE11_BASE_SCENERY
|
toLog);
|
||||||
: XPLANE12_BASE_SCENERY,
|
|
||||||
XPLANE_CUSTOM_SCENERY,
|
|
||||||
XPLANE_PLUGIN_DIRECTORY "log.txt",
|
|
||||||
database);
|
|
||||||
germanairlinesva::file::simdata::toFile(
|
|
||||||
database,
|
|
||||||
XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
|
|
||||||
|
|
||||||
configuration.updateScenery(hash);
|
|
||||||
toLog("Sim Database updated");
|
|
||||||
} else {
|
|
||||||
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 = 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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Thread for sending data to websocket
|
||||||
// serverThread = std::thread(&serverWorker);
|
serverThread = std::thread(&serverWorker);
|
||||||
// recordingThread = std::thread(&recordingWorker);
|
recordingThread = std::thread(&recordingWorker);
|
||||||
toLog("Workers started");
|
toLog("Workers started");
|
||||||
|
|
||||||
toLog("Logbook Test");
|
toLog("Logbook Test");
|
||||||
@@ -216,9 +190,12 @@ PLUGIN_API void XPluginStop(void)
|
|||||||
XPLMUnregisterFlightLoopCallback(flightLoop, nullptr);
|
XPLMUnregisterFlightLoopCallback(flightLoop, nullptr);
|
||||||
/* End threads */
|
/* End threads */
|
||||||
wantsExit = true;
|
wantsExit = true;
|
||||||
// serverThread.join();
|
serverThread.join();
|
||||||
// recordingThread.join();
|
recordingThread.join();
|
||||||
// delete connector;
|
|
||||||
|
delete connector.release();
|
||||||
|
delete database.release();
|
||||||
|
delete configuration.release();
|
||||||
|
|
||||||
p.toFile("flight.rec");
|
p.toFile("flight.rec");
|
||||||
|
|
||||||
@@ -243,7 +220,7 @@ float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
|||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
std::memset(&toSend, 0, sizeof(germanairlinesva_websocket::data));
|
std::memset(&toSend, 0, sizeof(germanairlinesva::websocket::data));
|
||||||
|
|
||||||
toSend.pause = XPLMGetDatai(pauseIndicator);
|
toSend.pause = XPLMGetDatai(pauseIndicator);
|
||||||
toSend.pBrake = XPLMGetDataf(parkingBrake);
|
toSend.pBrake = XPLMGetDataf(parkingBrake);
|
||||||
@@ -284,11 +261,11 @@ void serverWorker()
|
|||||||
germanairlinesva::util::setThreadName("GAServerWorker");
|
germanairlinesva::util::setThreadName("GAServerWorker");
|
||||||
|
|
||||||
while (!wantsExit) {
|
while (!wantsExit) {
|
||||||
struct germanairlinesva_websocket::data copy;
|
struct germanairlinesva::websocket::data copy;
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
std::memcpy(©, &toSend, sizeof(germanairlinesva_websocket::data));
|
std::memcpy(©, &toSend, sizeof(germanairlinesva::websocket::data));
|
||||||
}
|
}
|
||||||
|
|
||||||
connector->sendData(copy);
|
connector->sendData(copy);
|
||||||
@@ -307,11 +284,11 @@ void recordingWorker()
|
|||||||
std::uint32_t segment = 0;
|
std::uint32_t segment = 0;
|
||||||
|
|
||||||
while (!wantsExit) {
|
while (!wantsExit) {
|
||||||
germanairlinesva_websocket::data copy;
|
germanairlinesva::websocket::data copy;
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
std::memcpy(©, &toSend, sizeof(germanairlinesva_websocket::data));
|
std::memcpy(©, &toSend, sizeof(germanairlinesva::websocket::data));
|
||||||
}
|
}
|
||||||
|
|
||||||
germanairlinesva::file::recording::RecordingEntry currentPath(
|
germanairlinesva::file::recording::RecordingEntry currentPath(
|
||||||
|
|||||||
Reference in New Issue
Block a user