Namespaces

Better File handling
This commit is contained in:
2022-09-06 00:29:19 +02:00
parent 9dcca746ed
commit b22a60c85e
24 changed files with 1106 additions and 781 deletions
+68
View File
@@ -0,0 +1,68 @@
#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;
germanairlinesva_geodata::point center;
std::uint8_t radius;
std::vector<std::uint8_t> file;
public:
// From X-Plane or MakeRwys
Gate(const std::string &designator,
double latitude,
double longitude,
std::uint8_t radius);
// From database
Gate(const std::string &designator,
germanairlinesva_geodata::point center,
std::uint8_t radius);
std::uint8_t *getBinaryData() { return file.data(); }
std::size_t getBinaryLength() { return file.size(); }
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 std::ostream &operator<<(std::ostream &os, const Gate &gate);
};
inline std::ostream &operator<<(std::ostream &os, const Gate &gate)
{
return os << gate.to_string();
}
} // namespace germanairlinesva_simdata
#endif
+208
View File
@@ -0,0 +1,208 @@
#ifndef GERMANAIRLINESVA_GACONNECTOR_GEODATA_H
#define GERMANAIRLINESVA_GACONNECTOR_GEODATA_H
#ifdef IBM
#define WIN32_LEAN_AND_MEAN
#endif
#define BUFSIZE 1024
#define MD5LEN 16
#define EARTH_M 6371000
#include <cmath>
#pragma pack(push)
#pragma pack(1)
namespace germanairlinesva_geodata
{
struct point {
double latitude;
double longitude;
};
struct box {
struct point topLeft;
struct point topRight;
struct point bottomRight;
struct point bottomLeft;
};
static inline double toFeet(double value) { return value * 3.280839895; }
static inline double toDegrees(double value) { return value * 180 / M_PI; }
static inline double toRadians(double value) { return value * M_PI / 180; }
static inline double normalize(double value)
{
return fmod(value + 360, 360);
}
// Input and Output in degrees
static inline double bearingDD(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 normalize(toDegrees(atan2(y, x)));
}
// Input in degrees, Output in metres
static inline double distanceEarthD(double fromLatitude,
double fromLongitude,
double toLatitude,
double toLongitude)
{
double lat1r, lon1r, lat2r, lon2r, u, v;
lat1r = toRadians(fromLatitude);
lon1r = toRadians(fromLongitude);
lat2r = toRadians(toLatitude);
lon2r = toRadians(toLongitude);
u = sin((lat2r - lat1r) / 2);
v = sin((lon2r - lon1r) / 2);
return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}
// Input and Output in degrees
static inline struct point calculatePointDD(struct point coordinates,
double bearing,
double distance)
{
double r_latitude = toRadians(coordinates.latitude);
double r_longitude = toRadians(coordinates.longitude);
double r_bearing = toRadians(bearing);
double newLatitude =
std::asin(std::sin(r_latitude) * std::cos(distance / EARTH_M) +
std::cos(r_latitude) * std::sin(distance / EARTH_M) *
std::cos(r_bearing));
double newLongitude =
r_longitude +
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
std::cos(r_latitude),
std::cos(distance / EARTH_M) -
std::sin(r_latitude) * std::sin(newLatitude));
return {toDegrees(newLatitude), toDegrees(newLongitude)};
}
// Input in degrees, Output in radians
static inline struct point calculatePointDR(struct point coordinates,
double bearing,
double distance)
{
double r_latitude = toRadians(coordinates.latitude);
double r_longitude = toRadians(coordinates.longitude);
double r_bearing = toRadians(bearing);
double newLatitude =
std::asin(std::sin(r_latitude) * std::cos(distance / EARTH_M) +
std::cos(r_latitude) * std::sin(distance / EARTH_M) *
std::cos(r_bearing));
double newLongitude =
r_longitude +
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
std::cos(r_latitude),
std::cos(distance / EARTH_M) -
std::sin(r_latitude) * std::sin(newLatitude));
return {newLatitude, newLongitude};
}
// LAT/LON in radians, BEARING/Output in degrees
static inline struct point calculatePointRD(struct point coordinates,
double bearing,
double distance)
{
double r_bearing = toRadians(bearing);
double newLatitude = std::asin(
std::sin(coordinates.latitude) * std::cos(distance / EARTH_M) +
std::cos(coordinates.latitude) * std::sin(distance / EARTH_M) *
std::cos(r_bearing));
double newLongitude =
coordinates.longitude +
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
std::cos(coordinates.latitude),
std::cos(distance / EARTH_M) -
std::sin(coordinates.latitude) * std::sin(newLatitude));
return {toDegrees(newLatitude), toDegrees(newLongitude)};
}
// LAT/LON/Output in radians, BEARING in degrees
static inline struct point calculatePointRR(struct point coordinates,
double bearing,
double distance)
{
double r_bearing = toRadians(bearing);
double newLatitude = std::asin(
std::sin(coordinates.latitude) * std::cos(distance / EARTH_M) +
std::cos(coordinates.latitude) * std::sin(distance / EARTH_M) *
std::cos(r_bearing));
double newLongitude =
coordinates.longitude +
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
std::cos(coordinates.latitude),
std::cos(distance / EARTH_M) -
std::sin(coordinates.latitude) * std::sin(newLatitude));
return {newLatitude, newLongitude};
}
// Input in degrees, calculate from center
static inline box calculateBoxDD(struct point center,
double bearing,
double length,
double width)
{
struct point primaryCenter = calculatePointDR(center, bearing, -length / 2);
struct point secondaryCenter =
calculatePointDR(center, bearing, length / 2);
double offsetHeadingNorth =
bearing - 90 > 0 ? bearing - 90 : bearing - 90 + 360;
struct point primaryTop =
calculatePointRD(primaryCenter, offsetHeadingNorth, width / 2);
struct point primaryBottom =
calculatePointRD(primaryCenter, offsetHeadingNorth, -width / 2);
struct point secondaryTop =
calculatePointRD(secondaryCenter, offsetHeadingNorth, width / 2);
struct point secondaryBottom =
calculatePointRD(secondaryCenter, offsetHeadingNorth, -width / 2);
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
}
// Input in degrees, calculate from start end
static inline box calculateBoxDD(struct point start,
struct point end,
double bearing,
double width)
{
double offsetHeadingNorth =
bearing - 90 > 0 ? bearing - 90 : bearing - 90 + 360;
struct point primaryTop =
calculatePointDD(start, offsetHeadingNorth, width / 2);
struct point primaryBottom =
calculatePointDD(start, offsetHeadingNorth, -width / 2);
struct point secondaryTop =
calculatePointDD(end, offsetHeadingNorth, width / 2);
struct point secondaryBottom =
calculatePointDD(end, offsetHeadingNorth, -width / 2);
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
}
} // namespace germanairlinesva_geodata
#pragma pack(pop)
#endif
+81
View File
@@ -0,0 +1,81 @@
#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);
std::uint8_t *getBinaryData() { return file.data(); }
std::size_t getBinaryLength() { return file.size(); }
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 std::ostream &operator<<(std::ostream &os, const Runway &runway);
};
inline std::ostream &operator<<(std::ostream &os, const Runway &runway)
{
return os << runway.to_string();
}
} // namespace germanairlinesva_simdata
#endif
+35
View File
@@ -0,0 +1,35 @@
#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMDATA_H
#define GERMANAIRLINESVA_GACONNECTOR_SIMDATA_H
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include "gate.h"
#include "runway.h"
#include "util.hpp"
namespace germanairlinesva_simdata
{
int scan(
const char *defaultFile,
const char *sceneryPack,
const char *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, std::vector<std::string> fields);
void makeRunway(std::vector<Runway> *runways,
std::vector<std::string> fields);
void makeGate1300(std::vector<Gate> *gates, std::vector<std::string> fields);
} // namespace germanairlinesva_simdata
#endif
+191
View File
@@ -0,0 +1,191 @@
#ifndef GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#define GERMANAIRLINESVA_GACONNECTOR_SIMULATORDATABASE_H
#include "gate.h"
#include "runway.h"
#define CURRENT_VERSION 1
#include <cstdint>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
/*
* 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
std::uint8_t header[] = {'V', 'G', 'A', 'S', 0, CURRENT_VERSION};
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
germanairlinesva_geodata::point center;
in.read(reinterpret_cast<char *>(&center), 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
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