218 lines
6.6 KiB
C++
218 lines
6.6 KiB
C++
#ifndef GERMANAIRLINESVA_FILE_SIMDATA_SIMDATABASE_H
|
|
#define GERMANAIRLINESVA_FILE_SIMDATA_SIMDATABASE_H
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "config/config.hpp"
|
|
#include "constants.h"
|
|
#include "simdata/gate.hpp"
|
|
#include "simdata/runway.hpp"
|
|
#ifdef XP
|
|
#include "simdata/simdataXP.hpp"
|
|
#endif
|
|
#if not defined(XP) && not defined(MSFS)
|
|
#include "simdata/simdataESP.hpp"
|
|
#endif
|
|
|
|
/*
|
|
* 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
|
|
{
|
|
class SimDatabase
|
|
{
|
|
private:
|
|
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
|
airports;
|
|
|
|
inline void 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 utilities::geodata::point center =
|
|
read<struct utilities::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 utilities::geodata::box bounds =
|
|
read<struct utilities::geodata::box>(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,
|
|
bounds,
|
|
width,
|
|
length,
|
|
trueHeading);
|
|
}
|
|
}
|
|
|
|
in.close();
|
|
}
|
|
|
|
inline void fromFile(const char *path)
|
|
{
|
|
std::ifstream in(path, std::ifstream::binary);
|
|
|
|
std::string ident = readString(in, 4);
|
|
if (ident.compare(SIMDATABASE_HEADER) != 0) {
|
|
throw std::invalid_argument("Wrong file");
|
|
}
|
|
std::uint8_t version = read<std::uint8_t>(in);
|
|
|
|
if (version == 1) {
|
|
this->readVersion1(in);
|
|
}
|
|
}
|
|
|
|
inline void toFile(const char *path) const
|
|
{
|
|
std::ofstream out(path, std::fstream::binary);
|
|
|
|
// File Header
|
|
out.write(SIMDATABASE_HEADER, 4);
|
|
out.write("\1", 1);
|
|
// 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();
|
|
}
|
|
|
|
inline const char *resolveFilename(int simVersion) const
|
|
{
|
|
switch (simVersion) {
|
|
case FSX_VERSION:
|
|
return BASE_DIRECTORY FSX_PREFIX SIMDATABASE;
|
|
case FSXSE_VERSION:
|
|
return BASE_DIRECTORY FSXSE_PREFIX SIMDATABASE;
|
|
case P3D3_VERSION:
|
|
return BASE_DIRECTORY P3D3_PREFIX SIMDATABASE;
|
|
case P3D4_VERSION:
|
|
return BASE_DIRECTORY P3D4_PREFIX SIMDATABASE;
|
|
case P3D5_VERSION:
|
|
return BASE_DIRECTORY P3D5_PREFIX SIMDATABASE;
|
|
case MSFS_VERSION:
|
|
return "NONE";
|
|
default:
|
|
return BASE_DIRECTORY SIMDATABASE;
|
|
}
|
|
}
|
|
|
|
public:
|
|
inline SimDatabase(int simVersion,
|
|
const char *hash,
|
|
std::shared_ptr<config::Config> &configuration,
|
|
std::function<void(const std::string)> toLog)
|
|
{
|
|
if (strcmp(configuration->getScenery(simVersion).c_str(), hash) !=
|
|
0 ||
|
|
!utilities::fileExists(resolveFilename(simVersion))) {
|
|
#ifdef XP
|
|
scan(simVersion < 12000 ? XPLANE11_BASE_SCENERY
|
|
: XPLANE12_BASE_SCENERY,
|
|
XPLANE_CUSTOM_SCENERY,
|
|
BASE_DIRECTORY "log.txt",
|
|
airports);
|
|
#endif
|
|
#ifndef MSFS
|
|
scan(BASE_DIRECTORY MAKERWYS_R5,
|
|
BASE_DIRECTORY MAKERWYS_G5,
|
|
BASE_DIRECTORY "db_log.txt",
|
|
airports);
|
|
#endif
|
|
configuration->updateScenery(simVersion, hash);
|
|
|
|
#ifndef MSFS
|
|
this->toFile(resolveFilename(simVersion));
|
|
#endif
|
|
toLog("Sim Database updated");
|
|
} else {
|
|
|
|
#ifndef MSFS
|
|
this->fromFile(resolveFilename(simVersion));
|
|
#endif
|
|
toLog("Sim Database loaded");
|
|
}
|
|
}
|
|
|
|
inline std::size_t getCount() const { return this->airports.size(); }
|
|
|
|
inline const std::pair<const std::vector<Gate>,
|
|
const std::vector<Runway>>
|
|
operator[](std::string key)
|
|
{
|
|
auto it = this->airports.find(key);
|
|
if (it != this->airports.end()) {
|
|
return this->airports[key];
|
|
} else {
|
|
return std::pair<std::vector<Gate>, std::vector<Runway>>();
|
|
}
|
|
}
|
|
};
|
|
} // namespace simdata
|
|
} // namespace file
|
|
} // namespace germanairlinesva
|
|
|
|
#endif
|