Runways and Gates now with new read/write
This commit is contained in:
parent
2fc2170763
commit
94fbc1f558
48
.vscode/c_cpp_properties.json
vendored
Normal file
48
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"configurations": [{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"LIN",
|
||||||
|
"XPLM200",
|
||||||
|
"XPLM210"
|
||||||
|
],
|
||||||
|
"compilerPath": "/opt/llvm-mingw/bin/clang",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"intelliSenseMode": "linux-clang-x64"
|
||||||
|
}, {
|
||||||
|
"name": "Windows",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"IBM",
|
||||||
|
"XPLM200",
|
||||||
|
"XPLM210"
|
||||||
|
],
|
||||||
|
"compilerPath": "/opt/llvm-mingw/bin/x86_64-w64-mingw32-clang",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"intelliSenseMode": "windows-clang-x64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"APL",
|
||||||
|
"XPLM200",
|
||||||
|
"XPLM210"
|
||||||
|
],
|
||||||
|
"compilerPath": "/opt/osxcross/target/bin/o64-clang",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"intelliSenseMode": "macos-clang-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
@ -16,9 +16,6 @@ option(DEBUG "Debug symbols" OFF)
|
|||||||
add_subdirectory(
|
add_subdirectory(
|
||||||
ixwebsocket
|
ixwebsocket
|
||||||
)
|
)
|
||||||
add_subdirectory(
|
|
||||||
simdata
|
|
||||||
)
|
|
||||||
add_subdirectory(
|
add_subdirectory(
|
||||||
file
|
file
|
||||||
)
|
)
|
||||||
|
|||||||
26
file/gate.cpp
Normal file
26
file/gate.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "simdata/gate.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace simdata
|
||||||
|
{
|
||||||
|
Gate::Gate(std::string designator,
|
||||||
|
struct germanairlinesva::geodata::point center,
|
||||||
|
std::uint8_t radius)
|
||||||
|
{
|
||||||
|
this->designator = designator;
|
||||||
|
this->center = center;
|
||||||
|
this->radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gate::toFile(std::ofstream &out) const
|
||||||
|
{
|
||||||
|
writeString(out, this->designator);
|
||||||
|
write<struct germanairlinesva::geodata::point>(out, this->center);
|
||||||
|
write<std::uint8_t>(out, this->radius);
|
||||||
|
}
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
@ -25,10 +25,10 @@ namespace file
|
|||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(config, line)) {
|
while (std::getline(config, line)) {
|
||||||
std::vector<std::string> fields =
|
std::vector<std::string> fields =
|
||||||
germanairlinesva_util::split(line, '=');
|
germanairlinesva::util::split(line, '=');
|
||||||
if (fields.size() >= 2) {
|
if (fields.size() >= 2) {
|
||||||
germanairlinesva_util::trim(fields[0]);
|
germanairlinesva::util::trim(fields[0]);
|
||||||
germanairlinesva_util::trim(fields[1]);
|
germanairlinesva::util::trim(fields[1]);
|
||||||
settings[fields[0]] = fields[1];
|
settings[fields[0]] = fields[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "geodata.h"
|
#include "geodata.hpp"
|
||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ namespace file
|
|||||||
std::uint32_t time = 0;
|
std::uint32_t time = 0;
|
||||||
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;
|
struct germanairlinesva::geodata::point coordinates;
|
||||||
std::vector<std::uint8_t> file;
|
std::vector<std::uint8_t> file;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -33,7 +33,7 @@ namespace file
|
|||||||
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 germanairlinesva::geodata::point coordinates);
|
||||||
|
|
||||||
inline const std::uint8_t *getBinaryData() const { return file.data(); }
|
inline const std::uint8_t *getBinaryData() const { return file.data(); }
|
||||||
inline std::size_t getBinaryLength() const { return file.size(); }
|
inline std::size_t getBinaryLength() const { return file.size(); }
|
||||||
|
|||||||
67
file/include/simdata/gate.h
Normal file
67
file/include/simdata/gate.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_GATE_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_GATE_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <streambuf>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "geodata.hpp"
|
||||||
|
#include "helpers.hpp"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace simdata
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Representation of gate
|
||||||
|
* Heading in degrees (0...360)
|
||||||
|
* Radius in metres
|
||||||
|
*
|
||||||
|
* Designator must be null terminated
|
||||||
|
*
|
||||||
|
* UINT8 | CHAR[] | POINT | UINT8
|
||||||
|
* -------+------------+--------+-------
|
||||||
|
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
||||||
|
*/
|
||||||
|
class Gate
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string designator;
|
||||||
|
struct germanairlinesva::geodata::point center;
|
||||||
|
std::uint8_t radius;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Gate(std::string designator,
|
||||||
|
struct germanairlinesva::geodata::point center,
|
||||||
|
std::uint8_t radius);
|
||||||
|
|
||||||
|
void toFile(std::ofstream &out) const;
|
||||||
|
|
||||||
|
inline const std::string to_string() const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "Gate " << this->designator << " at " << this->center.latitude
|
||||||
|
<< "N " << this->center.longitude << "E, Radius "
|
||||||
|
<< (int)this->radius;
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline std::ostream &operator<<(std::ostream &os,
|
||||||
|
const Gate &gate)
|
||||||
|
{
|
||||||
|
return os << gate.to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
87
file/include/simdata/runway.h
Normal file
87
file/include/simdata/runway.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_RUNWAY_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_RUNWAY_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "geodata.hpp"
|
||||||
|
#include "helpers.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace simdata
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Representation of one runway with supplementary information
|
||||||
|
* Heading in degrees (0...360) true
|
||||||
|
* Width and length in meters
|
||||||
|
*
|
||||||
|
* Designator must be null terminated
|
||||||
|
*
|
||||||
|
* UINT8 | CHAR[] | BOX | UINT8 | UINT16 | UINT16
|
||||||
|
* -------+------------+--------+-------+--------+-------
|
||||||
|
* STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG
|
||||||
|
*/
|
||||||
|
class Runway
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string designator;
|
||||||
|
struct germanairlinesva::geodata::box bounds;
|
||||||
|
std::uint8_t width;
|
||||||
|
std::uint16_t length;
|
||||||
|
std::uint16_t trueHeading;
|
||||||
|
std::vector<std::uint8_t> file;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// From X-Plane or MakeRwys
|
||||||
|
Runway(std::string designator,
|
||||||
|
double latitudeStart,
|
||||||
|
double longitudeStart,
|
||||||
|
double latitudeEnd,
|
||||||
|
double longitudeEnd,
|
||||||
|
double width);
|
||||||
|
// From database
|
||||||
|
Runway(std::string designator,
|
||||||
|
struct germanairlinesva::geodata::box bounds,
|
||||||
|
std::uint8_t width,
|
||||||
|
std::uint16_t length,
|
||||||
|
std::uint16_t trueHeading);
|
||||||
|
|
||||||
|
void toFile(std::ofstream &out) const;
|
||||||
|
|
||||||
|
inline const std::string to_string() const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "Runway " << this->designator << " with bounds "
|
||||||
|
<< this->bounds.topLeft.latitude << "N "
|
||||||
|
<< this->bounds.topLeft.longitude << "E, "
|
||||||
|
<< this->bounds.topRight.latitude << "N "
|
||||||
|
<< this->bounds.topRight.longitude << "E, "
|
||||||
|
<< this->bounds.bottomRight.latitude << "N "
|
||||||
|
<< this->bounds.bottomRight.longitude << "E, "
|
||||||
|
<< this->bounds.bottomLeft.latitude << "N "
|
||||||
|
<< this->bounds.bottomLeft.longitude << "E, "
|
||||||
|
<< "Width " << (int)this->width << "m, Length " << this->length
|
||||||
|
<< "m, True Heading " << this->trueHeading << "°";
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline std::ostream &operator<<(std::ostream &os,
|
||||||
|
const Runway &runway)
|
||||||
|
{
|
||||||
|
return os << runway.to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
41
file/include/simdata/simdataXP.h
Normal file
41
file/include/simdata/simdataXP.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef GERMANAIRLINESVA_FILE_SIMDATAXP_H
|
||||||
|
#define GERMANAIRLINESVA_FILE_SIMDATAXP_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "simdata/gate.h"
|
||||||
|
#include "simdata/runway.h"
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace simdata
|
||||||
|
{
|
||||||
|
int scan(
|
||||||
|
const std::string defaultFile,
|
||||||
|
const std::string sceneryPack,
|
||||||
|
const std::string logFile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports);
|
||||||
|
|
||||||
|
void makeAirport(
|
||||||
|
const std::string &kind,
|
||||||
|
std::ifstream &infile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports,
|
||||||
|
std::ofstream &logfile);
|
||||||
|
void makeGate15(std::vector<Gate> &gates,
|
||||||
|
const std::vector<std::string> &fields);
|
||||||
|
void makeRunway(std::vector<Runway> &runways,
|
||||||
|
const std::vector<std::string> &fields);
|
||||||
|
void makeGate1300(std::vector<Gate> &gates,
|
||||||
|
const std::vector<std::string> &fields);
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
174
file/include/simdata/simulatorDatabase.hpp
Normal file
174
file/include/simdata/simulatorDatabase.hpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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(
|
||||||
|
std::map<
|
||||||
|
std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
&airports,
|
||||||
|
const std::string &file)
|
||||||
|
{
|
||||||
|
std::uint8_t null = 0;
|
||||||
|
std::ofstream out(file, std::fstream::binary);
|
||||||
|
|
||||||
|
// File Header, Last member is version
|
||||||
|
std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1};
|
||||||
|
out.write(reinterpret_cast<const char *>(header), 6);
|
||||||
|
// Num Airports
|
||||||
|
std::uint16_t numAirports = airports.size();
|
||||||
|
out.write(reinterpret_cast<const char *>(&numAirports),
|
||||||
|
sizeof(numAirports));
|
||||||
|
// Airport
|
||||||
|
for (const std::pair<
|
||||||
|
const std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
&airport : airports) {
|
||||||
|
std::string icao = airport.first;
|
||||||
|
std::vector<germanairlinesva::file::simdata::Gate> gates =
|
||||||
|
airport.second.first;
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway> runways =
|
||||||
|
airport.second.second;
|
||||||
|
// ICAO
|
||||||
|
std::uint8_t icaoLength = icao.length();
|
||||||
|
out.write(reinterpret_cast<const char *>(&icaoLength),
|
||||||
|
sizeof(icaoLength));
|
||||||
|
out.write(icao.c_str(), icaoLength);
|
||||||
|
out.write(reinterpret_cast<const char *>(&null), sizeof(null));
|
||||||
|
// Gates
|
||||||
|
std::uint16_t numGates = gates.size();
|
||||||
|
out.write(reinterpret_cast<const char *>(&numGates), sizeof(numGates));
|
||||||
|
for (germanairlinesva::file::simdata::Gate &gate : gates) {
|
||||||
|
gate.toFile(out);
|
||||||
|
}
|
||||||
|
// Runways
|
||||||
|
std::uint8_t numRunways = runways.size();
|
||||||
|
out.write(reinterpret_cast<const char *>(&numRunways),
|
||||||
|
sizeof(numRunways));
|
||||||
|
for (germanairlinesva::file::simdata::Runway &runway : runways) {
|
||||||
|
runway.toFile(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::map<
|
||||||
|
std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
readVersion1(std::ifstream &in)
|
||||||
|
{
|
||||||
|
std::map<std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
airports;
|
||||||
|
|
||||||
|
std::uint16_t numAirports;
|
||||||
|
in.read(reinterpret_cast<char *>(&numAirports), sizeof(numAirports));
|
||||||
|
|
||||||
|
for (int i = 0; i < numAirports; i++) {
|
||||||
|
// ICAO
|
||||||
|
std::uint8_t icaoLength;
|
||||||
|
in.read(reinterpret_cast<char *>(&icaoLength), sizeof(icaoLength));
|
||||||
|
char *icao = static_cast<char *>(calloc(icaoLength + 1, sizeof(char)));
|
||||||
|
in.read(icao, icaoLength + 1);
|
||||||
|
// Gates
|
||||||
|
std::uint16_t numGates;
|
||||||
|
in.read(reinterpret_cast<char *>(&numGates), sizeof(numGates));
|
||||||
|
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);
|
||||||
|
|
||||||
|
airports[icao].first.emplace_back(designator, center, radius);
|
||||||
|
}
|
||||||
|
// Runways
|
||||||
|
std::uint8_t numRunways;
|
||||||
|
in.read(reinterpret_cast<char *>(&numRunways), sizeof(numRunways));
|
||||||
|
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);
|
||||||
|
|
||||||
|
airports[icao].second.emplace_back(designator,
|
||||||
|
bounds,
|
||||||
|
width,
|
||||||
|
length,
|
||||||
|
trueHeading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
return airports;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::map<
|
||||||
|
std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
fromFile(const std::string &file)
|
||||||
|
{
|
||||||
|
std::map<std::string,
|
||||||
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
|
airports;
|
||||||
|
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;
|
||||||
|
in.read(reinterpret_cast<char *>(&version), 1);
|
||||||
|
|
||||||
|
if (version == 1) {
|
||||||
|
return readVersion1(in);
|
||||||
|
}
|
||||||
|
return airports;
|
||||||
|
}
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -8,7 +8,7 @@ namespace file
|
|||||||
{
|
{
|
||||||
Logbook::Logbook()
|
Logbook::Logbook()
|
||||||
{
|
{
|
||||||
if (germanairlinesva_util::fileExists(XPLANE_PLUGIN_DIRECTORY LOGBOOK)) {
|
if (germanairlinesva::util::fileExists(XPLANE_PLUGIN_DIRECTORY LOGBOOK)) {
|
||||||
this->fromFile(XPLANE_PLUGIN_DIRECTORY LOGBOOK);
|
this->fromFile(XPLANE_PLUGIN_DIRECTORY LOGBOOK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace file
|
|||||||
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 germanairlinesva_geodata::point coordinates)
|
struct germanairlinesva::geodata::point coordinates)
|
||||||
{
|
{
|
||||||
this->time = time;
|
this->time = time;
|
||||||
this->altitude = altitude;
|
this->altitude = altitude;
|
||||||
|
|||||||
57
file/runway.cpp
Normal file
57
file/runway.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#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<struct germanairlinesva::geodata::box>(out, this->bounds);
|
||||||
|
write<std::uint8_t>(out, this->width);
|
||||||
|
write<std::uint16_t>(out, this->length);
|
||||||
|
write<std::uint16_t>(out, this->trueHeading);
|
||||||
|
}
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
198
file/simdataXP.cpp
Normal file
198
file/simdataXP.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
#include "simdata/simdataXP.h"
|
||||||
|
|
||||||
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace file
|
||||||
|
{
|
||||||
|
namespace simdata
|
||||||
|
{
|
||||||
|
int scan(
|
||||||
|
const std::string defaultFile,
|
||||||
|
const std::string sceneryPack,
|
||||||
|
const std::string logFile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports)
|
||||||
|
{
|
||||||
|
std::ifstream base(defaultFile);
|
||||||
|
if (!base.good()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::ifstream custom(sceneryPack);
|
||||||
|
if (!custom.good()) {
|
||||||
|
base.close();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
std::ofstream logfile(logFile, std::fstream::trunc);
|
||||||
|
if (!logfile.good()) {
|
||||||
|
base.close();
|
||||||
|
custom.close();
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default
|
||||||
|
logfile << "<FILE> " << defaultFile << std::endl;
|
||||||
|
makeAirport("DEFAULT", base, airports, logfile);
|
||||||
|
base.close();
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
size_t pos;
|
||||||
|
std::vector<std::string> packs;
|
||||||
|
while (std::getline(custom, line)) {
|
||||||
|
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
||||||
|
std::string path =
|
||||||
|
germanairlinesva::util::rtrim_copy(line.substr(pos + 13)) +
|
||||||
|
"Earth nav data/apt.dat";
|
||||||
|
packs.emplace_back(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::reverse(packs.begin(), packs.end());
|
||||||
|
|
||||||
|
for (std::string const &path : packs) {
|
||||||
|
std::ifstream pack(path);
|
||||||
|
if (pack.good()) {
|
||||||
|
logfile << "<FILE> " << path << std::endl;
|
||||||
|
makeAirport("CUSTOM", pack, airports, logfile);
|
||||||
|
pack.close();
|
||||||
|
} else {
|
||||||
|
pack.close();
|
||||||
|
logfile << "<STATUS>"
|
||||||
|
<< "Could not find " << path << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logfile << std::endl
|
||||||
|
<< "<STATUS> Total airports: " << airports.size() << std::endl;
|
||||||
|
|
||||||
|
custom.close();
|
||||||
|
logfile.close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeAirport(
|
||||||
|
const std::string &kind,
|
||||||
|
std::ifstream &infile,
|
||||||
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||||
|
&airports,
|
||||||
|
std::ofstream &logfile)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::string *currentIcao = nullptr;
|
||||||
|
std::vector<Gate> tmpGates;
|
||||||
|
std::vector<Runway> tmpRunways;
|
||||||
|
|
||||||
|
int apCount = 0;
|
||||||
|
int validCount = 0;
|
||||||
|
|
||||||
|
while (std::getline(infile, line)) {
|
||||||
|
std::vector<std::string> fields =
|
||||||
|
germanairlinesva::util::split(line, ' ');
|
||||||
|
fields = germanairlinesva::util::select_T<std::string>(
|
||||||
|
fields,
|
||||||
|
[](const std::string &s) { return s.length() > 0; });
|
||||||
|
|
||||||
|
if (fields.empty())
|
||||||
|
continue;
|
||||||
|
if (fields[0] == "1") {
|
||||||
|
// Write to file if ICAO is valid, and we have gates and runways
|
||||||
|
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||||
|
!tmpGates.empty()) {
|
||||||
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
|
validCount += 1;
|
||||||
|
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||||
|
<< std::endl;
|
||||||
|
} else if (currentIcao != nullptr) {
|
||||||
|
logfile << "\t<STATUS> " << *currentIcao
|
||||||
|
<< " had no gates or runways" << std::endl;
|
||||||
|
}
|
||||||
|
tmpGates = std::vector<Gate>();
|
||||||
|
tmpRunways = std::vector<Runway>();
|
||||||
|
currentIcao = new std::string(fields[4]);
|
||||||
|
apCount += 1;
|
||||||
|
logfile << "\t<" << kind << "> " << line << std::endl;
|
||||||
|
} else if (currentIcao != nullptr && fields[0] == "15") {
|
||||||
|
makeGate15(tmpGates, fields);
|
||||||
|
logfile << "\t\t<GATE OLD> " << line << std::endl;
|
||||||
|
} else if (fields[0] == "16" || fields[0] == "17") {
|
||||||
|
// Write to file if ICAO is valid, and we have gates and runways
|
||||||
|
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||||
|
!tmpGates.empty()) {
|
||||||
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
|
validCount += 1;
|
||||||
|
logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||||
|
<< std::endl;
|
||||||
|
} else if (currentIcao != nullptr) {
|
||||||
|
logfile << "\t<STATUS> " << *currentIcao
|
||||||
|
<< " had no gates or runways" << std::endl;
|
||||||
|
}
|
||||||
|
tmpGates = std::vector<Gate>();
|
||||||
|
tmpRunways = std::vector<Runway>();
|
||||||
|
currentIcao = nullptr;
|
||||||
|
logfile << "\t<" << kind << " SKIPPED> " << line << std::endl;
|
||||||
|
} else if (currentIcao != nullptr && fields[0] == "100") {
|
||||||
|
makeRunway(tmpRunways, fields);
|
||||||
|
logfile << "\t\t<RUNWAY> " << line << std::endl;
|
||||||
|
} else if (currentIcao != nullptr && fields[0] == "1300") {
|
||||||
|
makeGate1300(tmpGates, fields);
|
||||||
|
logfile << "\t\t<GATE> " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
|
||||||
|
airports[*currentIcao] = {tmpGates, tmpRunways};
|
||||||
|
validCount += 1;
|
||||||
|
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
||||||
|
}
|
||||||
|
logfile << "<STATUS> " << apCount << " airports found, of which "
|
||||||
|
<< validCount << " are valid" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeGate15(std::vector<Gate> &gates,
|
||||||
|
const std::vector<std::string> &fields)
|
||||||
|
{
|
||||||
|
std::string gateName;
|
||||||
|
for (size_t j = 4; j < fields.size() - 1; j++) {
|
||||||
|
gateName += fields[j] + " ";
|
||||||
|
}
|
||||||
|
gateName += fields.back();
|
||||||
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
|
struct germanairlinesva::geodata::point pt {
|
||||||
|
std::stod(fields[1]), std::stod(fields[2])
|
||||||
|
};
|
||||||
|
gates.emplace_back(gateName, pt, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeRunway(std::vector<Runway> &runways,
|
||||||
|
const std::vector<std::string> &fields)
|
||||||
|
{
|
||||||
|
runways.emplace_back(fields[8],
|
||||||
|
std::stod(fields[9]),
|
||||||
|
std::stod(fields[10]),
|
||||||
|
std::stod(fields[18]),
|
||||||
|
std::stod(fields[19]),
|
||||||
|
std::stod(fields[1]));
|
||||||
|
runways.emplace_back(fields[17],
|
||||||
|
std::stod(fields[18]),
|
||||||
|
std::stod(fields[19]),
|
||||||
|
std::stod(fields[9]),
|
||||||
|
std::stod(fields[10]),
|
||||||
|
std::stod(fields[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeGate1300(std::vector<Gate> &gates,
|
||||||
|
const std::vector<std::string> &fields)
|
||||||
|
{
|
||||||
|
std::string gateName;
|
||||||
|
for (size_t j = 6; j < fields.size() - 1; j++) {
|
||||||
|
gateName += fields[j] + " ";
|
||||||
|
}
|
||||||
|
gateName += fields.back();
|
||||||
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
|
|
||||||
|
struct germanairlinesva::geodata::point pt {
|
||||||
|
std::stod(fields[1]), std::stod(fields[2])
|
||||||
|
};
|
||||||
|
gates.emplace_back(gateName, pt, 40);
|
||||||
|
}
|
||||||
|
} // namespace simdata
|
||||||
|
} // namespace file
|
||||||
|
} // namespace germanairlinesva
|
||||||
@ -1,95 +0,0 @@
|
|||||||
file(GLOB simdata CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/simdata/*.cpp)
|
|
||||||
|
|
||||||
add_library(simdata SHARED
|
|
||||||
${simdata}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(simdata PRIVATE
|
|
||||||
${CMAKE_SOURCE_DIR}/simdata/include
|
|
||||||
${CMAKE_SOURCE_DIR}/utilities/include
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(simdata PROPERTIES
|
|
||||||
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/simdata/include
|
|
||||||
)
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-Wall
|
|
||||||
-Wextra
|
|
||||||
-pedantic
|
|
||||||
)
|
|
||||||
if(DEBUG)
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-g
|
|
||||||
)
|
|
||||||
target_link_options(simdata PRIVATE
|
|
||||||
-g
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-O2
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
message("Building simdata for MacOSX Universal into ${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}")
|
|
||||||
|
|
||||||
set_target_properties(simdata PROPERTIES
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}"
|
|
||||||
BUILD_WITH_INSTALL_NAME_DIR TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
"SHELL:-arch x86_64"
|
|
||||||
)
|
|
||||||
target_link_options(simdata PRIVATE
|
|
||||||
"SHELL:-arch x86_64"
|
|
||||||
)
|
|
||||||
target_link_libraries(simdata PRIVATE
|
|
||||||
"-framework Security"
|
|
||||||
)
|
|
||||||
elseif(UNIX)
|
|
||||||
message("Building simdata for Linux ${BIT} into ${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}")
|
|
||||||
|
|
||||||
set_target_properties(simdata PROPERTIES
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}"
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-nodefaultlibs
|
|
||||||
)
|
|
||||||
if()
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-m32
|
|
||||||
)
|
|
||||||
target_link_options(simdata PRIVATE
|
|
||||||
-m32
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
elseif(WIN32)
|
|
||||||
if (BIT STREQUAL "32")
|
|
||||||
message("Building simdata for Windows ${BIT} into ${PROJECT_BINARY_DIR}/ESP/${PLUGIN_NAME}")
|
|
||||||
|
|
||||||
set_target_properties(simdata PROPERTIES
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/ESP/${PLUGIN_NAME}"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message("Building simdata for Windows ${BIT} into ${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}")
|
|
||||||
|
|
||||||
set_target_properties(simdata PROPERTIES
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/X-Plane/${PLUGIN_NAME}/${BIT}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEBUG)
|
|
||||||
target_compile_options(simdata PRIVATE
|
|
||||||
-gcodeview
|
|
||||||
)
|
|
||||||
target_link_options(simdata PRIVATE
|
|
||||||
-Wl,-pdb=
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
target_link_options(simdata PRIVATE
|
|
||||||
-static-libgcc
|
|
||||||
-static-libstdc++
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
#include "gate.h"
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
Gate::Gate(std::string designator,
|
|
||||||
double latitude,
|
|
||||||
double longitude,
|
|
||||||
std::uint8_t radius)
|
|
||||||
{
|
|
||||||
this->designator = designator;
|
|
||||||
this->center = {latitude, longitude};
|
|
||||||
this->radius = radius;
|
|
||||||
|
|
||||||
file = std::vector<std::uint8_t>(1 + this->designator.length() + 1 +
|
|
||||||
sizeof(center) + sizeof(radius),
|
|
||||||
0);
|
|
||||||
std::uint8_t *bufPtr = file.data();
|
|
||||||
std::memset(bufPtr,
|
|
||||||
static_cast<std::uint8_t>(this->designator.length()),
|
|
||||||
sizeof(std::uint8_t));
|
|
||||||
bufPtr++;
|
|
||||||
std::memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
|
||||||
bufPtr += this->designator.length() + 1;
|
|
||||||
std::memcpy(bufPtr, &this->center, sizeof(this->center));
|
|
||||||
bufPtr += sizeof(this->center);
|
|
||||||
std::memcpy(bufPtr, &this->radius, sizeof(this->radius));
|
|
||||||
}
|
|
||||||
|
|
||||||
// From database
|
|
||||||
Gate::Gate(std::string designator,
|
|
||||||
struct germanairlinesva_geodata::point center,
|
|
||||||
std::uint8_t radius)
|
|
||||||
{
|
|
||||||
this->designator = designator;
|
|
||||||
this->center = center;
|
|
||||||
this->radius = radius;
|
|
||||||
|
|
||||||
file = std::vector<std::uint8_t>(1 + this->designator.length() + 1 +
|
|
||||||
sizeof(center) + sizeof(radius),
|
|
||||||
0);
|
|
||||||
std::uint8_t *bufPtr = file.data();
|
|
||||||
std::memset(bufPtr,
|
|
||||||
static_cast<std::uint8_t>(this->designator.length()),
|
|
||||||
sizeof(std::uint8_t));
|
|
||||||
bufPtr++;
|
|
||||||
std::memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
|
||||||
bufPtr += this->designator.length() + 1;
|
|
||||||
std::memcpy(bufPtr, &this->center, sizeof(this->center));
|
|
||||||
bufPtr += sizeof(this->center);
|
|
||||||
std::memcpy(bufPtr, &this->radius, sizeof(this->radius));
|
|
||||||
}
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_GATE_H
|
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_GATE_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <streambuf>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "geodata.h"
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Representation of gate
|
|
||||||
* Heading in degrees (0...360)
|
|
||||||
* Radius in metres
|
|
||||||
*
|
|
||||||
* Designator must be null terminated
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | POINT | UINT8
|
|
||||||
* -------+------------+--------+-------
|
|
||||||
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
|
||||||
*/
|
|
||||||
class Gate
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string designator;
|
|
||||||
struct germanairlinesva_geodata::point center;
|
|
||||||
std::uint8_t radius;
|
|
||||||
std::vector<std::uint8_t> file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// From X-Plane or MakeRwys
|
|
||||||
Gate(std::string designator,
|
|
||||||
double latitude,
|
|
||||||
double longitude,
|
|
||||||
std::uint8_t radius);
|
|
||||||
// From database
|
|
||||||
Gate(std::string designator,
|
|
||||||
struct germanairlinesva_geodata::point center,
|
|
||||||
std::uint8_t radius);
|
|
||||||
|
|
||||||
inline const std::uint8_t *getBinaryData() const { return file.data(); }
|
|
||||||
inline std::size_t getBinaryLength() const { return file.size(); }
|
|
||||||
|
|
||||||
inline const std::string to_string() const
|
|
||||||
{
|
|
||||||
std::ostringstream str;
|
|
||||||
str << "Gate " << this->designator << " at " << this->center.latitude
|
|
||||||
<< "N " << this->center.longitude << "E, Radius "
|
|
||||||
<< (int)this->radius;
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend inline std::ostream &operator<<(std::ostream &os, const Gate &gate)
|
|
||||||
{
|
|
||||||
return os << gate.to_string();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H
|
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H
|
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <regex>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "geodata.h"
|
|
||||||
#include "util.hpp"
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Representation of one runway with supplementary information
|
|
||||||
* Heading in degrees (0...360) true
|
|
||||||
* Width and length in meters
|
|
||||||
*
|
|
||||||
* Designator must be null terminated
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | BOX | UINT8 | UINT16 | UINT16
|
|
||||||
* -------+------------+--------+-------+--------+-------
|
|
||||||
* STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG
|
|
||||||
*/
|
|
||||||
class Runway
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string designator;
|
|
||||||
struct germanairlinesva_geodata::box bounds;
|
|
||||||
std::uint8_t width;
|
|
||||||
std::uint16_t length;
|
|
||||||
std::uint16_t trueHeading;
|
|
||||||
std::vector<std::uint8_t> file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// From X-Plane or MakeRwys
|
|
||||||
Runway(std::string designator,
|
|
||||||
double latitudeStart,
|
|
||||||
double longitudeStart,
|
|
||||||
double latitudeEnd,
|
|
||||||
double longitudeEnd,
|
|
||||||
double width);
|
|
||||||
// From database
|
|
||||||
Runway(std::string designator,
|
|
||||||
struct germanairlinesva_geodata::box bounds,
|
|
||||||
std::uint8_t width,
|
|
||||||
std::uint16_t length,
|
|
||||||
std::uint16_t trueHeading);
|
|
||||||
|
|
||||||
inline const std::uint8_t *getBinaryData() const { return file.data(); }
|
|
||||||
inline std::size_t getBinaryLength() const { return file.size(); }
|
|
||||||
|
|
||||||
inline const std::string to_string() const
|
|
||||||
{
|
|
||||||
std::ostringstream str;
|
|
||||||
str << "Runway " << this->designator << " with bounds "
|
|
||||||
<< this->bounds.topLeft.latitude << "N "
|
|
||||||
<< this->bounds.topLeft.longitude << "E, "
|
|
||||||
<< this->bounds.topRight.latitude << "N "
|
|
||||||
<< this->bounds.topRight.longitude << "E, "
|
|
||||||
<< this->bounds.bottomRight.latitude << "N "
|
|
||||||
<< this->bounds.bottomRight.longitude << "E, "
|
|
||||||
<< this->bounds.bottomLeft.latitude << "N "
|
|
||||||
<< this->bounds.bottomLeft.longitude << "E, "
|
|
||||||
<< "Width " << (int)this->width << "m, Length " << this->length
|
|
||||||
<< "m, True Heading " << this->trueHeading << "°";
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend inline std::ostream &operator<<(std::ostream &os,
|
|
||||||
const Runway &runway)
|
|
||||||
{
|
|
||||||
return os << runway.to_string();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMDATA_H
|
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_SIMDATA_H
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "gate.h"
|
|
||||||
#include "runway.h"
|
|
||||||
#include "util.hpp"
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
int scan(
|
|
||||||
const std::string defaultFile,
|
|
||||||
const std::string sceneryPack,
|
|
||||||
const std::string logFile,
|
|
||||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
|
||||||
&airports);
|
|
||||||
|
|
||||||
void makeAirport(
|
|
||||||
const std::string &kind,
|
|
||||||
std::ifstream &infile,
|
|
||||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
|
||||||
&airports,
|
|
||||||
std::ofstream &logfile);
|
|
||||||
void makeGate15(std::vector<Gate> &gates,
|
|
||||||
const std::vector<std::string> &fields);
|
|
||||||
void makeRunway(std::vector<Runway> &runways,
|
|
||||||
const std::vector<std::string> &fields);
|
|
||||||
void makeGate1300(std::vector<Gate> &gates,
|
|
||||||
const std::vector<std::string> &fields);
|
|
||||||
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
|
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "gate.h"
|
|
||||||
#include "runway.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Header
|
|
||||||
*
|
|
||||||
* CHAR[5] | UINT8
|
|
||||||
* --------+--------
|
|
||||||
* VGAS | VERSION
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Airport
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | UINT16 | GATE[] | UINT8 | RUNWAY[]
|
|
||||||
* --------+--------+----------+--------+---------+---------
|
|
||||||
* STRLEN | ICAO | NUMGATES | GATES | NUMRWYS | RUNWAYS
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
static inline void
|
|
||||||
toFile(std::map<std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
&airports,
|
|
||||||
const std::string &file)
|
|
||||||
{
|
|
||||||
std::uint8_t null = 0;
|
|
||||||
std::ofstream out(file, std::fstream::binary);
|
|
||||||
|
|
||||||
// File Header, Last member is version
|
|
||||||
std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1};
|
|
||||||
out.write(reinterpret_cast<const char *>(header), 6);
|
|
||||||
// Num Airports
|
|
||||||
std::uint16_t numAirports = airports.size();
|
|
||||||
out.write(reinterpret_cast<const char *>(&numAirports),
|
|
||||||
sizeof(numAirports));
|
|
||||||
// Airport
|
|
||||||
for (const std::pair<
|
|
||||||
const std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
&airport : airports) {
|
|
||||||
std::string icao = airport.first;
|
|
||||||
std::vector<germanairlinesva_simdata::Gate> gates = airport.second.first;
|
|
||||||
std::vector<germanairlinesva_simdata::Runway> runways =
|
|
||||||
airport.second.second;
|
|
||||||
// ICAO
|
|
||||||
std::uint8_t icaoLength = icao.length();
|
|
||||||
out.write(reinterpret_cast<const char *>(&icaoLength),
|
|
||||||
sizeof(icaoLength));
|
|
||||||
out.write(icao.c_str(), icaoLength);
|
|
||||||
out.write(reinterpret_cast<const char *>(&null), sizeof(null));
|
|
||||||
// Gates
|
|
||||||
std::uint16_t numGates = gates.size();
|
|
||||||
out.write(reinterpret_cast<const char *>(&numGates), sizeof(numGates));
|
|
||||||
for (germanairlinesva_simdata::Gate &gate : gates) {
|
|
||||||
out.write(reinterpret_cast<const char *>(gate.getBinaryData()),
|
|
||||||
(std::streamsize)gate.getBinaryLength());
|
|
||||||
}
|
|
||||||
// Runways
|
|
||||||
std::uint8_t numRunways = runways.size();
|
|
||||||
out.write(reinterpret_cast<const char *>(&numRunways),
|
|
||||||
sizeof(numRunways));
|
|
||||||
for (germanairlinesva_simdata::Runway &runway : runways) {
|
|
||||||
out.write(reinterpret_cast<const char *>(runway.getBinaryData()),
|
|
||||||
(std::streamsize)runway.getBinaryLength());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::map<
|
|
||||||
std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
readVersion1(std::ifstream &in)
|
|
||||||
{
|
|
||||||
std::map<std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
airports;
|
|
||||||
|
|
||||||
std::uint16_t numAirports;
|
|
||||||
in.read(reinterpret_cast<char *>(&numAirports), sizeof(numAirports));
|
|
||||||
|
|
||||||
for (int i = 0; i < numAirports; i++) {
|
|
||||||
// ICAO
|
|
||||||
std::uint8_t icaoLength;
|
|
||||||
in.read(reinterpret_cast<char *>(&icaoLength), sizeof(icaoLength));
|
|
||||||
char *icao = static_cast<char *>(calloc(icaoLength + 1, sizeof(char)));
|
|
||||||
in.read(icao, icaoLength + 1);
|
|
||||||
// Gates
|
|
||||||
std::uint16_t numGates;
|
|
||||||
in.read(reinterpret_cast<char *>(&numGates), sizeof(numGates));
|
|
||||||
for (int j = 0; j < numGates; j++) {
|
|
||||||
// ICAO
|
|
||||||
std::uint8_t designatorLength;
|
|
||||||
in.read(reinterpret_cast<char *>(&designatorLength),
|
|
||||||
sizeof(designatorLength));
|
|
||||||
char *designator =
|
|
||||||
static_cast<char *>(calloc(designatorLength + 1, sizeof(char)));
|
|
||||||
in.read(designator, designatorLength + 1);
|
|
||||||
// Center
|
|
||||||
struct germanairlinesva_geodata::point center;
|
|
||||||
in.read(reinterpret_cast<char *>(¢er), sizeof(center));
|
|
||||||
// Radius
|
|
||||||
std::uint8_t radius;
|
|
||||||
in.read(reinterpret_cast<char *>(&radius), sizeof(radius));
|
|
||||||
|
|
||||||
airports[icao].first.emplace_back(designator, center, radius);
|
|
||||||
}
|
|
||||||
// Runways
|
|
||||||
std::uint8_t numRunways;
|
|
||||||
in.read(reinterpret_cast<char *>(&numRunways), sizeof(numRunways));
|
|
||||||
for (int j = 0; j < numRunways; j++) {
|
|
||||||
// ICAO
|
|
||||||
std::uint8_t designatorLength;
|
|
||||||
in.read(reinterpret_cast<char *>(&designatorLength),
|
|
||||||
sizeof(designatorLength));
|
|
||||||
char *designator =
|
|
||||||
static_cast<char *>(calloc(designatorLength + 1, sizeof(char)));
|
|
||||||
in.read(designator, designatorLength + 1);
|
|
||||||
// Bounds
|
|
||||||
struct germanairlinesva_geodata::box bounds;
|
|
||||||
in.read(reinterpret_cast<char *>(&bounds), sizeof(bounds));
|
|
||||||
// Width
|
|
||||||
std::uint8_t width;
|
|
||||||
in.read(reinterpret_cast<char *>(&width), sizeof(width));
|
|
||||||
// Length
|
|
||||||
std::uint16_t length;
|
|
||||||
in.read(reinterpret_cast<char *>(&length), sizeof(length));
|
|
||||||
// True Heading
|
|
||||||
std::uint16_t trueHeading;
|
|
||||||
in.read(reinterpret_cast<char *>(&trueHeading), sizeof(trueHeading));
|
|
||||||
|
|
||||||
airports[icao].second.emplace_back(designator,
|
|
||||||
bounds,
|
|
||||||
width,
|
|
||||||
length,
|
|
||||||
trueHeading);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
return airports;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::map<
|
|
||||||
std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
fromFile(const std::string &file)
|
|
||||||
{
|
|
||||||
std::map<std::string,
|
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
|
||||||
airports;
|
|
||||||
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;
|
|
||||||
in.read(reinterpret_cast<char *>(&version), 1);
|
|
||||||
|
|
||||||
if (version == 1) {
|
|
||||||
return readVersion1(in);
|
|
||||||
}
|
|
||||||
return airports;
|
|
||||||
}
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
#include "runway.h"
|
|
||||||
namespace germanairlinesva_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);
|
|
||||||
|
|
||||||
file = std::vector<std::uint8_t>(
|
|
||||||
1 + this->designator.length() + 1 + sizeof(this->bounds) +
|
|
||||||
sizeof(this->width) + sizeof(this->length) +
|
|
||||||
sizeof(this->trueHeading),
|
|
||||||
0);
|
|
||||||
std::uint8_t *bufPtr = file.data();
|
|
||||||
std::memset(bufPtr,
|
|
||||||
static_cast<std::uint8_t>(this->designator.length()),
|
|
||||||
sizeof(std::uint8_t));
|
|
||||||
bufPtr++;
|
|
||||||
std::memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
|
||||||
bufPtr += this->designator.length() + 1;
|
|
||||||
std::memcpy(bufPtr, &this->bounds, sizeof(this->bounds));
|
|
||||||
bufPtr += sizeof(this->bounds);
|
|
||||||
std::memcpy(bufPtr, &this->width, sizeof(this->width));
|
|
||||||
bufPtr += sizeof(this->width);
|
|
||||||
std::memcpy(bufPtr, &this->length, sizeof(this->length));
|
|
||||||
bufPtr += sizeof(this->length);
|
|
||||||
std::memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
file = std::vector<std::uint8_t>(
|
|
||||||
1 + this->designator.length() + 1 + sizeof(this->bounds) +
|
|
||||||
sizeof(this->width) + sizeof(this->length) +
|
|
||||||
sizeof(this->trueHeading),
|
|
||||||
0);
|
|
||||||
std::uint8_t *bufPtr = file.data();
|
|
||||||
std::memset(bufPtr,
|
|
||||||
static_cast<std::uint8_t>(this->designator.length()),
|
|
||||||
sizeof(std::uint8_t));
|
|
||||||
bufPtr++;
|
|
||||||
std::memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
|
||||||
bufPtr += this->designator.length() + 1;
|
|
||||||
std::memcpy(bufPtr, &this->bounds, sizeof(this->bounds));
|
|
||||||
bufPtr += sizeof(this->bounds);
|
|
||||||
std::memcpy(bufPtr, &this->width, sizeof(this->width));
|
|
||||||
bufPtr += sizeof(this->width);
|
|
||||||
std::memcpy(bufPtr, &this->length, sizeof(this->length));
|
|
||||||
bufPtr += sizeof(this->length);
|
|
||||||
std::memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
|
|
||||||
}
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
#include "simdata.h"
|
|
||||||
|
|
||||||
namespace germanairlinesva_simdata
|
|
||||||
{
|
|
||||||
int scan(
|
|
||||||
const std::string defaultFile,
|
|
||||||
const std::string sceneryPack,
|
|
||||||
const std::string logFile,
|
|
||||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
|
||||||
&airports)
|
|
||||||
{
|
|
||||||
std::ifstream base(defaultFile);
|
|
||||||
if (!base.good()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::ifstream custom(sceneryPack);
|
|
||||||
if (!custom.good()) {
|
|
||||||
base.close();
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
std::ofstream logfile(logFile, std::fstream::trunc);
|
|
||||||
if (!logfile.good()) {
|
|
||||||
base.close();
|
|
||||||
custom.close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default
|
|
||||||
logfile << "<FILE> " << defaultFile << std::endl;
|
|
||||||
makeAirport("DEFAULT", base, airports, logfile);
|
|
||||||
base.close();
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
size_t pos;
|
|
||||||
std::vector<std::string> packs;
|
|
||||||
while (std::getline(custom, line)) {
|
|
||||||
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
|
||||||
std::string path =
|
|
||||||
germanairlinesva_util::rtrim_copy(line.substr(pos + 13)) +
|
|
||||||
"Earth nav data/apt.dat";
|
|
||||||
packs.emplace_back(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::reverse(packs.begin(), packs.end());
|
|
||||||
|
|
||||||
for (std::string const &path : packs) {
|
|
||||||
std::ifstream pack(path);
|
|
||||||
if (pack.good()) {
|
|
||||||
logfile << "<FILE> " << path << std::endl;
|
|
||||||
makeAirport("CUSTOM", pack, airports, logfile);
|
|
||||||
pack.close();
|
|
||||||
} else {
|
|
||||||
pack.close();
|
|
||||||
logfile << "<STATUS>"
|
|
||||||
<< "Could not find " << path << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logfile << std::endl
|
|
||||||
<< "<STATUS> Total airports: " << airports.size() << std::endl;
|
|
||||||
|
|
||||||
custom.close();
|
|
||||||
logfile.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeAirport(
|
|
||||||
const std::string &kind,
|
|
||||||
std::ifstream &infile,
|
|
||||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
|
||||||
&airports,
|
|
||||||
std::ofstream &logfile)
|
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
std::string *currentIcao = nullptr;
|
|
||||||
std::vector<Gate> tmpGates;
|
|
||||||
std::vector<Runway> tmpRunways;
|
|
||||||
|
|
||||||
int apCount = 0;
|
|
||||||
int validCount = 0;
|
|
||||||
|
|
||||||
while (std::getline(infile, line)) {
|
|
||||||
std::vector<std::string> fields = germanairlinesva_util::split(line, ' ');
|
|
||||||
fields = germanairlinesva_util::select_T<std::string>(
|
|
||||||
fields,
|
|
||||||
[](const std::string &s) { return s.length() > 0; });
|
|
||||||
|
|
||||||
if (fields.empty())
|
|
||||||
continue;
|
|
||||||
if (fields[0] == "1") {
|
|
||||||
// Write to file if ICAO is valid, and we have gates and runways
|
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
|
||||||
!tmpGates.empty()) {
|
|
||||||
airports[*currentIcao] = {tmpGates, tmpRunways};
|
|
||||||
validCount += 1;
|
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
|
||||||
} else if (currentIcao != nullptr) {
|
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " had no gates or runways"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
tmpGates = std::vector<Gate>();
|
|
||||||
tmpRunways = std::vector<Runway>();
|
|
||||||
currentIcao = new std::string(fields[4]);
|
|
||||||
apCount += 1;
|
|
||||||
logfile << "\t<" << kind << "> " << line << std::endl;
|
|
||||||
} else if (currentIcao != nullptr && fields[0] == "15") {
|
|
||||||
makeGate15(tmpGates, fields);
|
|
||||||
logfile << "\t\t<GATE OLD> " << line << std::endl;
|
|
||||||
} else if (fields[0] == "16" || fields[0] == "17") {
|
|
||||||
// Write to file if ICAO is valid, and we have gates and runways
|
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
|
||||||
!tmpGates.empty()) {
|
|
||||||
airports[*currentIcao] = {tmpGates, tmpRunways};
|
|
||||||
validCount += 1;
|
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
|
||||||
} else if (currentIcao != nullptr) {
|
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " had no gates or runways"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
tmpGates = std::vector<Gate>();
|
|
||||||
tmpRunways = std::vector<Runway>();
|
|
||||||
currentIcao = nullptr;
|
|
||||||
logfile << "\t<" << kind << " SKIPPED> " << line << std::endl;
|
|
||||||
} else if (currentIcao != nullptr && fields[0] == "100") {
|
|
||||||
makeRunway(tmpRunways, fields);
|
|
||||||
logfile << "\t\t<RUNWAY> " << line << std::endl;
|
|
||||||
} else if (currentIcao != nullptr && fields[0] == "1300") {
|
|
||||||
makeGate1300(tmpGates, fields);
|
|
||||||
logfile << "\t\t<GATE> " << line << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
|
|
||||||
airports[*currentIcao] = {tmpGates, tmpRunways};
|
|
||||||
validCount += 1;
|
|
||||||
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
|
||||||
}
|
|
||||||
logfile << "<STATUS> " << apCount << " airports found, of which "
|
|
||||||
<< validCount << " are valid" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeGate15(std::vector<Gate> &gates,
|
|
||||||
const std::vector<std::string> &fields)
|
|
||||||
{
|
|
||||||
std::string gateName;
|
|
||||||
for (size_t j = 4; j < fields.size() - 1; j++) {
|
|
||||||
gateName += fields[j] + " ";
|
|
||||||
}
|
|
||||||
gateName += fields.back();
|
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
|
||||||
|
|
||||||
gates.emplace_back(gateName,
|
|
||||||
std::stod(fields[1]),
|
|
||||||
std::stod(fields[2]),
|
|
||||||
40);
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeRunway(std::vector<Runway> &runways,
|
|
||||||
const std::vector<std::string> &fields)
|
|
||||||
{
|
|
||||||
runways.emplace_back(fields[8],
|
|
||||||
std::stod(fields[9]),
|
|
||||||
std::stod(fields[10]),
|
|
||||||
std::stod(fields[18]),
|
|
||||||
std::stod(fields[19]),
|
|
||||||
std::stod(fields[1]));
|
|
||||||
runways.emplace_back(fields[17],
|
|
||||||
std::stod(fields[18]),
|
|
||||||
std::stod(fields[19]),
|
|
||||||
std::stod(fields[9]),
|
|
||||||
std::stod(fields[10]),
|
|
||||||
std::stod(fields[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeGate1300(std::vector<Gate> &gates,
|
|
||||||
const std::vector<std::string> &fields)
|
|
||||||
{
|
|
||||||
std::string gateName;
|
|
||||||
for (size_t j = 6; j < fields.size() - 1; j++) {
|
|
||||||
gateName += fields[j] + " ";
|
|
||||||
}
|
|
||||||
gateName += fields.back();
|
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
|
||||||
|
|
||||||
gates.emplace_back(gateName,
|
|
||||||
std::stod(fields[1]),
|
|
||||||
std::stod(fields[2]),
|
|
||||||
40);
|
|
||||||
}
|
|
||||||
} // namespace germanairlinesva_simdata
|
|
||||||
@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace germanairlinesva_geodata
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace geodata
|
||||||
{
|
{
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
@ -205,7 +207,7 @@ namespace germanairlinesva_geodata
|
|||||||
|
|
||||||
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
|
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
|
||||||
}
|
}
|
||||||
|
} // namespace geodata
|
||||||
} // namespace germanairlinesva_geodata
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -39,7 +39,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace germanairlinesva_util
|
namespace germanairlinesva
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline std::vector<T>
|
static inline std::vector<T>
|
||||||
@ -297,7 +299,7 @@ namespace germanairlinesva_util
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
} // namespace util
|
||||||
} // namespace germanairlinesva_util
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2,112 +2,112 @@
|
|||||||
|
|
||||||
namespace germanairlinesva_websocket
|
namespace germanairlinesva_websocket
|
||||||
{
|
{
|
||||||
Websocket::Websocket(std::string host,
|
Websocket::Websocket(std::string host,
|
||||||
std::string user,
|
std::string user,
|
||||||
std::function<void(const std::string)> toLog)
|
std::function<void(const std::string)> toLog)
|
||||||
: host(host), user(user), toLog(std::move(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")) {
|
||||||
|
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 << "New connection" << std::endl;
|
debug_msg << std::endl << "Connection closed" << std::endl;
|
||||||
debug_msg << "Uri: " << msg->openInfo.uri << std::endl;
|
debug_msg << "Code: " << msg->closeInfo.code << std::endl;
|
||||||
debug_msg << "Headers:" << std::endl;
|
debug_msg << "Reason: " << msg->closeInfo.reason << std::endl;
|
||||||
for (const auto &it : msg->openInfo.headers) {
|
debug_msg << "Remote: " << msg->closeInfo.remote << std::endl;
|
||||||
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;
|
||||||
|
|
||||||
this->webSocket->send("MASTER:" + user);
|
debug_msg << std::endl << "Connection error" << std::endl;
|
||||||
this->toLog("Connecting as " + user);
|
debug_msg << "Decompression: " << msg->errorInfo.decompressionError
|
||||||
} else if (msg->type == ix::WebSocketMessageType::Close) {
|
<< std::endl;
|
||||||
if (msg->closeInfo.reason.compare("DUPLICATE")) {
|
debug_msg << "HTTP status: " << msg->errorInfo.http_status << std::endl;
|
||||||
this->webSocket->disableAutomaticReconnection();
|
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("Disconnected due to beeing a duplicate simualtor");
|
this->toLog(debug_msg.str());
|
||||||
} else {
|
} else if (msg->type == ix::WebSocketMessageType::Message) {
|
||||||
std::stringstream debug_msg;
|
if (!msg->str.empty()) {
|
||||||
|
this->toLog(msg->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
debug_msg << std::endl << "Connection closed" << std::endl;
|
void Websocket::sendData(data &d)
|
||||||
debug_msg << "Code: " << msg->closeInfo.code << std::endl;
|
{
|
||||||
debug_msg << "Reason: " << msg->closeInfo.reason << std::endl;
|
if (strcmp(d.path, this->lastPath) != 0) {
|
||||||
debug_msg << "Remote: " << msg->closeInfo.remote << std::endl;
|
strcpy(this->lastPath, d.path);
|
||||||
|
if (germanairlinesva::util::generateMD5(d.path,
|
||||||
this->toLog(debug_msg.str());
|
this->lastHash,
|
||||||
}
|
this->toLog)) {
|
||||||
} else if (msg->type == ix::WebSocketMessageType::Error) {
|
strcpy(this->lastHash, "NOT SET");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Websocket::sendData(data &d)
|
nlohmann::json json = {
|
||||||
{
|
{"altitude", d.alt},
|
||||||
if (strcmp(d.path, this->lastPath) != 0) {
|
{"vs", d.vs},
|
||||||
strcpy(this->lastPath, d.path);
|
{"ias", d.ias},
|
||||||
if (germanairlinesva_util::generateMD5(d.path,
|
{"magHdg", d.magHeading},
|
||||||
this->lastHash,
|
{"truHdg", d.truHdg},
|
||||||
this->toLog)) {
|
{"totFuel", d.totFuelKg},
|
||||||
strcpy(this->lastHash, "NOT SET");
|
{"fuelFlow", d.ff},
|
||||||
}
|
{"hash", this->lastHash},
|
||||||
}
|
};
|
||||||
|
|
||||||
nlohmann::json json = {
|
if (this->webSocket != nullptr) {
|
||||||
{"altitude", d.alt},
|
std::ostringstream msg;
|
||||||
{"vs", d.vs},
|
msg << "SEND:" << user << ":" << json.dump();
|
||||||
{"ias", d.ias},
|
this->webSocket->send(msg.str(), false);
|
||||||
{"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 germanairlinesva_websocket
|
} // namespace germanairlinesva_websocket
|
||||||
@ -117,6 +117,5 @@ elseif(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
target_link_libraries(germanairlinesva_xplugin PRIVATE
|
||||||
simdata
|
|
||||||
ixwebsocket
|
ixwebsocket
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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.h"
|
#include "simdata/simdataXP.h"
|
||||||
#include "simulatorDatabase.hpp"
|
#include "simdata/simulatorDatabase.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "websocket.h"
|
#include "websocket.h"
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,8 @@ std::atomic<bool> wantsExit;
|
|||||||
|
|
||||||
std::map<std::string, std::string> configuration;
|
std::map<std::string, std::string> configuration;
|
||||||
std::map<std::string,
|
std::map<std::string,
|
||||||
std::pair<std::vector<germanairlinesva_simdata::Gate>,
|
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
|
||||||
std::vector<germanairlinesva_simdata::Runway>>>
|
std::vector<germanairlinesva::file::simdata::Runway>>>
|
||||||
airports;
|
airports;
|
||||||
germanairlinesva_websocket::Websocket *connector;
|
germanairlinesva_websocket::Websocket *connector;
|
||||||
int xplaneVersion;
|
int xplaneVersion;
|
||||||
@ -130,19 +130,20 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
|||||||
toLog("WebSocket started");
|
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) {
|
||||||
|
|
||||||
if (strcmp(configuration["scenery"].c_str(), hash) != 0 ||
|
if (strcmp(configuration["scenery"].c_str(), hash) != 0 ||
|
||||||
!germanairlinesva_util::fileExists(
|
!germanairlinesva::util::fileExists(
|
||||||
XPLANE_PLUGIN_DIRECTORY SIMDATABASE)) {
|
XPLANE_PLUGIN_DIRECTORY SIMDATABASE)) {
|
||||||
scan(xplaneVersion < 12000 ? XPLANE11_BASE_SCENERY
|
scan(xplaneVersion < 12000 ? XPLANE11_BASE_SCENERY
|
||||||
: XPLANE12_BASE_SCENERY,
|
: XPLANE12_BASE_SCENERY,
|
||||||
XPLANE_CUSTOM_SCENERY,
|
XPLANE_CUSTOM_SCENERY,
|
||||||
XPLANE_PLUGIN_DIRECTORY "log.txt",
|
XPLANE_PLUGIN_DIRECTORY "log.txt",
|
||||||
airports);
|
airports);
|
||||||
germanairlinesva_simdata::toFile(airports,
|
germanairlinesva::file::simdata::toFile(
|
||||||
XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
|
airports,
|
||||||
|
XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
|
||||||
|
|
||||||
configuration["scenery"] = hash;
|
configuration["scenery"] = hash;
|
||||||
germanairlinesva::file::config::writeConfig(
|
germanairlinesva::file::config::writeConfig(
|
||||||
@ -150,7 +151,7 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
|||||||
XPLANE_PLUGIN_DIRECTORY CONFIG);
|
XPLANE_PLUGIN_DIRECTORY CONFIG);
|
||||||
toLog("Sim Database updated");
|
toLog("Sim Database updated");
|
||||||
} else {
|
} else {
|
||||||
airports = germanairlinesva_simdata::fromFile(
|
airports = germanairlinesva::file::simdata::fromFile(
|
||||||
XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
|
XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
|
||||||
toLog("Sim Database loaded");
|
toLog("Sim Database loaded");
|
||||||
}
|
}
|
||||||
@ -279,7 +280,7 @@ float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
|||||||
|
|
||||||
void serverWorker()
|
void serverWorker()
|
||||||
{
|
{
|
||||||
germanairlinesva_util::setThreadName("GAServerWorker");
|
germanairlinesva::util::setThreadName("GAServerWorker");
|
||||||
|
|
||||||
while (!wantsExit) {
|
while (!wantsExit) {
|
||||||
struct germanairlinesva_websocket::data copy;
|
struct germanairlinesva_websocket::data copy;
|
||||||
@ -297,7 +298,7 @@ void serverWorker()
|
|||||||
|
|
||||||
void recordingWorker()
|
void recordingWorker()
|
||||||
{
|
{
|
||||||
germanairlinesva_util::setThreadName("GARecordingWorker");
|
germanairlinesva::util::setThreadName("GARecordingWorker");
|
||||||
|
|
||||||
germanairlinesva::file::recording::RecordingEntry lastPath;
|
germanairlinesva::file::recording::RecordingEntry lastPath;
|
||||||
std::uint32_t segment = 0;
|
std::uint32_t segment = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user