Android release v6.7_preview1
[xcsoar.git] / src / Waypoint / WaypointWriter.cpp
blob667418f8937df1181334c8a314adc1b176aed2db
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Waypoint/WaypointWriter.hpp"
26 #include "Engine/Waypoint/Waypoints.hpp"
27 #include "IO/TextWriter.hpp"
28 #include "Engine/Waypoint/Runway.hpp"
29 #include "RadioFrequency.hpp"
31 void
32 WaypointWriter::Save(TextWriter &writer, WaypointFileType type)
34 // Iterate through the waypoint list and save each waypoint with
35 // the right file number to the TextWriter
36 /// @todo JMW: iteration ordered by ID would be preferred
37 for (auto it = waypoints.begin(); it != waypoints.end(); ++it) {
38 const Waypoint& wp = *it;
39 if (wp.file_num == file_number)
40 WriteWaypoint(writer, wp, type);
44 void
45 WaypointWriter::WriteWaypoint(TextWriter &writer, const Waypoint &wp, WaypointFileType type)
47 switch (type) {
48 case WaypointFileType::WINPILOT:
49 WriteWinPilot(writer, wp);
50 break;
52 case WaypointFileType::SEEYOU:
53 WriteSeeYou(writer, wp);
54 break;
56 case WaypointFileType::UNKNOWN:
57 case WaypointFileType::ZANDER:
58 case WaypointFileType::FS:
59 case WaypointFileType::OZI_EXPLORER:
60 case WaypointFileType::COMPE_GPS:
61 gcc_unreachable();
62 break;
66 void
67 WaypointWriter::WriteWinPilot(TextWriter &writer, const Waypoint &wp)
69 // Write the waypoint id
70 writer.Format("%u,", wp.original_id > 0 ? wp.original_id : wp.id);
72 // Write the latitude
73 WriteAngleDMS(writer, wp.location.latitude, true);
74 writer.Write(',');
76 // Write the longitude id
77 WriteAngleDMS(writer, wp.location.longitude, false);
78 writer.Write(',');
80 // Write the altitude id
81 WriteAltitude(writer, wp.elevation);
82 writer.Write(',');
84 // Write the waypoint flags
85 WriteWinPilotFlags(writer, wp);
86 writer.Write(',');
88 // Write the waypoint name
89 writer.Write(wp.name.c_str());
90 writer.Write(',');
92 // Write the waypoint description
93 writer.WriteLine(wp.comment.c_str());
96 void
97 WaypointWriter::WriteSeeYou(TextWriter &writer, const Waypoint &wp)
99 // Write Title
100 writer.Format("\"%s\",", wp.name.c_str());
102 // Write Code
103 writer.Write(',');
105 // Write Country
106 writer.Write(',');
108 // Write Latitude
109 WriteAngleDMM(writer, wp.location.latitude, true);
110 writer.Write(',');
112 // Write Longitude
113 WriteAngleDMM(writer, wp.location.longitude, false);
114 writer.Write(',');
116 // Write Elevation
117 WriteAltitude(writer, wp.elevation);
118 writer.Write(',');
120 // Write Style
121 WriteSeeYouFlags(writer, wp);
122 writer.Write(',');
124 // Write Runway Direction
125 if (wp.type == Waypoint::Type::AIRFIELD ||
126 wp.type == Waypoint::Type::OUTLANDING)
127 writer.Format("%03u", wp.runway.GetDirectionDegrees());
129 writer.Write(',');
131 // Write Runway Length
132 if (wp.type == Waypoint::Type::AIRFIELD ||
133 wp.type == Waypoint::Type::OUTLANDING)
134 writer.Format("%03uM", wp.runway.GetLength());
136 writer.Write(',');
138 // Write Airport Frequency
139 if (wp.radio_frequency.IsDefined()) {
140 const unsigned freq = wp.radio_frequency.GetKiloHertz();
141 writer.Format("\"%u.%03u\"", freq / 1000, freq % 1000);
144 writer.Write(',');
146 // Write Description
147 writer.FormatLine("\"%s\"", wp.comment.c_str());
150 void
151 WaypointWriter::WriteAngleDMS(TextWriter &writer, const Angle angle,
152 bool is_latitude)
154 // Calculate degrees, minutes and seconds
155 unsigned deg, min, sec;
156 bool is_positive;
157 angle.ToDMS(deg, min, sec, is_positive);
159 // Save them into the buffer string
160 writer.Format(is_latitude ? "%02u:%02u:%02u" : "%03u:%02u:%02u",
161 deg, min, sec);
163 // Attach the buffer string to the output
164 if (is_latitude)
165 writer.Write(is_positive ? "N" : "S");
166 else
167 writer.Write(is_positive ? "E" : "W");
170 void
171 WaypointWriter::WriteAngleDMM(TextWriter &writer, const Angle angle,
172 bool is_latitude)
174 // Calculate degrees, minutes and decimal minutes
175 unsigned deg, min, mmm;
176 bool is_positive;
177 angle.ToDMM(deg, min, mmm, is_positive);
179 // Save them into the buffer string
180 writer.Format(is_latitude ? "%02u%02u.%03u" : "%03u%02u.%03u",
181 deg, min, mmm);
183 // Attach the buffer string to the output
184 if (is_latitude)
185 writer.Write(is_positive ? "N" : "S");
186 else
187 writer.Write(is_positive ? "E" : "W");
190 void
191 WaypointWriter::WriteAltitude(TextWriter &writer, fixed altitude)
193 writer.Format("%dM", (int)altitude);
196 void
197 WaypointWriter::WriteWinPilotFlags(TextWriter &writer, const Waypoint &wp)
199 if (wp.IsAirport())
200 writer.Write('A');
201 if (wp.flags.turn_point)
202 writer.Write('T');
203 if (wp.IsLandable())
204 writer.Write('L');
205 if (wp.flags.home)
206 writer.Write('H');
207 if (wp.flags.start_point)
208 writer.Write('S');
209 if (wp.flags.finish_point)
210 writer.Write('F');
212 // set as turnpoint by default if nothing else
213 if (!wp.flags.turn_point &&
214 !wp.IsLandable() &&
215 !wp.flags.home &&
216 !wp.flags.start_point &&
217 !wp.flags.finish_point)
218 writer.Write('T');
221 void
222 WaypointWriter::WriteSeeYouFlags(TextWriter &writer, const Waypoint &wp)
224 switch (wp.type) {
225 case Waypoint::Type::NORMAL:
226 writer.Write('1');
227 break;
229 case Waypoint::Type::OUTLANDING:
230 writer.Write('3');
231 break;
233 case Waypoint::Type::AIRFIELD:
234 if (wp.flags.home)
235 writer.Write('4');
236 else // 2 or 5 no rule for this!
237 writer.Write('2');
238 break;
240 case Waypoint::Type::MOUNTAIN_PASS:
241 writer.Write('6');
242 break;
244 case Waypoint::Type::MOUNTAIN_TOP:
245 writer.Write('7');
246 break;
248 case Waypoint::Type::OBSTACLE:
249 writer.Write('8');
250 break;
252 case Waypoint::Type::TOWER:
253 // 11 or 16 no rule for this!
254 writer.Write("11");
255 break;
257 case Waypoint::Type::TUNNEL:
258 writer.Write("13");
259 break;
261 case Waypoint::Type::BRIDGE:
262 writer.Write("14");
263 break;
265 case Waypoint::Type::POWERPLANT:
266 writer.Write("15");
267 break;
269 case Waypoint::Type::THERMAL_HOTSPOT:
270 break;