2012-08-28 00:26:36 +01:00
|
|
|
/**
|
|
|
|
* NavDataCache.hxx - defines a unified binary cache for navigation
|
|
|
|
* data, parsed from various text / XML sources.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Written by James Turner, started 2012.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2012 James Turner
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
#ifndef FG_NAVDATACACHE_HXX
|
|
|
|
#define FG_NAVDATACACHE_HXX
|
|
|
|
|
|
|
|
#include <memory>
|
2012-09-19 18:15:49 +01:00
|
|
|
|
|
|
|
#include <simgear/misc/strutils.hxx> // for string_list
|
2012-08-28 00:26:36 +01:00
|
|
|
#include <Navaids/positioned.hxx>
|
|
|
|
|
|
|
|
class SGPath;
|
2012-10-01 17:18:36 +01:00
|
|
|
class FGRunway;
|
2012-08-28 00:26:36 +01:00
|
|
|
|
|
|
|
namespace flightgear
|
|
|
|
{
|
|
|
|
|
|
|
|
/// a pair of airport ID, runway ID
|
|
|
|
typedef std::pair<PositionedID, PositionedID> AirportRunwayPair;
|
|
|
|
|
|
|
|
typedef std::pair<FGPositioned::Type, PositionedID> TypedPositioned;
|
|
|
|
typedef std::vector<TypedPositioned> TypedPositionedVec;
|
|
|
|
|
|
|
|
// pair of airway ID, destination node ID
|
|
|
|
typedef std::pair<int, PositionedID> AirwayEdge;
|
|
|
|
typedef std::vector<AirwayEdge> AirwayEdgeVec;
|
|
|
|
|
|
|
|
namespace Octree {
|
|
|
|
class Node;
|
|
|
|
class Branch;
|
|
|
|
}
|
|
|
|
|
|
|
|
class NavDataCache
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~NavDataCache();
|
|
|
|
|
|
|
|
// singleton accessor
|
|
|
|
static NavDataCache* instance();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* predicate - check if the cache needs to be rebuilt.
|
|
|
|
* This can happen is the cache file is missing or damaged, or one of the
|
|
|
|
** global input files is changed.
|
|
|
|
*/
|
|
|
|
bool isRebuildRequired();
|
|
|
|
|
|
|
|
/**
|
2012-09-25 17:24:12 +01:00
|
|
|
* run the cache rebuild - returns true if rebuild is complete,
|
|
|
|
* otherwise keep going.
|
2012-08-28 00:26:36 +01:00
|
|
|
*/
|
2012-09-25 17:24:12 +01:00
|
|
|
bool rebuild();
|
2012-08-28 00:26:36 +01:00
|
|
|
|
|
|
|
bool isCachedFileModified(const SGPath& path) const;
|
|
|
|
void stampCacheFile(const SGPath& path);
|
|
|
|
|
|
|
|
int readIntProperty(const std::string& key);
|
|
|
|
double readDoubleProperty(const std::string& key);
|
|
|
|
std::string readStringProperty(const std::string& key);
|
|
|
|
|
|
|
|
void writeIntProperty(const std::string& key, int value);
|
|
|
|
void writeStringProperty(const std::string& key, const std::string& value);
|
|
|
|
void writeDoubleProperty(const std::string& key, const double& value);
|
|
|
|
|
2012-09-19 18:15:49 +01:00
|
|
|
string_list readStringListProperty(const std::string& key);
|
|
|
|
void writeStringListProperty(const std::string& key, const string_list& values);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* retrieve an FGPositioned from the cache.
|
|
|
|
* This may be trivial if the object is previously loaded, or require actual
|
|
|
|
* disk IO.
|
|
|
|
*/
|
2013-03-06 23:21:29 +01:00
|
|
|
FGPositionedRef loadById(PositionedID guid);
|
2012-08-28 00:26:36 +01:00
|
|
|
|
|
|
|
PositionedID insertAirport(FGPositioned::Type ty, const std::string& ident,
|
|
|
|
const std::string& name);
|
|
|
|
void insertTower(PositionedID airportId, const SGGeod& pos);
|
|
|
|
PositionedID insertRunway(FGPositioned::Type ty, const std::string& ident,
|
|
|
|
const SGGeod& pos, PositionedID apt,
|
|
|
|
double heading, double length, double width, double displacedThreshold,
|
|
|
|
double stopway, int surfaceCode);
|
|
|
|
void setRunwayReciprocal(PositionedID runway, PositionedID recip);
|
|
|
|
void setRunwayILS(PositionedID runway, PositionedID ils);
|
|
|
|
|
|
|
|
void updateRunwayThreshold(PositionedID runwayID, const SGGeod &aThreshold,
|
|
|
|
double aHeading, double aDisplacedThreshold,
|
|
|
|
double aStopway);
|
|
|
|
|
|
|
|
PositionedID insertNavaid(FGPositioned::Type ty, const std::string& ident,
|
|
|
|
const std::string& name, const SGGeod& pos, int freq, int range, double multiuse,
|
|
|
|
PositionedID apt, PositionedID runway);
|
|
|
|
void updateILS(PositionedID ils, const SGGeod& newPos, double aHdg);
|
2013-03-07 23:31:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
// Assign colocated DME to a navaid
|
|
|
|
void setNavaidColocated(PositionedID navaid, PositionedID colocatedDME);
|
2012-08-28 00:26:36 +01:00
|
|
|
|
|
|
|
PositionedID insertCommStation(FGPositioned::Type ty,
|
|
|
|
const std::string& name, const SGGeod& pos, int freq, int range,
|
|
|
|
PositionedID apt);
|
|
|
|
PositionedID insertFix(const std::string& ident, const SGGeod& aPos);
|
|
|
|
|
2013-03-02 13:44:20 +00:00
|
|
|
PositionedID createPOI(FGPositioned::Type ty, const std::string& ident, const SGGeod& aPos);
|
2012-08-28 00:26:36 +01:00
|
|
|
|
2013-03-02 13:44:20 +00:00
|
|
|
void removePOI(FGPositioned::Type ty, const std::string& aIdent);
|
|
|
|
|
2012-11-24 12:14:56 +00:00
|
|
|
void dropGroundnetFor(PositionedID aAirport);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
PositionedID insertParking(const std::string& name, const SGGeod& aPos,
|
|
|
|
PositionedID aAirport,
|
|
|
|
double aHeading, int aRadius, const std::string& aAircraftType,
|
|
|
|
const std::string& aAirlines);
|
|
|
|
|
|
|
|
void setParkingPushBackRoute(PositionedID parking, PositionedID pushBackNode);
|
|
|
|
|
|
|
|
PositionedID insertTaxiNode(const SGGeod& aPos, PositionedID aAirport, int aHoldType, bool aOnRunway);
|
|
|
|
|
|
|
|
void insertGroundnetEdge(PositionedID aAirport, PositionedID from, PositionedID to);
|
|
|
|
|
|
|
|
/// update the metar flag associated with an airport
|
2012-08-28 00:26:36 +01:00
|
|
|
void setAirportMetar(const std::string& icao, bool hasMetar);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* Modify the position of an existing item.
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
void updatePosition(PositionedID item, const SGGeod &pos);
|
|
|
|
|
2013-03-06 23:21:29 +01:00
|
|
|
FGPositionedList findAllWithIdent( const std::string& ident,
|
|
|
|
FGPositioned::Filter* filter,
|
|
|
|
bool exact );
|
|
|
|
FGPositionedList findAllWithName( const std::string& ident,
|
|
|
|
FGPositioned::Filter* filter,
|
|
|
|
bool exact );
|
2012-08-28 00:26:36 +01:00
|
|
|
|
2013-03-06 23:21:29 +01:00
|
|
|
FGPositionedRef findClosestWithIdent( const std::string& aIdent,
|
|
|
|
const SGGeod& aPos,
|
|
|
|
FGPositioned::Filter* aFilter );
|
2012-08-28 00:26:36 +01:00
|
|
|
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* Helper to implement the AirportSearch widget. Optimised text search of
|
|
|
|
* airport names and idents, returning a list suitable for passing directly
|
|
|
|
* to PLIB.
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
char** searchAirportNamesAndIdents(const std::string& aFilter);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* Find the closest matching comm-station on a frequency, to a position.
|
|
|
|
* The filter with be used for both type ranging and to validate the result
|
|
|
|
* candidates.
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
FGPositionedRef findCommByFreq(int freqKhz, const SGGeod& pos, FGPositioned::Filter* filt);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* find all items of a specified type (or range of types) at an airport
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
PositionedIDVec airportItemsOfType(PositionedID apt, FGPositioned::Type ty,
|
|
|
|
FGPositioned::Type maxTy = FGPositioned::INVALID);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* find the first match item of the specified type and ident, at an airport
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
PositionedID airportItemWithIdent(PositionedID apt, FGPositioned::Type ty, const std::string& ident);
|
2012-10-01 17:18:36 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find all navaids matching a particular frequency, sorted by range from the
|
|
|
|
* supplied position. Type-range will be determined from the filter
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
PositionedIDVec findNavaidsByFreq(int freqKhz, const SGGeod& pos, FGPositioned::Filter* filt);
|
|
|
|
|
|
|
|
/// overload version of the above that does not consider positioned when
|
|
|
|
/// returning results. Only used by TACAN carrier search
|
|
|
|
PositionedIDVec findNavaidsByFreq(int freqKhz, FGPositioned::Filter* filt);
|
|
|
|
|
2012-10-30 15:43:54 +00:00
|
|
|
/**
|
|
|
|
* Given a runway and type, find the corresponding navaid (ILS / GS / OM)
|
|
|
|
*/
|
|
|
|
PositionedID findNavaidForRunway(PositionedID runway, FGPositioned::Type ty);
|
2013-03-07 23:31:01 +01:00
|
|
|
|
2012-08-28 00:26:36 +01:00
|
|
|
/**
|
|
|
|
* given a navaid name (or similar) from apt.dat / nav.dat, find the
|
|
|
|
* corresponding airport and runway IDs.
|
|
|
|
* Such names look like: 'LHBP 31L DME-ILS' or 'UEEE 23L MM'
|
|
|
|
*/
|
|
|
|
AirportRunwayPair findAirportRunway(const std::string& name);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given an aiport, and runway and ILS identifier, find the corresponding cache
|
|
|
|
* entry. This matches the data we get in the ils.xml files for airports.
|
|
|
|
*/
|
|
|
|
PositionedID findILS(PositionedID airport, const std::string& runway, const std::string& navIdent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given an Octree node ID, return a bit-mask defining which of the child
|
|
|
|
* nodes exist. In practice this means an 8-bit value be sufficent, but
|
|
|
|
* an int works fine too.
|
|
|
|
*/
|
|
|
|
int getOctreeBranchChildren(int64_t octreeNodeId);
|
|
|
|
|
|
|
|
void defineOctreeNode(Octree::Branch* pr, Octree::Node* nd);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* given an octree leaf, return all its child positioned items and their types
|
|
|
|
*/
|
|
|
|
TypedPositionedVec getOctreeLeafChildren(int64_t octreeNodeId);
|
|
|
|
|
|
|
|
// airways
|
|
|
|
int findAirway(int network, const std::string& aName);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/**
|
|
|
|
* insert an edge between two positioned nodes, into the network.
|
|
|
|
* The airway identifier will be set accordingly. No reverse edge is created
|
|
|
|
* by this method - edges are directional so a reverses must be explicitly
|
|
|
|
* created.
|
|
|
|
*/
|
2012-08-28 00:26:36 +01:00
|
|
|
void insertEdge(int network, int airwayID, PositionedID from, PositionedID to);
|
|
|
|
|
2012-10-01 17:18:36 +01:00
|
|
|
/// is the specified positioned a node on the network?
|
2012-08-28 00:26:36 +01:00
|
|
|
bool isInAirwayNetwork(int network, PositionedID pos);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* retrive all the destination points reachcable from a positioned
|
|
|
|
* in an airway
|
|
|
|
*/
|
|
|
|
AirwayEdgeVec airwayEdgesFrom(int network, PositionedID pos);
|
2012-10-01 17:18:36 +01:00
|
|
|
|
|
|
|
// ground-network
|
|
|
|
PositionedIDVec groundNetNodes(PositionedID aAirport, bool onlyPushback);
|
|
|
|
void markGroundnetAsPushback(PositionedID nodeId);
|
|
|
|
|
|
|
|
PositionedID findGroundNetNode(PositionedID airport, const SGGeod& aPos,
|
|
|
|
bool onRunway, FGRunway* aRunway = NULL);
|
|
|
|
PositionedIDVec groundNetEdgesFrom(PositionedID pos, bool onlyPushback);
|
|
|
|
|
|
|
|
PositionedIDVec findAirportParking(PositionedID airport, const std::string& flightType,
|
|
|
|
int radius);
|
2012-12-23 23:32:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Transaction
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Transaction(NavDataCache* cache);
|
|
|
|
~Transaction();
|
|
|
|
|
|
|
|
void commit();
|
|
|
|
private:
|
|
|
|
NavDataCache* _instance;
|
|
|
|
bool _committed;
|
|
|
|
};
|
2012-08-28 00:26:36 +01:00
|
|
|
private:
|
|
|
|
NavDataCache();
|
2012-09-25 17:24:12 +01:00
|
|
|
|
|
|
|
friend class RebuildThread;
|
|
|
|
void doRebuild();
|
|
|
|
|
2012-12-23 23:32:53 +00:00
|
|
|
friend class Transaction;
|
|
|
|
|
|
|
|
void beginTransaction();
|
|
|
|
void commitTransaction();
|
|
|
|
void abortTransaction();
|
|
|
|
|
2012-08-28 00:26:36 +01:00
|
|
|
class NavDataCachePrivate;
|
|
|
|
std::auto_ptr<NavDataCachePrivate> d;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // of namespace flightgear
|
|
|
|
|
|
|
|
#endif // of FG_NAVDATACACHE_HXX
|
|
|
|
|