]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/NavDataCache.hxx
31616769301fd2d79f4e0e45a95bcb0ff17d3bf0
[flightgear.git] / src / Navaids / NavDataCache.hxx
1 /**
2  * NavDataCache.hxx - defines a unified binary cache for navigation
3  * data, parsed from various text / XML sources.
4  */
5  
6 // Written by James Turner, started 2012.
7 //
8 // Copyright (C) 2012 James Turner
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23
24 #ifndef FG_NAVDATACACHE_HXX
25 #define FG_NAVDATACACHE_HXX
26
27 #include <memory>
28
29 #include <simgear/misc/strutils.hxx> // for string_list
30 #include <Navaids/positioned.hxx>
31     
32 class SGPath;
33 class FGRunway;
34
35 namespace flightgear
36 {
37   
38 /// a pair of airport ID, runway ID
39 typedef std::pair<PositionedID, PositionedID> AirportRunwayPair;
40   
41 typedef std::pair<FGPositioned::Type, PositionedID> TypedPositioned;
42 typedef std::vector<TypedPositioned> TypedPositionedVec;
43
44 // pair of airway ID, destination node ID
45 typedef std::pair<int, PositionedID> AirwayEdge;
46 typedef std::vector<AirwayEdge> AirwayEdgeVec;
47   
48 namespace Octree {
49   class Node;
50   class Branch;
51 }
52   
53 class NavDataCache
54 {
55 public:
56     ~NavDataCache();
57     
58 // singleton accessor
59     static NavDataCache* instance();
60           
61   /**
62    * predicate - check if the cache needs to be rebuilt.
63    * This can happen is the cache file is missing or damaged, or one of the
64    ** global input files is changed.
65    */
66   bool isRebuildRequired();
67   
68   /**
69    * run the cache rebuild - returns true if rebuild is complete,
70    * otherwise keep going.
71    */
72   bool rebuild();
73   
74   bool isCachedFileModified(const SGPath& path) const;
75   void stampCacheFile(const SGPath& path);
76   
77   int readIntProperty(const std::string& key);
78   double readDoubleProperty(const std::string& key);
79   std::string readStringProperty(const std::string& key);
80   
81   void writeIntProperty(const std::string& key, int value);
82   void writeStringProperty(const std::string& key, const std::string& value);
83   void writeDoubleProperty(const std::string& key, const double& value);
84   
85   string_list readStringListProperty(const std::string& key);
86   void writeStringListProperty(const std::string& key, const string_list& values);
87   
88   /**
89    * retrieve an FGPositioned from the cache.
90    * This may be trivial if the object is previously loaded, or require actual
91    * disk IO.
92    */
93   FGPositionedRef loadById(PositionedID guid);
94   
95   PositionedID insertAirport(FGPositioned::Type ty, const std::string& ident,
96                              const std::string& name);
97   void insertTower(PositionedID airportId, const SGGeod& pos);
98   PositionedID insertRunway(FGPositioned::Type ty, const std::string& ident,
99                           const SGGeod& pos, PositionedID apt,
100                           double heading, double length, double width, double displacedThreshold,
101                           double stopway, int surfaceCode);
102   void setRunwayReciprocal(PositionedID runway, PositionedID recip);
103   void setRunwayILS(PositionedID runway, PositionedID ils);
104   
105   void updateRunwayThreshold(PositionedID runwayID, const SGGeod &aThreshold,
106                     double aHeading, double aDisplacedThreshold,
107                     double aStopway);
108   
109   PositionedID insertNavaid(FGPositioned::Type ty, const std::string& ident,
110                             const std::string& name, const SGGeod& pos, int freq, int range, double multiuse,
111                             PositionedID apt, PositionedID runway);
112   void updateILS(PositionedID ils, const SGGeod& newPos, double aHdg);
113
114
115   // Assign colocated DME to a navaid
116   void setNavaidColocated(PositionedID navaid, PositionedID colocatedDME);
117   
118   PositionedID insertCommStation(FGPositioned::Type ty,
119                                  const std::string& name, const SGGeod& pos, int freq, int range,
120                                 PositionedID apt);
121   PositionedID insertFix(const std::string& ident, const SGGeod& aPos);
122   
123   PositionedID createPOI(FGPositioned::Type ty, const std::string& ident, const SGGeod& aPos);
124   
125   void removePOI(FGPositioned::Type ty, const std::string& aIdent);
126     
127   void dropGroundnetFor(PositionedID aAirport);
128   
129   PositionedID insertParking(const std::string& name, const SGGeod& aPos,
130                              PositionedID aAirport,
131                              double aHeading, int aRadius, const std::string& aAircraftType,
132                              const std::string& aAirlines);
133   
134   void setParkingPushBackRoute(PositionedID parking, PositionedID pushBackNode);
135   
136   PositionedID insertTaxiNode(const SGGeod& aPos, PositionedID aAirport, int aHoldType, bool aOnRunway);
137   
138   void insertGroundnetEdge(PositionedID aAirport, PositionedID from, PositionedID to);
139   
140   /// update the metar flag associated with an airport
141   void setAirportMetar(const std::string& icao, bool hasMetar);
142   
143   /**
144    * Modify the position of an existing item.
145    */
146   void updatePosition(PositionedID item, const SGGeod &pos);
147   
148   FGPositionedList findAllWithIdent( const std::string& ident,
149                                      FGPositioned::Filter* filter,
150                                      bool exact );
151   FGPositionedList findAllWithName( const std::string& ident,
152                                     FGPositioned::Filter* filter,
153                                     bool exact );
154   
155   FGPositionedRef findClosestWithIdent( const std::string& aIdent,
156                                         const SGGeod& aPos,
157                                         FGPositioned::Filter* aFilter );
158   
159
160   /**
161    * Helper to implement the AirportSearch widget. Optimised text search of
162    * airport names and idents, returning a list suitable for passing directly
163    * to PLIB.
164    */
165   char** searchAirportNamesAndIdents(const std::string& aFilter);
166   
167   /**
168    * Find the closest matching comm-station on a frequency, to a position.
169    * The filter with be used for both type ranging and to validate the result
170    * candidates.
171    */
172   FGPositionedRef findCommByFreq(int freqKhz, const SGGeod& pos, FGPositioned::Filter* filt);
173   
174   /**
175    * find all items of a specified type (or range of types) at an airport
176    */
177   PositionedIDVec airportItemsOfType(PositionedID apt, FGPositioned::Type ty,
178                                      FGPositioned::Type maxTy = FGPositioned::INVALID);
179     
180   /**
181    * find the first match item of the specified type and ident, at an airport
182    */
183   PositionedID airportItemWithIdent(PositionedID apt, FGPositioned::Type ty, const std::string& ident);
184     
185   /**
186    * Find all navaids matching a particular frequency, sorted by range from the
187    * supplied position. Type-range will be determined from the filter
188    */
189   PositionedIDVec findNavaidsByFreq(int freqKhz, const SGGeod& pos, FGPositioned::Filter* filt);
190   
191   /// overload version of the above that does not consider positioned when
192   /// returning results. Only used by TACAN carrier search
193   PositionedIDVec findNavaidsByFreq(int freqKhz, FGPositioned::Filter* filt);
194   
195   /**
196    * Given a runway and type, find the corresponding navaid (ILS / GS / OM)
197    */
198   PositionedID findNavaidForRunway(PositionedID runway, FGPositioned::Type ty);
199
200   /**
201    * given a navaid name (or similar) from apt.dat / nav.dat, find the
202    * corresponding airport and runway IDs.
203    * Such names look like: 'LHBP 31L DME-ILS' or 'UEEE 23L MM'
204    */
205   AirportRunwayPair findAirportRunway(const std::string& name);
206   
207   /**
208    * Given an aiport, and runway and ILS identifier, find the corresponding cache
209    * entry. This matches the data we get in the ils.xml files for airports.
210    */
211   PositionedID findILS(PositionedID airport, const std::string& runway, const std::string& navIdent);
212   
213   /**
214    * Given an Octree node ID, return a bit-mask defining which of the child
215    * nodes exist. In practice this means an 8-bit value be sufficent, but
216    * an int works fine too.
217    */
218   int getOctreeBranchChildren(int64_t octreeNodeId);
219   
220   void defineOctreeNode(Octree::Branch* pr, Octree::Node* nd);
221     
222   /**
223    * given an octree leaf, return all its child positioned items and their types
224    */
225   TypedPositionedVec getOctreeLeafChildren(int64_t octreeNodeId);
226   
227 // airways
228   int findAirway(int network, const std::string& aName);
229   
230   /**
231    * insert an edge between two positioned nodes, into the network.
232    * The airway identifier will be set accordingly. No reverse edge is created
233    * by this method - edges are directional so a reverses must be explicitly
234    * created.
235    */
236   void insertEdge(int network, int airwayID, PositionedID from, PositionedID to);
237   
238   /// is the specified positioned a node on the network?
239   bool isInAirwayNetwork(int network, PositionedID pos);
240   
241   /**
242    * retrive all the destination points reachcable from a positioned
243    * in an airway
244    */
245   AirwayEdgeVec airwayEdgesFrom(int network, PositionedID pos);
246   
247 // ground-network
248   PositionedIDVec groundNetNodes(PositionedID aAirport, bool onlyPushback);
249   void markGroundnetAsPushback(PositionedID nodeId);
250   
251   PositionedID findGroundNetNode(PositionedID airport, const SGGeod& aPos,
252                                  bool onRunway, FGRunway* aRunway = NULL);
253   PositionedIDVec groundNetEdgesFrom(PositionedID pos, bool onlyPushback);
254   
255   PositionedIDVec findAirportParking(PositionedID airport, const std::string& flightType,
256                                      int radius);
257
258
259     class Transaction
260     {
261     public:
262         Transaction(NavDataCache* cache);
263         ~Transaction();
264         
265         void commit();
266     private:
267         NavDataCache* _instance;
268         bool _committed;
269     };
270 private:
271   NavDataCache();
272   
273   friend class RebuildThread;
274   void doRebuild();
275   
276   friend class Transaction;
277   
278     void beginTransaction();
279     void commitTransaction();
280     void abortTransaction();
281     
282   class NavDataCachePrivate;
283   std::auto_ptr<NavDataCachePrivate> d;      
284 };
285   
286 } // of namespace flightgear
287
288 #endif // of FG_NAVDATACACHE_HXX
289