1
0
Fork 0

NavData: don't load XML extension files from unsuitable scenery paths

Add a 'scenery_path' field to the 'airport' table of the SQLite
NavDataCache database. For each airport, this field indicates the
scenery realpath() that contributed the apt.dat file for the airport (as
an exception, for airports whose apt.dat file is
$FG_ROOT/Airports/apt.dat.gz, the path thus stored is for now $FG_ROOT,
which is technically not a scenery path). This path is then made
available via FGAirport::sceneryPath(), which allows us to implement the
following change (in this commit):

A) The lookup of *.procedures.xml is unchanged.

B) For other XML extension files (groundnet, ils, runway_rename,
   threshold, twr):

 - The search performed by XMLLoader::findAirportData() through
   globals->get_fg_scenery() stops immediately after the scenery path p
   that contributed the apt.dat file for the airport.

 - Paths that come earlier than p in globals->get_fg_scenery() order may
   contain XML extension files that will *override* sibling files that
   might exist in p (as was already the case before this commit).

The rationale behind this change is that we don't want a custom scenery
with good data in its NavData folder regarding airport FOO to get
"ruined" by files such as FOO.threshold.xml present in the TerraSync
directory---which is assumed to come later in globals->get_fg_scenery()
order.

*.procedures.xml files are excluded from the change because there is a
widespread use of a huge set of procedure files for the whole world; if
airport FOO in a custom scenery has no procedure files, we do want to
let FlightGear find FOO.procedures.xml inside the scenery path
containing the huge dataset (which should come *after* custom sceneries
in globals->get_fg_scenery() order so as to give these custom sceneries
the option to provide better *.procedures.xml files and have them take
precedence over less specialized sources such as the huge dataset).

Reference discussion: https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAKor_THrQCiS1ES_ENSrmn1j3s39dX0qQXSbYBUz6yuokse_pQ%40mail.gmail.com/#msg37860751
This commit is contained in:
Florent Rougon 2023-07-14 10:31:19 +02:00
parent a207cdd207
commit 351ca111ad
14 changed files with 134 additions and 60 deletions

View file

@ -73,7 +73,8 @@ osgDB::ReaderWriter::ReadResult AirportBuilder::readNode(const std::string& file
const std::string airportId = aptFile.file_base();
APTLoader aptLoader;
const FGAirport* airport = aptLoader.loadAirportFromFile(airportId, aptFile);
const FGAirport* airport = aptLoader.loadAirportFromFile(
airportId, {aptFile, SGPath()}); // maybe provide a path if this is used
if (! airport) return ReadResult::FILE_NOT_HANDLED;
SG_LOG( SG_TERRAIN, SG_DEBUG, "Building airport : " << airportId << " " << airport->getName());

View file

@ -12,6 +12,7 @@
#include <algorithm>
#include <cassert>
#include <utility>
#include <simgear/debug/ErrorReportingCallback.hxx>
#include <simgear/debug/logstream.hxx>
@ -54,10 +55,12 @@ FGAirport::FGAirport( PositionedID aGuid,
const SGGeod& location,
const std::string &name,
bool has_metar,
Type aType ):
Type aType,
SGPath sceneryPath):
FGPositioned(aGuid, aType, id, location),
_name(name),
_has_metar(has_metar),
_sceneryPath(std::move(sceneryPath)),
mTowerDataLoaded(false),
mHasTower(false),
mRunwaysLoaded(false),
@ -90,6 +93,11 @@ bool FGAirport::isHeliport() const
return type() == HELIPORT;
}
SGPath FGAirport::sceneryPath() const
{
return _sceneryPath;
}
//------------------------------------------------------------------------------
unsigned int FGAirport::numRunways() const
{

View file

@ -14,6 +14,7 @@
#include <vector>
#include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <Navaids/positioned.hxx>
#include <Navaids/procedure.hxx>
@ -30,8 +31,15 @@ class FGGroundNetwork;
class FGAirport : public FGPositioned
{
public:
// 'sceneryPath' is the scenery path that provided the apt.dat file for
// the airport (except for the “default dat file” under $FG_ROOT and the
// null SGPath special case, 'sceneryPath' should be an element of
// globals->get_fg_scenery()). Knowing this allows one to stop looking for
// files such as ils.xml or threshold.xml in scenery paths that come later
// in globals->get_fg_scenery() order (cf. XMLLoader::findAirportData()).
FGAirport(PositionedID aGuid, const std::string& id, const SGGeod& location,
const std::string& name, bool has_metar, Type aType);
const std::string& name, bool has_metar, Type aType,
SGPath sceneryPath = SGPath());
~FGAirport();
static bool isType(FGPositioned::Type ty)
@ -39,6 +47,9 @@ public:
return (ty >= FGPositioned::AIRPORT) && (ty <= FGPositioned::SEAPORT);
}
// Return the realpath() of the scenery folder under which we found the
// apt.dat file for this airport.
SGPath sceneryPath() const;
const std::string& getId() const { return ident(); }
const std::string& getName() const { return _name; }
std::string toString() const { return "an airport " + ident(); }
@ -350,6 +361,7 @@ private:
std::string _name;
bool _has_metar = false;
const SGPath _sceneryPath;
void loadRunways() const;
void loadHelipads() const;

View file

@ -68,10 +68,11 @@ APTLoader::APTLoader()
APTLoader::~APTLoader() {}
void APTLoader::readAptDatFile(const SGPath& aptdb_file,
void APTLoader::readAptDatFile(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllAptDatFiles)
{
const SGPath aptdb_file = sceneryLocation.datPath;
string apt_dat = aptdb_file.utf8Str(); // full path to the file being parsed
sg_gzifstream in(aptdb_file, std::ios_base::in | std::ios_base::binary, true);
@ -175,6 +176,7 @@ void APTLoader::readAptDatFile(const SGPath& aptdb_file,
// We haven't seen this airport yet in any apt.dat file
RawAirportInfo& airportInfo = insertRetval.first->second;
airportInfo.file = aptdb_file;
airportInfo.sceneryPath = sceneryLocation.sceneryPath;
airportInfo.rowCode = rowCode;
airportInfo.firstLineNum = line_num;
airportInfo.firstLineTokens = std::move(tokens);
@ -203,7 +205,7 @@ void APTLoader::loadAirports()
for (AirportInfoMapType::const_iterator it = airportInfoMap.begin();
it != airportInfoMap.end(); ++it) {
// Full path to the apt.dat file this airport info comes from
const string aptDat = it->second.file.utf8Str();
const SGPath aptDat = it->second.file;
// this is just the current airport identifier
last_apt_id = it->first;
@ -225,15 +227,15 @@ void APTLoader::loadAirports()
}
// Parse and return specific apt.dat file containing a single airport.
const FGAirport* APTLoader::loadAirportFromFile(const std::string& id, const SGPath& aptdb_file)
const FGAirport* APTLoader::loadAirportFromFile(const std::string& id, const NavDataCache::SceneryLocation& sceneryLocation)
{
std::size_t bytesReadSoFar = 10;
std::size_t totalSizeOfAllAptDatFiles = 100;
readAptDatFile(aptdb_file.str(), bytesReadSoFar, totalSizeOfAllAptDatFiles);
readAptDatFile(sceneryLocation, bytesReadSoFar, totalSizeOfAllAptDatFiles);
RawAirportInfo rawInfo = airportInfoMap[id];
return loadAirport(aptdb_file.c_str(), id, &rawInfo, true);
return loadAirport(sceneryLocation.datPath, id, &rawInfo, true);
}
static bool isCommLine(const int code)
@ -241,13 +243,15 @@ static bool isCommLine(const int code)
return ((code >= 50) && (code <= 56)) || ((code >= 1050) && (code <= 1056));
}
const FGAirport* APTLoader::loadAirport(const string& aptDat, const std::string& airportID, RawAirportInfo* airport_info, bool createFGAirport)
const FGAirport* APTLoader::loadAirport(const SGPath& aptDatFile, const std::string& airportID, RawAirportInfo* airport_info, bool createFGAirport)
{
// The first line for this airport was already split over whitespace, but
// remains to be parsed for the most part.
parseAirportLine(airport_info->rowCode, airport_info->firstLineTokens);
parseAirportLine(airport_info->rowCode, airport_info->firstLineTokens,
airport_info->sceneryPath);
const LinesList& lines = airport_info->otherLines;
const string aptDat = aptDatFile.utf8Str();
NodeBlock current_block = None;
// Loop over the second and subsequent lines
@ -422,7 +426,8 @@ void APTLoader::finishAirport(const string& aptDat)
// 'rowCode' is passed to avoid decoding it twice, since that work was already
// done in order to detect the start of the new airport.
void APTLoader::parseAirportLine(unsigned int rowCode,
const vector<string>& token)
const vector<string>& token,
const SGPath& sceneryPath)
{
// The algorithm in APTLoader::readAptDatFile() ensures this is at least 5.
vector<string>::size_type lastIndex = token.size() - 1;
@ -443,7 +448,7 @@ void APTLoader::parseAirportLine(unsigned int rowCode,
rwy_count = 0;
currentAirportPosID = cache->insertAirport(fptypeFromRobinType(rowCode),
id, name);
id, name, sceneryPath);
}
void APTLoader::parseRunwayLine810(const string& aptDat, unsigned int lineNum,

View file

@ -9,9 +9,11 @@
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <Navaids/positioned.hxx>
#include <Navaids/NavDataCache.hxx>
#include <simgear/compiler.h>
#include <simgear/math/SGGeod.hxx>
#include <simgear/misc/sg_path.hxx>
@ -20,7 +22,6 @@
#include "airport.hxx"
class NavDataCache;
class sg_gzifstream;
class FGPavement;
@ -36,7 +37,8 @@ public:
// Read the specified apt.dat file into 'airportInfoMap'.
// 'bytesReadSoFar' and 'totalSizeOfAllAptDatFiles' are used for progress
// information.
void readAptDatFile(const SGPath& aptdb_file, std::size_t bytesReadSoFar,
void readAptDatFile(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllAptDatFiles);
// Read all airports gathered in 'airportInfoMap' and load them into the
// navdata cache (even in case of overlapping apt.dat files,
@ -45,7 +47,7 @@ public:
// Load a specific airport defined in aptdb_file, and return a "rich" view
// of the airport including taxiways, pavement and line features.
const FGAirport* loadAirportFromFile(const std::string& id, const SGPath& aptdb_file);
const FGAirport* loadAirportFromFile(const std::string& id, const NavDataCache::SceneryLocation& sceneryLocation);
private:
struct Line {
@ -62,6 +64,8 @@ private:
struct RawAirportInfo {
// apt.dat file where the airport was defined
SGPath file;
// Base path of the corresponding scenery
SGPath sceneryPath;
// Row code for the airport (1, 16 or 17)
unsigned int rowCode;
// Line number in the apt.dat file where the airport definition starts
@ -80,7 +84,7 @@ private:
APTLoader(const APTLoader&); // disable copy constructor
APTLoader& operator=(const APTLoader&); // disable copy-assignment operator
const FGAirport* loadAirport(const std::string& aptDat, const std::string& airportID, RawAirportInfo* airport_info, bool createFGAirport = false);
const FGAirport* loadAirport(const SGPath& aptDat, const std::string& airportID, RawAirportInfo* airport_info, bool createFGAirport = false);
// Tell whether an apt.dat line is blank or a comment line
bool isBlankOrCommentLine(const std::string& line);
@ -89,7 +93,8 @@ private:
void throwExceptionIfStreamError(const sg_gzifstream& input_stream,
const SGPath& path);
void parseAirportLine(unsigned int rowCode,
const std::vector<std::string>& token);
const std::vector<std::string>& token,
const SGPath& sceneryPath);
void finishAirport(const std::string& aptDat);
void parseRunwayLine810(const std::string& aptDat, unsigned int lineNum,
const std::vector<std::string>& token);

View file

@ -18,6 +18,7 @@
#endif
#include <cstdio>
#include <utility>
#include <simgear/misc/sg_path.hxx>
#include <simgear/xml/easyxml.hxx>
@ -105,11 +106,19 @@ void XMLLoader::load(FGRunwayPreference* p) {
bool XMLLoader::findAirportData(const std::string& aICAO,
const std::string& aFileName, SGPath& aPath)
{
FGAirportRef airport = FGAirport::findByIdent(aICAO);
if (!airport) {
return false;
}
string fileName(aFileName);
if (!simgear::strutils::ends_with(aFileName, ".xml")) {
fileName.append(".xml");
}
const bool performFullTraversal = airport->sceneryPath().isNull() ||
!fileName.compare("procedures.xml");
PathList sc = globals->get_fg_scenery();
char buffer[128];
::snprintf(buffer, 128, "%c/%c/%c/%s.%s",
@ -119,13 +128,18 @@ bool XMLLoader::findAirportData(const std::string& aICAO,
for (PathList::const_iterator it = sc.begin(); it != sc.end(); ++it) {
// fg_senery contains empty strings as "markers" (see FGGlobals::set_fg_scenery)
if (!it->isNull()) {
SGPath path(*it);
path.append("Airports");
path.append(string(buffer));
const SGPath path = *it / "Airports" / buffer;
if (path.exists()) {
aPath = path;
aPath = std::move(path);
return true;
} // of path exists
// Unless we are in “full traversal mode”, don't look in scenery paths
// that come after the one which contributed the apt.dat file for the
// airport.
if (!performFullTraversal && *it == airport->sceneryPath()) {
return false;
}
}
} // of scenery path iteration
return false;

View file

@ -3110,7 +3110,15 @@ void Options::printJSONReport() const
// For this method, it doesn't matter if the cache is out-of-date
const NavDataCache::DatFilesGroupInfo& datFilesInfo =
cache->getDatFilesInfo(datType);
cJSON *datPathsNode = p->createJSONArrayFromPathList(datFilesInfo.paths);
// Create a list of SGPath instances (for the .dat files) from the list of
// NavDataCache::SceneryLocation structs that datFilesInfo.paths is.
PathList datFiles(datFilesInfo.paths.size());
const auto map = [](const auto& e) { return e.datPath; };
std::transform(std::cbegin(datFilesInfo.paths),
std::cend(datFilesInfo.paths), std::begin(datFiles), map);
cJSON *datPathsNode = p->createJSONArrayFromPathList(datFiles);
string key = NavDataCache::datTypeStr[datType] + ".dat files";
cJSON_AddItemToObject(navDataNode, key.c_str(), datPathsNode);
}

View file

@ -1,6 +1,6 @@
#pragma once
const int SCHEMA_VERSION = 21;
const int SCHEMA_VERSION = 22;
#define SCHEMA_SQL \
"CREATE TABLE properties (key VARCHAR, value VARCHAR);" \
@ -15,7 +15,7 @@ const int SCHEMA_VERSION = 21;
"CREATE INDEX pos_name ON positioned(name collate nocase);" \
"CREATE INDEX pos_apt_type ON positioned(airport, type);" \
\
"CREATE TABLE airport (has_metar BOOL);" \
"CREATE TABLE airport (scenery_path VARCHAR, has_metar BOOL);" \
"CREATE TABLE comm (freq_khz INT,range_nm INT);" \
"CREATE INDEX comm_freq ON comm(freq_khz);" \
\

View file

@ -17,6 +17,7 @@
#include <stdint.h> // for int64_t
#include <sstream> // for std::ostringstream
#include <mutex>
#include <utility>
#ifdef SYSTEM_SQLITE
// the standard sqlite3.h doesn't give a way to set SQLITE_UINT64_TYPE,
@ -563,7 +564,7 @@ public:
"(path, stamp, sha) VALUES (?,?, ?)");
loadPositioned = prepare("SELECT " POSITIONED_COLS " FROM positioned WHERE rowid=?");
loadAirportStmt = prepare("SELECT has_metar FROM airport WHERE rowid=?");
loadAirportStmt = prepare("SELECT scenery_path, has_metar FROM airport WHERE rowid=?");
loadNavaid = prepare("SELECT range_nm, freq, multiuse, runway, colocated FROM navaid WHERE rowid=?");
loadCommStation = prepare("SELECT freq_khz, range_nm FROM comm WHERE rowid=?");
loadRunwayStmt = prepare("SELECT heading, length_ft, width_m, surface, displaced_threshold,"
@ -588,7 +589,7 @@ public:
setAirportPos = prepare("UPDATE positioned SET lon=?2, lat=?3, elev_m=?4, octree_node=?5, "
"cart_x=?6, cart_y=?7, cart_z=?8 WHERE rowid=?1");
insertAirport = prepare("INSERT INTO airport (rowid, has_metar) VALUES (?, ?)");
insertAirport = prepare("INSERT INTO airport (rowid, scenery_path, has_metar) VALUES (?, ?, ?)");
insertNavaid = prepare("INSERT INTO navaid (rowid, freq, range_nm, multiuse, runway, colocated)"
" VALUES (?1, ?2, ?3, ?4, ?5, ?6)");
@ -704,10 +705,12 @@ public:
{
sqlite3_bind_int64(loadAirportStmt, 1, rowId);
execSelect1(loadAirportStmt);
bool hasMetar = (sqlite3_column_int(loadAirportStmt, 0) > 0);
SGPath sceneryPath{(char *) sqlite3_column_text(loadAirportStmt, 0)};
bool hasMetar = (sqlite3_column_int(loadAirportStmt, 1) > 0);
reset(loadAirportStmt);
return new FGAirport(rowId, id, pos, name, hasMetar, ty);
return new FGAirport(rowId, id, pos, name, hasMetar, ty,
std::move(sceneryPath));
}
FGRunwayBase* loadRunway(sqlite3_int64 rowId, FGPositioned::Type ty,
@ -1156,7 +1159,7 @@ void NavDataCache::NavDataCachePrivate::findDatFiles(
const std::string name = f.file();
if (simgear::strutils::ends_with(name, ".dat") ||
simgear::strutils::ends_with(name, ".dat.gz")) {
result.paths.push_back(f);
result.paths.push_back({f, path});
result.totalSize += f.sizeInBytes();
}
}
@ -1167,9 +1170,9 @@ void NavDataCache::NavDataCachePrivate::findDatFiles(
// now
SGPath defaultDatFile(globals->get_fg_root());
defaultDatFile.append(NavDataCache::defaultDatFile[datFileType]);
if ((result.paths.empty() || result.paths.back() != defaultDatFile) &&
if ((result.paths.empty() || result.paths.back().datPath != defaultDatFile) &&
defaultDatFile.isFile()) {
result.paths.push_back(defaultDatFile);
result.paths.push_back({defaultDatFile, globals->get_fg_root()});
result.totalSize += defaultDatFile.sizeInBytes();
}
@ -1195,8 +1198,8 @@ bool NavDataCache::NavDataCachePrivate::areDatFilesModified(
NavDataCache::datTypeStr[datFileType];
const string_list cachedFiles = outer->readOrderedStringListProperty(
datTypeStr + ".dat files", SGPath::pathListSep);
const PathList& datFiles = datFilesGroupInfo.paths;
PathList::const_iterator datFilesIt = datFiles.begin();
const auto& datFiles = datFilesGroupInfo.paths;
auto datFilesIt = datFiles.cbegin();
string_list::const_iterator cachedFilesIt = cachedFiles.begin();
// Same logic as in NavDataCachePrivate::isCachedFileModified()
sgDebugPriority logLevel = verbose ? SG_WARN : SG_DEBUG;
@ -1210,7 +1213,7 @@ bool NavDataCache::NavDataCachePrivate::areDatFilesModified(
}
while (datFilesIt != datFiles.end()) {
const SGPath& path = *(datFilesIt++);
const SGPath& path = (datFilesIt++)->datPath;
if (!path.exists()) {
throw sg_exception(
@ -1643,25 +1646,24 @@ void NavDataCache::setRebuildPhaseProgress(RebuildPhase ph, unsigned int percent
void NavDataCache::loadDatFiles(
DatFileType type,
std::function<void(const SGPath&, std::size_t, std::size_t)> loader)
std::function<void(const SceneryLocation&, std::size_t, std::size_t)> loader)
{
SGTimeStamp st;
string typeStr = datTypeStr[type];
const string typeStr = datTypeStr[type];
string_list datFiles;
NavDataCache::DatFilesGroupInfo datFilesInfo = getDatFilesInfo(type);
const PathList datPaths = datFilesInfo.paths;
const NavDataCache::DatFilesGroupInfo datFilesInfo = getDatFilesInfo(type);
const SceneryLocationList sceneryLocations = datFilesInfo.paths;
std::size_t bytesReadSoFar = 0;
st.stamp();
for (PathList::const_iterator it = datPaths.begin();
it != datPaths.end(); it++) {
string path = it->realpath().utf8Str();
for (const auto& scLoc : sceneryLocations) {
const string path = scLoc.datPath.realpath().utf8Str();
datFiles.push_back(path);
SG_LOG(SG_GENERAL, SG_INFO,
"Loading " + typeStr + ".dat file: '" << path << "'");
loader(*it, bytesReadSoFar, datFilesInfo.totalSize);
bytesReadSoFar += it->sizeInBytes();
stampCacheFile(*it); // this uses the realpath() of the file
"Loading " + typeStr + ".dat file: '" << std::move(path) << "'");
loader(scLoc, bytesReadSoFar, datFilesInfo.totalSize);
bytesReadSoFar += scLoc.datPath.sizeInBytes();
stampCacheFile(scLoc.datPath); // this uses the realpath() of the file
}
// Store the list of .dat files we have loaded
@ -2032,8 +2034,10 @@ FGPositionedRef NavDataCache::loadById(PositionedID rowid)
}
PositionedID NavDataCache::insertAirport(FGPositioned::Type ty, const string& ident,
const string& name)
const string& name,
const SGPath& sceneryPath)
{
const string sceneryPath_str = sceneryPath.utf8Str();
// airports have their pos computed based on the avergae runway centres
// so the pos isn't available immediately. Pass a dummy pos and avoid
// doing spatial indexing until later
@ -2042,6 +2046,7 @@ PositionedID NavDataCache::insertAirport(FGPositioned::Type ty, const string& id
false /* spatial index */);
sqlite3_bind_int64(d->insertAirport, 1, rowId);
sqlite_bind_stdstring(d->insertAirport, 2, sceneryPath_str);
d->execInsert(d->insertAirport);
return rowId;

View file

@ -10,9 +10,10 @@
#include <cstddef> // for std::size_t
#include <functional>
#include <memory>
#include <vector>
#include <Main/globals.hxx> // for PathList
#include <Navaids/positioned.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/strutils.hxx> // for string_list
@ -66,9 +67,16 @@ public:
DATFILETYPE_LAST
};
struct SceneryLocation {
SGPath datPath;
SGPath sceneryPath; // scenery realpath() the dat file belongs to
};
using SceneryLocationList = std::vector<SceneryLocation>;
struct DatFilesGroupInfo {
DatFileType datFileType; // for instance, DATFILETYPE_APT
PathList paths; // SGPath instances
SceneryLocationList paths;
std::size_t totalSize; // total size of all these files, in bytes
};
@ -144,7 +152,8 @@ public:
FGPositionedRef loadById(PositionedID guid);
PositionedID insertAirport(FGPositioned::Type ty, const std::string& ident,
const std::string& name);
const std::string& name,
const SGPath& sceneryPath);
void insertTower(PositionedID airportId, const SGGeod& pos);
@ -335,7 +344,7 @@ private:
// A generic function for loading all navigation data files of the
// specified type (apt/fix/nav etc.) using the passed type-specific loader.
void loadDatFiles(DatFileType type,
std::function<void(const SGPath&, std::size_t, std::size_t)> loader);
std::function<void(const SceneryLocation&, std::size_t, std::size_t)> loader);
void doRebuild();

View file

@ -65,9 +65,11 @@ FixesLoader::~FixesLoader()
{ }
// Load fixes from the specified fix.dat (or fix.dat.gz) file
void FixesLoader::loadFixes(const SGPath& path, std::size_t bytesReadSoFar,
void FixesLoader::loadFixes(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllDatFiles)
{
const SGPath path = sceneryLocation.datPath;
sg_gzifstream in( path );
const std::string utf8path = path.utf8Str();

View file

@ -25,6 +25,7 @@
#define _FG_FIXLIST_HXX
#include <Navaids/NavDataCache.hxx>
#include <simgear/compiler.h>
#include <simgear/math/SGGeod.hxx>
#include <unordered_map>
@ -35,8 +36,6 @@ class sg_gzifstream;
namespace flightgear
{
class NavDataCache; // forward declaration
class FixesLoader
{
public:
@ -44,7 +43,8 @@ namespace flightgear
~FixesLoader();
// Load fixes from the specified fix.dat (or fix.dat.gz) file
void loadFixes(const SGPath& path, std::size_t bytesReadSoFar,
void loadFixes(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllDatFiles);
private:

View file

@ -426,10 +426,12 @@ PositionedID NavLoader::processNavLine(
}
// load and initialize the navigational databases
void NavLoader::loadNav(const SGPath& path, std::size_t bytesReadSoFar,
void NavLoader::loadNav(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllDatFiles)
{
NavDataCache* cache = NavDataCache::instance();
const SGPath path = sceneryLocation.datPath;
const string utf8Path = path.utf8Str();
sg_gzifstream in(path);

View file

@ -27,11 +27,13 @@
#include <simgear/compiler.h>
#include <simgear/math/SGGeod.hxx>
#include <string>
#include <map>
#include <tuple>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/positioned.hxx>
#include <map>
#include <string>
#include <tuple>
// forward decls
class FGTACANList;
class SGPath;
@ -42,7 +44,8 @@ namespace flightgear
class NavLoader {
public:
// load and initialize the navigational databases
void loadNav(const SGPath& path, std::size_t bytesReadSoFar,
void loadNav(const NavDataCache::SceneryLocation& sceneryLocation,
std::size_t bytesReadSoFar,
std::size_t totalSizeOfAllDatFiles);
void loadCarrierNav(const SGPath& path);