Move MakeRwys to own lib
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
file(GLOB makerwysxp CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/makerwysxp/*.cpp)
|
||||
|
||||
add_library(makerwysxp SHARED
|
||||
${makerwysxp}
|
||||
)
|
||||
|
||||
target_include_directories(makerwysxp PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/makerwysxp/include
|
||||
${CMAKE_SOURCE_DIR}/file
|
||||
)
|
||||
|
||||
set_target_properties(makerwysxp PROPERTIES
|
||||
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/makerwysxp/include
|
||||
)
|
||||
target_compile_definitions(makerwysxp PRIVATE
|
||||
_USE_MATH_DEFINES
|
||||
)
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-pedantic
|
||||
)
|
||||
if(DEBUG)
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-g
|
||||
)
|
||||
target_link_options(makerwysxp PRIVATE
|
||||
-g
|
||||
)
|
||||
else()
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-O2
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
message("Building makerwysxp for MacOSX Universal into ${PROJECT_BINARY_DIR}/${PLUGIN_NAME}/${BIT}")
|
||||
|
||||
set_target_properties(makerwysxp PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}"
|
||||
BUILD_WITH_INSTALL_NAME_DIR TRUE
|
||||
)
|
||||
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
"SHELL:-arch i386"
|
||||
"SHELL:-arch x86_64"
|
||||
)
|
||||
target_link_options(makerwysxp PRIVATE
|
||||
"SHELL:-arch i386"
|
||||
"SHELL:-arch x86_64"
|
||||
)
|
||||
target_link_libraries(makerwysxp PRIVATE
|
||||
"-framework Security"
|
||||
)
|
||||
elseif(UNIX)
|
||||
message("Building makerwysxp for Linux ${BIT} into ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}")
|
||||
|
||||
set_target_properties(makerwysxp PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}"
|
||||
)
|
||||
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-nodefaultlibs
|
||||
)
|
||||
if(BIT STREQUAL "32")
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-m32
|
||||
)
|
||||
target_link_options(makerwysxp PRIVATE
|
||||
-m32
|
||||
)
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
message("Building makerwysxp for Windows ${BIT} into ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}")
|
||||
|
||||
set_target_properties(makerwysxp PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}"
|
||||
)
|
||||
|
||||
if(DEBUG)
|
||||
target_compile_options(makerwysxp PRIVATE
|
||||
-gcodeview
|
||||
)
|
||||
target_link_options(makerwysxp PRIVATE
|
||||
-Wl,-pdb=
|
||||
)
|
||||
endif()
|
||||
target_link_options(makerwysxp PRIVATE
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_GATE_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_GATE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* Representation of X-Plane gate
|
||||
* Heading in degrees (0...360)
|
||||
*
|
||||
* Length in bytes: 18 + length of designator
|
||||
* Designator must be null terminated
|
||||
*
|
||||
* UINT8 | CHAR[] | DOUBLE | DOUBLE | UINT8
|
||||
* ------+------------+--------+--------+------
|
||||
* LEN | DESIGNATOR | LAT | LON | WIDTH
|
||||
*/
|
||||
class Gate
|
||||
{
|
||||
private:
|
||||
std::string designator;
|
||||
double latitude;
|
||||
double longitude;
|
||||
std::vector<std::uint8_t> file;
|
||||
|
||||
public:
|
||||
Gate(const std::string &designator, double latitude, double longitude)
|
||||
{
|
||||
|
||||
this->designator = designator;
|
||||
this->latitude = latitude;
|
||||
this->longitude = longitude;
|
||||
|
||||
file = std::vector<std::uint8_t>(18 + this->designator.length(), 0);
|
||||
std::uint8_t *bufPtr = file.data();
|
||||
memset(bufPtr,
|
||||
static_cast<std::uint8_t>(this->designator.length()),
|
||||
sizeof(std::uint8_t));
|
||||
bufPtr++; // Designator length
|
||||
memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
||||
bufPtr += this->designator.length() + 1; // Designator plus null termination
|
||||
memcpy(bufPtr, &this->latitude, sizeof(this->latitude));
|
||||
bufPtr += 8; // Latitude
|
||||
memcpy(bufPtr, &this->longitude, sizeof(this->longitude));
|
||||
}
|
||||
|
||||
std::uint8_t *getBinaryData() { return file.data(); }
|
||||
std::size_t getBinaryLength() { return file.size(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAKERWYSXP_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAKERWYSXP_H
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "gate.hpp"
|
||||
#include "runway.hpp"
|
||||
#include "stringExtensions.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H
|
||||
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
/*
|
||||
* Representation of one X-Plane runway with supplementary information
|
||||
* Heading in degrees (0...360)
|
||||
* Width and length in feet
|
||||
*
|
||||
* Length in bytes: 23 + length of designator
|
||||
* Designator must be null terminated
|
||||
*
|
||||
* UINT8 | CHAR[] | DOUBLE | DOUBLE | UINT8 | UINT16 | UINT16
|
||||
* ------+------------+--------+--------+-------+--------+-------
|
||||
* LEN | DESIGNATOR | LAT | LON | WIDTH | LENGTH | TRUHDG
|
||||
*/
|
||||
class Runway
|
||||
{
|
||||
private:
|
||||
std::string designator;
|
||||
double latitudeStart;
|
||||
double longitudeStart;
|
||||
std::uint8_t width;
|
||||
std::uint16_t length;
|
||||
std::uint16_t trueHeading;
|
||||
std::vector<std::uint8_t> file;
|
||||
|
||||
public:
|
||||
Runway(std::string designator,
|
||||
double latitudeStart,
|
||||
double longitudeStart,
|
||||
double latitudeEnd,
|
||||
double longitudeEnd,
|
||||
double width)
|
||||
{
|
||||
this->designator = std::move(designator);
|
||||
this->latitudeStart = latitudeStart;
|
||||
this->longitudeStart = longitudeStart;
|
||||
this->width = (std::uint8_t)std::round(util::to_feet(width));
|
||||
double dist = util::distanceEarth(latitudeStart,
|
||||
longitudeStart,
|
||||
latitudeEnd,
|
||||
longitudeEnd);
|
||||
this->length = (std::uint16_t)std::round(util::to_feet(dist));
|
||||
this->trueHeading = (std::uint16_t)std::round(util::bearing(latitudeStart,
|
||||
longitudeStart,
|
||||
latitudeEnd,
|
||||
longitudeEnd));
|
||||
|
||||
file = std::vector<std::uint8_t>(23 + this->designator.length(), 0);
|
||||
std::uint8_t *bufPtr = file.data();
|
||||
memset(bufPtr,
|
||||
static_cast<std::uint8_t>(this->designator.length()),
|
||||
sizeof(std::uint8_t));
|
||||
bufPtr++;
|
||||
memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
||||
bufPtr += this->designator.length() + 1;
|
||||
memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
|
||||
bufPtr += sizeof(this->latitudeStart);
|
||||
memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
|
||||
bufPtr += sizeof(this->longitudeStart);
|
||||
memcpy(bufPtr, &this->width, sizeof(this->width));
|
||||
bufPtr += sizeof(this->width);
|
||||
memcpy(bufPtr, &this->length, sizeof(this->length));
|
||||
bufPtr += sizeof(this->length);
|
||||
memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
|
||||
}
|
||||
|
||||
Runway(std::string designator,
|
||||
double latitudeStart,
|
||||
double longitudeStart,
|
||||
std::uint8_t width,
|
||||
std::uint16_t length,
|
||||
std::uint16_t trueHeading)
|
||||
{
|
||||
this->designator = std::move(designator);
|
||||
this->latitudeStart = latitudeStart;
|
||||
this->longitudeStart = longitudeStart;
|
||||
this->width = width;
|
||||
this->length = length;
|
||||
this->trueHeading = trueHeading;
|
||||
|
||||
file = std::vector<std::uint8_t>(23 + this->designator.length(), 0);
|
||||
std::uint8_t *bufPtr = file.data();
|
||||
memset(bufPtr,
|
||||
static_cast<std::uint8_t>(this->designator.length()),
|
||||
sizeof(std::uint8_t));
|
||||
bufPtr++;
|
||||
memcpy(bufPtr, this->designator.c_str(), this->designator.length());
|
||||
bufPtr += this->designator.length() + 1;
|
||||
memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
|
||||
bufPtr += sizeof(this->latitudeStart);
|
||||
memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
|
||||
bufPtr += sizeof(this->longitudeStart);
|
||||
memcpy(bufPtr, &this->width, sizeof(this->width));
|
||||
bufPtr += sizeof(this->width);
|
||||
memcpy(bufPtr, &this->length, sizeof(this->length));
|
||||
bufPtr += sizeof(this->length);
|
||||
memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
|
||||
}
|
||||
|
||||
std::uint8_t *getBinaryData() { return file.data(); }
|
||||
std::size_t getBinaryLength() { return file.size(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,174 @@
|
||||
#include "include/makeRwysXP.h"
|
||||
|
||||
int scan(const char *defaultFile,
|
||||
const char *sceneryPack,
|
||||
const char *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::ios::out | std::ios::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 =
|
||||
rtrim_copy(line.substr(pos + 13)) + "Earth nav data/apt.dat";
|
||||
packs.push_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 = split(line, ' ');
|
||||
fields = 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, 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->push_back(Gate{gateName, std::stod(fields[1]), std::stod(fields[2])});
|
||||
}
|
||||
|
||||
void makeRunway(std::vector<Runway> *runways, std::vector<std::string> fields)
|
||||
{
|
||||
runways->push_back(Runway{fields[8],
|
||||
std::stod(fields[9]),
|
||||
std::stod(fields[10]),
|
||||
std::stod(fields[18]),
|
||||
std::stod(fields[19]),
|
||||
std::stod(fields[1])});
|
||||
runways->push_back(Runway{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, 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->push_back(Gate{gateName, std::stod(fields[1]), std::stod(fields[2])});
|
||||
}
|
||||
Reference in New Issue
Block a user