bool WaypointReaderFS::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &way_points) { //$FormatGEO //ACONCAGU S 32 39 12.00 W 070 00 42.00 6962 Aconcagua //BERGNEUS N 51 03 07.02 E 007 42 22.02 488 Bergneustadt [A] //GOLDENGA N 37 49 03.00 W 122 28 42.00 227 Golden Gate Bridge //REDSQUAR N 55 45 15.00 E 037 37 12.00 123 Red Square //SYDNEYOP S 33 51 25.02 E 151 12 54.96 5 Sydney Opera //$FormatUTM //Aconcagu 19H 0405124 6386692 6962 Aconcagua //Bergneus 32U 0409312 5656398 488 Bergneustadt [A] //Golden G 10S 0545914 4185695 227 Golden Gate Bridge //Red Squa 37U 0413390 6179582 123 Red Square //Sydney O 56H 0334898 6252272 5 Sydney Opera if (line[0] == '\0') return true; if (linenum == 0 && _tcsstr(line, _T("$FormatUTM")) == line) { is_utm = true; return true; } if (line[0] == _T('$')) return true; // Determine the length of the line size_t len = _tcslen(line); // If less then 27 characters -> something is wrong -> cancel if (len < (is_utm ? 39 : 47)) return false; GeoPoint location; if ((!is_utm && !ParseLocation(line + 10, location)) || (is_utm && !ParseLocationUTM(line + 9, location))) return false; Waypoint new_waypoint(location); new_waypoint.file_num = file_num; new_waypoint.original_id = 0; if (!ParseString(line, new_waypoint.name, 8)) return false; if (!ParseAltitude(line + (is_utm ? 32 : 41), new_waypoint.elevation) && !CheckAltitude(new_waypoint)) return false; // Description (Characters 35-44) if (len > (is_utm ? 38 : 47)) ParseString(line + (is_utm ? 38 : 47), new_waypoint.comment); way_points.Append(new_waypoint); return true; }
bool WaypointReaderOzi::ParseLine(const TCHAR *line, Waypoints &way_points) { if (line[0] == '\0') return true; // Ignore first four header lines if (ignore_lines > 0) { --ignore_lines; return true; } TCHAR ctemp[255]; const TCHAR *params[20]; static constexpr unsigned int max_params = ARRAY_SIZE(params); size_t n_params; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // Get fields n_params = ExtractParameters(line, ctemp, params, max_params, true, _T('"')); // Check if the basic fields are provided if (n_params < 15) return false; GeoPoint location; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[2], location.latitude)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[3], location.longitude)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); long value; new_waypoint.original_id = (ParseNumber(params[0], value) ? value : 0); if (!ParseString(params[1], new_waypoint.name)) return false; if (ParseNumber(params[14], value) && value != -777) new_waypoint.elevation = Units::ToSysUnit(value, Unit::FEET); else if (!factory.FallbackElevation(new_waypoint)) return false; // Description (Characters 35-44) ParseString(params[11], new_waypoint.comment); way_points.Append(std::move(new_waypoint)); return true; }
bool WaypointReaderZander::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &way_points) { // If (end-of-file or comment) if (line[0] == '\0' || line[0] == 0x1a || _tcsstr(line, _T("**")) == line || _tcsstr(line, _T("*")) == line) // -> return without error condition return true; // Determine the length of the line size_t len = _tcslen(line); // If less then 34 characters -> something is wrong -> cancel if (len < 34) return false; GeoPoint location; // Latitude (Characters 13-20 // DDMMSS(N/S)) if (!ParseAngle(line + 13, location.latitude, true)) return false; // Longitude (Characters 21-29 // DDDMMSS(E/W)) if (!ParseAngle(line + 21, location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint(location); new_waypoint.file_num = file_num; new_waypoint.original_id = 0; // Name (Characters 0-12) if (!ParseString(line, new_waypoint.name, 12)) return false; // Altitude (Characters 30-34 // e.g. 1561 (in meters)) /// @todo configurable behaviour if (!ParseAltitude(line + 30, new_waypoint.elevation) && !CheckAltitude(new_waypoint)) return false; // Description (Characters 35-44) if (len > 35) ParseString(line + 35, new_waypoint.comment, 9); // Flags (Characters 45-49) if (len < 46 || !ParseFlags(line + 45, new_waypoint)) if (len < 36 || !ParseFlagsFromDescription(line + 35, new_waypoint)) new_waypoint.flags.turn_point = true; way_points.Append(new_waypoint); return true; }
static unsigned TestCopy(Waypoints& waypoints) { const WaypointPtr wp = waypoints.LookupId(5); if (!wp) return false; unsigned size_old = waypoints.size(); Waypoint wp_copy = *wp; wp_copy.id = waypoints.size() + 1; waypoints.Append(std::move(wp_copy)); waypoints.Optimise(); unsigned size_new = waypoints.size(); return (size_new == size_old + 1); }
static void AddSpiralWaypoints(Waypoints &waypoints, const GeoPoint ¢er = GeoPoint(Angle::Degrees(51.4), Angle::Degrees(7.85)), Angle angle_start = Angle::Degrees(0), Angle angle_step = Angle::Degrees(15), fixed distance_start = fixed(0), fixed distance_step = fixed(1000), fixed distance_max = fixed(150000)) { assert(positive(distance_step)); for (unsigned i = 0;; ++i) { GeoVector vector; vector.distance = distance_start + distance_step * i; if (vector.distance > distance_max) break; vector.bearing = angle_start + angle_step * i; Waypoint waypoint; waypoint.location = vector.EndPoint(center); waypoint.original_id = i; waypoint.elevation = fixed(i * 10 - 500); StaticString<256> buffer; if (i % 7 == 0) { buffer = _T("Airfield"); waypoint.type = Waypoint::Type::AIRFIELD; } else if (i % 3 == 0) { buffer = _T("Field"); waypoint.type = Waypoint::Type::OUTLANDING; } else buffer = _T("Waypoint"); buffer.AppendFormat(_T(" #%d"), i + 1); waypoint.name = buffer; waypoints.Append(std::move(waypoint)); } waypoints.Optimise(); }
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 WaypointReaderCompeGPS::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &waypoints) { /* * G WGS 84 * U 1 * W IT05FC A 46.9121939503ºN 11.9605922700°E 27-MAR-62 00:00:00 566.000000 Ahornach Sand, Ahornach LP, GS und HG * w Waypoint,0,-1.0,16777215,255,0,0,7,,0.0, * W IT05FB A 46.9260440931ºN 11.9676733017°E 27-MAR-62 00:00:00 1425.000000 Ahornach Sand, Ahornach SP, GS und HG * w Waypoint,0,-1.0,16777215,255,0,0,7,,0.0, * * W ShortName 31T 318570 4657569 27-MAR-62 00:00:00 0 some Comments * W ShortName A 41.234234N 7.234424W 27-MAR-62 00:00:00 0 Comments */ // Skip projection and file encoding information if (*line == _T('G') || *line == _T('B')) return true; // Check for format: UTM or LatLon if (*line == _T('U') && _tcsstr(line, _T("U 0")) == line) { is_utm = true; return true; } // Skip non-waypoint lines if (*line != _T('W')) return true; // Skip W indicator and whitespace line++; while (*line == _T(' ')) line++; // Find next space delimiter, skip shortname const TCHAR *name = line; const TCHAR *space = _tcsstr(line, _T(" ")); if (space == NULL) return false; unsigned name_length = space - line; if (name_length == 0) return false; line = space; while (*line == _T(' ')) line++; // Parse location GeoPoint location; if ((!is_utm && !ParseLocation(line, location)) || (is_utm && !ParseLocationUTM(line, location))) return false; // Skip whitespace while (*line == _T(' ')) line++; // Skip unused date field line = _tcsstr(line, _T(" ")); if (line == NULL) return false; line++; // Skip unused time field line = _tcsstr(line, _T(" ")); if (line == NULL) return false; line++; // Create new waypoint instance Waypoint waypoint(location); waypoint.file_num = file_num; waypoint.original_id = 0; waypoint.name.assign(name, name_length); // Parse altitude if (!ParseAltitude(line, waypoint.elevation) && !CheckAltitude(waypoint)) return false; // Skip whitespace while (*line == _T(' ')) line++; // Parse waypoint name waypoint.comment.assign(line); waypoints.Append(std::move(waypoint)); return true; }
bool WaypointReaderWinPilot::ParseLine(const TCHAR *line, Waypoints &waypoints) { TCHAR ctemp[4096]; const TCHAR *params[20]; static constexpr unsigned int max_params = ARRAY_SIZE(params); size_t n_params; // If (end-of-file) if (line[0] == '\0') // -> return without error condition return true; // If comment if (line[0] == _T('*')) { if (first) { first = false; welt2000_format = (_tcsstr(line, _T("WRITTEN BY WELT2000")) != nullptr); } // -> return without error condition return true; } if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; GeoPoint location; // Get fields n_params = ExtractParameters(line, ctemp, params, max_params, true); if (n_params < 6) return false; // Latitude (e.g. 51:15.900N) if (!ParseAngle(params[1], location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[2], location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); // Name (e.g. KAMPLI) if (*params[5] == _T('\0')) return false; new_waypoint.name=params[5]; // Altitude (e.g. 458M) /// @todo configurable behaviour if (!ParseAltitude(params[3], new_waypoint.elevation) && !factory.FallbackElevation(new_waypoint)) return false; if (n_params > 6) { // Description (e.g. 119.750 Airport) new_waypoint.comment=params[6]; if (welt2000_format) ParseRunwayDirection(params[6], new_waypoint.runway); } // Waypoint Flags (e.g. AT) ParseFlags(params[4], new_waypoint); waypoints.Append(std::move(new_waypoint)); return true; }
/** * Initialises waypoints with random and non-random waypoints * for testing * * @param waypoints waypoints class to add waypoints to */ bool setup_waypoints(Waypoints &waypoints, const unsigned n) { Waypoint wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed_zero), Angle::Degrees(fixed_zero))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(wp); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed_zero), Angle::Degrees(fixed_one))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(wp); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed_one), Angle::Degrees(fixed_one))); wp.name = _T("Hello"); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed_half; waypoints.Append(wp); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed(0.8)), Angle::Degrees(fixed(0.5)))); wp.name = _T("Unk"); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(wp); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed_one), Angle::Degrees(fixed_zero))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(wp); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed_zero), Angle::Degrees(fixed(0.23)))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(wp); for (unsigned i=0; i<(unsigned)std::max((int)n-6,0); i++) { int x = rand()%1200-100; int y = rand()%1200-100; double z = rand()% std::max(terrain_height,1); wp = waypoints.Create(GeoPoint(Angle::Degrees(fixed(x/1000.0)), Angle::Degrees(fixed(y/1000.0)))); wp.type = Waypoint::Type::NORMAL; wp.elevation = fixed(z); waypoints.Append(wp); } waypoints.Optimise(); if (verbose) { std::ofstream fin("results/res-wp-in.txt"); for (unsigned i=1; i<=waypoints.size(); i++) { const Waypoint *wp = waypoints.LookupId(i); if (wp != NULL) fin << *wp; } } 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; }
/** * Initialises waypoints with random and non-random waypoints * for testing * * @param waypoints waypoints class to add waypoints to */ bool SetupWaypoints(Waypoints &waypoints, const unsigned n) { Waypoint wp = waypoints.Create(GeoPoint(Angle::Zero(), Angle::Zero())); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(std::move(wp)); wp = waypoints.Create(GeoPoint(Angle::Zero(), Angle::Degrees(1))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(std::move(wp)); wp = waypoints.Create(GeoPoint(Angle::Degrees(1), Angle::Degrees(1))); wp.name = _T("Hello"); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.5); waypoints.Append(std::move(wp)); wp = waypoints.Create(GeoPoint(Angle::Degrees(0.8), Angle::Degrees(0.5))); wp.name = _T("Unk"); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(std::move(wp)); wp = waypoints.Create(GeoPoint(Angle::Degrees(1), Angle::Zero())); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(std::move(wp)); wp = waypoints.Create(GeoPoint(Angle::Zero(), Angle::Degrees(0.23))); wp.type = Waypoint::Type::AIRFIELD; wp.elevation = fixed(0.25); waypoints.Append(std::move(wp)); for (unsigned i=0; i<(unsigned)std::max((int)n-6,0); i++) { int x = rand()%1200-100; int y = rand()%1200-100; double z = rand()% std::max(terrain_height,1); wp = waypoints.Create(GeoPoint(Angle::Degrees(x / 1000.0), Angle::Degrees(y / 1000.0))); wp.type = Waypoint::Type::NORMAL; wp.elevation = fixed(z); waypoints.Append(std::move(wp)); } waypoints.Optimise(); if (verbose) { Directory::Create(Path(_T("output/results"))); std::ofstream fin("output/results/res-wp-in.txt"); for (unsigned i=1; i<=waypoints.size(); i++) { const Waypoint *wpt = waypoints.LookupId(i); if (wpt != NULL) fin << *wpt; } } return true; }