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 "WaypointReaderCompeGPS.hpp"
25 #include "Waypoint/Waypoints.hpp"
26 #include "IO/LineReader.hpp"
27 #include "Util/Macros.hpp"
28 #include "Geo/UTM.hpp"
33 ParseAngle(const TCHAR
*&src
, Angle
&angle
)
39 // Parse numerical value
40 double value
= _tcstod(src
, &endptr
);
45 angle
= Angle::Degrees(value
);
47 // Skip until next whitespace and look for NSEW signs
49 while (*src
!= _T(' ') && *src
!= _T('\0')) {
51 if (*src
== _T('N') || *src
== _T('n') ||
52 *src
== _T('E') || *src
== _T('e')) {
54 } else if (*src
== _T('S') || *src
== _T('s') ||
55 *src
== _T('W') || *src
== _T('w')) {
68 ParseLocation(const TCHAR
*&src
, GeoPoint
&p
)
70 // A 41.234234N 7.234424W
72 // Ignore but require 'A' placeholder
79 while (*src
== _T(' '))
83 if (!ParseAngle(src
, lat
) || !ParseAngle(src
, lon
))
89 // ensure longitude is within -180:180
96 ParseLocationUTM(const TCHAR
*&src
, GeoPoint
&p
)
103 long zone_number
= _tcstol(src
, &endptr
, 10);
108 char zone_letter
= src
[0];
111 long easting
= _tcstol(src
, &endptr
, 10);
112 if (endptr
== src
|| *endptr
!= _T(' '))
116 long northing
= _tcstol(src
, &endptr
, 10);
117 if (endptr
== src
|| *endptr
!= _T(' '))
120 UTM
u(zone_number
, zone_letter
, fixed(easting
), fixed(northing
));
123 // ensure longitude is within -180:180
132 ParseAltitude(const TCHAR
*&src
, fixed
&dest
)
135 double value
= _tcstod(src
, &endptr
);
145 WaypointReaderCompeGPS::ParseLine(const TCHAR
* line
, const unsigned linenum
,
146 Waypoints
&waypoints
)
151 * W IT05FC A 46.9121939503ºN 11.9605922700°E 27-MAR-62 00:00:00 566.000000 Ahornach Sand, Ahornach LP, GS und HG
152 * w Waypoint,0,-1.0,16777215,255,0,0,7,,0.0,
153 * W IT05FB A 46.9260440931ºN 11.9676733017°E 27-MAR-62 00:00:00 1425.000000 Ahornach Sand, Ahornach SP, GS und HG
154 * w Waypoint,0,-1.0,16777215,255,0,0,7,,0.0,
156 * W ShortName 31T 318570 4657569 27-MAR-62 00:00:00 0 some Comments
157 * W ShortName A 41.234234N 7.234424W 27-MAR-62 00:00:00 0 Comments
160 // Skip projection and file encoding information
161 if (*line
== _T('G') || *line
== _T('B'))
164 // Check for format: UTM or LatLon
165 if (*line
== _T('U') && _tcsstr(line
, _T("U 0")) == line
) {
170 // Skip non-waypoint lines
171 if (*line
!= _T('W'))
174 // Skip W indicator and whitespace
176 while (*line
== _T(' '))
179 // Find next space delimiter, skip shortname
180 const TCHAR
*name
= line
;
181 const TCHAR
*space
= _tcsstr(line
, _T(" "));
185 unsigned name_length
= space
- line
;
186 if (name_length
== 0)
190 while (*line
== _T(' '))
195 if ((!is_utm
&& !ParseLocation(line
, location
)) ||
196 (is_utm
&& !ParseLocationUTM(line
, location
)))
200 while (*line
== _T(' '))
203 // Skip unused date field
204 line
= _tcsstr(line
, _T(" "));
210 // Skip unused time field
211 line
= _tcsstr(line
, _T(" "));
217 // Create new waypoint instance
218 Waypoint
waypoint(location
);
219 waypoint
.file_num
= file_num
;
220 waypoint
.original_id
= 0;
221 waypoint
.name
.assign(name
, name_length
);
224 if (!ParseAltitude(line
, waypoint
.elevation
) &&
225 !CheckAltitude(waypoint
))
229 while (*line
== _T(' '))
232 // Parse waypoint name
233 waypoint
.comment
.assign(line
);
235 waypoints
.Append(std::move(waypoint
));
240 WaypointReaderCompeGPS::VerifyFormat(TLineReader
&reader
)
242 const TCHAR
*line
= reader
.ReadLine();
246 // Ignore optional line with encoding information
247 if (StringStartsWith(line
, _T("B ")))
248 if ((line
= reader
.ReadLine()) == NULL
)
251 return StringStartsWith(line
, _T("G WGS 84"));