bool WaypointReaderSeeYou::ParseLine(const TCHAR* line, Waypoints &waypoints) { enum { iName = 0, iLatitude = 3, iLongitude = 4, iElevation = 5, iStyle = 6, iRWDir = 7, iRWLen = 8, iFrequency = 9, iDescription = 10, }; if (first) { first = false; /* skip first line if it doesn't begin with a quotation character (usually the field order line) */ if (line[0] != _T('\"')) return true; } // If (end-of-file or comment) if (StringIsEmpty(line) || StringStartsWith(line, _T("*"))) // -> return without error condition return true; TCHAR ctemp[4096]; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // If task marker is reached ignore all following lines if (StringStartsWith(line, _T("-----Related Tasks-----"))) ignore_following = true; if (ignore_following) return true; // Get fields const TCHAR *params[20]; size_t n_params = ExtractParameters(line, ctemp, params, ARRAY_SIZE(params), true, _T('"')); // Check if the basic fields are provided if (iName >= n_params || iLatitude >= n_params || iLongitude >= n_params) return false; GeoPoint location; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[iLatitude], location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[iLongitude], location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); // Name (e.g. "Some Turnpoint") if (*params[iName] == _T('\0')) return false; new_waypoint.name = params[iName]; // Elevation (e.g. 458.0m) /// @todo configurable behaviour if ((iElevation >= n_params || !ParseAltitude(params[iElevation], new_waypoint.elevation)) && !factory.FallbackElevation(new_waypoint)) return false; // Style (e.g. 5) if (iStyle < n_params) ParseStyle(params[iStyle], new_waypoint.type); new_waypoint.flags.turn_point = true; // Frequency & runway direction/length (for airports and landables) // and description (e.g. "Some Description") if (new_waypoint.IsLandable()) { if (iFrequency < n_params) new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]); // Runway length (e.g. 546.0m) double rwlen = -1; if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) && rwlen > 0) new_waypoint.runway.SetLength(uround(rwlen)); if (iRWDir < n_params && *params[iRWDir]) { TCHAR *end; int direction =_tcstol(params[iRWDir], &end, 10); if (end == params[iRWDir] || direction < 0 || direction > 360 || (direction == 0 && rwlen <= 0)) direction = -1; else if (direction == 360) direction = 0; if (direction >= 0) new_waypoint.runway.SetDirectionDegrees(direction); } } if (iDescription < n_params) { /* * This convention was introduced by the OpenAIP * project (http://www.openaip.net/), since no waypoint type * exists for thermal hotspots. */ if (StringStartsWith(params[iDescription], _T("Hotspot"))) new_waypoint.type = Waypoint::Type::THERMAL_HOTSPOT; new_waypoint.comment = params[iDescription]; } waypoints.Append(std::move(new_waypoint)); return true; }
bool WaypointReaderSeeYou::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &waypoints) { enum { iName = 0, iLatitude = 3, iLongitude = 4, iElevation = 5, iStyle = 6, iRWDir = 7, iRWLen = 8, iFrequency = 9, iDescription = 10, }; if (linenum == 0) ignore_following = false; // If (end-of-file or comment) if (StringIsEmpty(line) || StringStartsWith(line, _T("**")) || StringStartsWith(line, _T("*"))) // -> return without error condition return true; TCHAR ctemp[4096]; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // Skip first line if it doesn't begin with a quotation character // (usually the field order line) if (linenum == 0 && line[0] != _T('\"')) return true; // If task marker is reached ignore all following lines if (_tcsstr(line, _T("-----Related Tasks-----")) == line) ignore_following = true; if (ignore_following) return true; // Get fields const TCHAR *params[20]; size_t n_params = ExtractParameters(line, ctemp, params, ARRAY_SIZE(params), true, _T('"')); // Check if the basic fields are provided if (iName >= n_params || iLatitude >= n_params || iLongitude >= n_params) return false; Waypoint new_waypoint; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[iLatitude], new_waypoint.location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[iLongitude], new_waypoint.location.longitude, false)) return false; new_waypoint.location.Normalize(); // ensure longitude is within -180:180 new_waypoint.file_num = file_num; new_waypoint.original_id = 0; // Name (e.g. "Some Turnpoint") if (*params[iName] == _T('\0')) return false; new_waypoint.name = params[iName]; // Elevation (e.g. 458.0m) /// @todo configurable behaviour if ((iElevation >= n_params || !ParseAltitude(params[iElevation], new_waypoint.elevation)) && !CheckAltitude(new_waypoint)) return false; // Style (e.g. 5) if (iStyle < n_params) ParseStyle(params[iStyle], new_waypoint.type); new_waypoint.flags.turn_point = true; // Frequency & runway direction/length (for airports and landables) // and description (e.g. "Some Description") if (new_waypoint.IsLandable()) { if (iFrequency < n_params) new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]); // Runway length (e.g. 546.0m) fixed rwlen = fixed_minus_one; if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) && positive(rwlen)) new_waypoint.runway.SetLength(uround(rwlen)); if (iRWDir < n_params && *params[iRWDir]) { TCHAR *end; int direction =_tcstol(params[iRWDir], &end, 10); if (end == params[iRWDir] || direction < 0 || direction > 360 || (direction == 0 && !positive(rwlen))) direction = -1; else if (direction == 360) direction = 0; if (direction >= 0) new_waypoint.runway.SetDirectionDegrees(direction); } } if (iDescription < n_params) new_waypoint.comment = params[iDescription]; waypoints.Append(new_waypoint); return true; }