1 // apt_loader.hxx -- a front end loader of the apt.dat file.  This loader
2 //                   populates the runway and basic classes.
3 //
4 // Written by Curtis Olson, started December 2004.
5 //
6 // Copyright (C) 2004  Curtis L. Olson  - http://www.flightgear.org/~curt
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 // $Id$
23 
24 
25 #ifndef _FG_APT_LOADER_HXX
26 #define _FG_APT_LOADER_HXX
27 
28 #include <string>
29 #include <vector>
30 #include <unordered_map>
31 
32 #include <simgear/compiler.h>
33 #include <simgear/structure/SGSharedPtr.hxx>
34 #include <simgear/math/SGGeod.hxx>
35 #include <simgear/misc/sg_path.hxx>
36 #include <Navaids/positioned.hxx>
37 
38 class NavDataCache;
39 class sg_gzifstream;
40 class FGPavement;
41 
42 namespace flightgear
43 {
44 
45 class APTLoader
46 {
47 public:
48   APTLoader();
49   ~APTLoader();
50 
51   // Read the specified apt.dat file into 'airportInfoMap'.
52   // 'bytesReadSoFar' and 'totalSizeOfAllAptDatFiles' are used for progress
53   // information.
54   void readAptDatFile(const SGPath& aptdb_file, std::size_t bytesReadSoFar,
55                       std::size_t totalSizeOfAllAptDatFiles);
56   // Read all airports gathered in 'airportInfoMap' and load them into the
57   // navdata cache (even in case of overlapping apt.dat files,
58   // 'airportInfoMap' has only one entry per airport).
59   void loadAirports();
60 
61 private:
62   struct Line
63   {
Lineflightgear::APTLoader::Line64     Line(unsigned int number_, unsigned int rowCode_, std::string str_)
65       : number(number_), rowCode(rowCode_), str(str_) { }
66 
67     unsigned int number;
68     unsigned int rowCode;         // Terminology of the apt.dat spec
69     std::string str;
70   };
71 
72   typedef std::vector<Line> LinesList;
73 
74   struct RawAirportInfo
75   {
76     // apt.dat file where the airport was defined
77     SGPath file;
78     // Row code for the airport (1, 16 or 17)
79     unsigned int rowCode;
80     // Line number in the apt.dat file where the airport definition starts
81     unsigned int firstLineNum;
82     // The whitespace-separated strings comprising the first line of the airport
83     // definition
84     std::vector<std::string> firstLineTokens;
85     // Subsequent lines of the airport definition (one element per line)
86     LinesList otherLines;
87   };
88 
89   typedef std::unordered_map<std::string, RawAirportInfo> AirportInfoMapType;
90   typedef SGSharedPtr<FGPavement> FGPavementPtr;
91 
92   APTLoader(const APTLoader&);            // disable copy constructor
93   APTLoader& operator=(const APTLoader&); // disable copy-assignment operator
94 
95   // Tell whether an apt.dat line is blank or a comment line
96   bool isBlankOrCommentLine(const std::string& line);
97   // Return a copy of 'line' with trailing '\r' char(s) removed
98   std::string cleanLine(const std::string& line);
99   void throwExceptionIfStreamError(const sg_gzifstream& input_stream,
100                                    const SGPath& path);
101   void parseAirportLine(unsigned int rowCode,
102                         const std::vector<std::string>& token);
103   void finishAirport(const std::string& aptDat);
104   void parseRunwayLine810(const std::string& aptDat, unsigned int lineNum,
105                           const std::vector<std::string>& token);
106   void parseRunwayLine850(const std::string& aptDat, unsigned int lineNum,
107                           const std::vector<std::string>& token);
108   void parseWaterRunwayLine850(const std::string& aptDat, unsigned int lineNum,
109                                const std::vector<std::string>& token);
110   void parseHelipadLine850(const std::string& aptDat, unsigned int lineNum,
111                            const std::vector<std::string>& token);
112   void parseViewpointLine(const std::string& aptDat, unsigned int lineNum,
113                           const std::vector<std::string>& token);
114   void parsePavementLine850(const std::vector<std::string>& token);
115   void parsePavementNodeLine850(
116     const std::string& aptDat, unsigned int lineNum, int rowCode,
117     const std::vector<std::string>& token);
118   void parseCommLine(
119     const std::string& aptDat, unsigned int lineNum, unsigned int rowCode,
120     const std::vector<std::string>& token);
121 
122   std::vector<std::string> token;
123   AirportInfoMapType airportInfoMap;
124   double rwy_lat_accum;
125   double rwy_lon_accum;
126   double last_rwy_heading;
127   int rwy_count;
128   std::string last_apt_id;
129   double last_apt_elev;
130   SGGeod tower;
131 
132   std::string pavement_ident;
133   bool pavement;
134   std::vector<FGPavementPtr> pavements;
135 
136   // Not an airport identifier in the sense of the apt.dat spec!
137   PositionedID currentAirportPosID;
138   NavDataCache* cache;
139 };
140 
141 bool metarDataLoad(const SGPath& path);
142 
143 } // of namespace flighgear
144 
145 #endif // _FG_APT_LOADER_HXX
146