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"
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
);
45 WaypointWriter::WriteWaypoint(TextWriter
&writer
, const Waypoint
&wp
, WaypointFileType type
)
48 case WaypointFileType::WINPILOT
:
49 WriteWinPilot(writer
, wp
);
52 case WaypointFileType::SEEYOU
:
53 WriteSeeYou(writer
, wp
);
56 case WaypointFileType::UNKNOWN
:
57 case WaypointFileType::ZANDER
:
58 case WaypointFileType::FS
:
59 case WaypointFileType::OZI_EXPLORER
:
60 case WaypointFileType::COMPE_GPS
:
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
);
73 WriteAngleDMS(writer
, wp
.location
.latitude
, true);
76 // Write the longitude id
77 WriteAngleDMS(writer
, wp
.location
.longitude
, false);
80 // Write the altitude id
81 WriteAltitude(writer
, wp
.elevation
);
84 // Write the waypoint flags
85 WriteWinPilotFlags(writer
, wp
);
88 // Write the waypoint name
89 writer
.Write(wp
.name
.c_str());
92 // Write the waypoint description
93 writer
.WriteLine(wp
.comment
.c_str());
97 WaypointWriter::WriteSeeYou(TextWriter
&writer
, const Waypoint
&wp
)
100 writer
.Format("\"%s\",", wp
.name
.c_str());
109 WriteAngleDMM(writer
, wp
.location
.latitude
, true);
113 WriteAngleDMM(writer
, wp
.location
.longitude
, false);
117 WriteAltitude(writer
, wp
.elevation
);
121 WriteSeeYouFlags(writer
, wp
);
124 // Write Runway Direction
125 if (wp
.type
== Waypoint::Type::AIRFIELD
||
126 wp
.type
== Waypoint::Type::OUTLANDING
)
127 writer
.Format("%03u", wp
.runway
.GetDirectionDegrees());
131 // Write Runway Length
132 if (wp
.type
== Waypoint::Type::AIRFIELD
||
133 wp
.type
== Waypoint::Type::OUTLANDING
)
134 writer
.Format("%03uM", wp
.runway
.GetLength());
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);
147 writer
.FormatLine("\"%s\"", wp
.comment
.c_str());
151 WaypointWriter::WriteAngleDMS(TextWriter
&writer
, const Angle angle
,
154 // Calculate degrees, minutes and seconds
155 unsigned deg
, min
, sec
;
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",
163 // Attach the buffer string to the output
165 writer
.Write(is_positive
? "N" : "S");
167 writer
.Write(is_positive
? "E" : "W");
171 WaypointWriter::WriteAngleDMM(TextWriter
&writer
, const Angle angle
,
174 // Calculate degrees, minutes and decimal minutes
175 unsigned deg
, min
, mmm
;
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",
183 // Attach the buffer string to the output
185 writer
.Write(is_positive
? "N" : "S");
187 writer
.Write(is_positive
? "E" : "W");
191 WaypointWriter::WriteAltitude(TextWriter
&writer
, fixed altitude
)
193 writer
.Format("%dM", (int)altitude
);
197 WaypointWriter::WriteWinPilotFlags(TextWriter
&writer
, const Waypoint
&wp
)
201 if (wp
.flags
.turn_point
)
207 if (wp
.flags
.start_point
)
209 if (wp
.flags
.finish_point
)
212 // set as turnpoint by default if nothing else
213 if (!wp
.flags
.turn_point
&&
216 !wp
.flags
.start_point
&&
217 !wp
.flags
.finish_point
)
222 WaypointWriter::WriteSeeYouFlags(TextWriter
&writer
, const Waypoint
&wp
)
225 case Waypoint::Type::NORMAL
:
229 case Waypoint::Type::OUTLANDING
:
233 case Waypoint::Type::AIRFIELD
:
236 else // 2 or 5 no rule for this!
240 case Waypoint::Type::MOUNTAIN_PASS
:
244 case Waypoint::Type::MOUNTAIN_TOP
:
248 case Waypoint::Type::OBSTACLE
:
252 case Waypoint::Type::TOWER
:
253 // 11 or 16 no rule for this!
257 case Waypoint::Type::TUNNEL
:
261 case Waypoint::Type::BRIDGE
:
265 case Waypoint::Type::POWERPLANT
:
269 case Waypoint::Type::THERMAL_HOTSPOT
: