static bool ParseLocation(const TCHAR *&src, GeoPoint &p) { // A 41.234234N 7.234424W // Ignore but require 'A' placeholder if (*src != _T('A')) return false; src++; // Skip whitespace while (*src == _T(' ')) src++; Angle lat, lon; if (!ParseAngle(src, lat) || !ParseAngle(src, lon)) return false; p.longitude = lon; p.latitude = lat; // ensure longitude is within -180:180 p.Normalize(); return true; }
static bool ParseLocationUTM(const TCHAR *&src, GeoPoint &p) { // 31T 318570 4657569 TCHAR *endptr; // Parse zone number long zone_number = _tcstol(src, &endptr, 10); if (endptr == src) return false; src = endptr; char zone_letter = src[0]; src++; long easting = _tcstol(src, &endptr, 10); if (endptr == src || *endptr != _T(' ')) return false; src = endptr; long northing = _tcstol(src, &endptr, 10); if (endptr == src || *endptr != _T(' ')) return false; UTM u(zone_number, zone_letter, fixed(easting), fixed(northing)); p = u.ToGeoPoint(); // ensure longitude is within -180:180 p.Normalize(); src = endptr; return true; }
/** * Subtracts a delta from a point * * @param delta Delta to subtract * * @return Modified point */ gcc_pure GeoPoint operator- (const GeoPoint &delta) const { GeoPoint res = *this; res.longitude -= delta.longitude; res.latitude -= delta.latitude; return res.Normalize(); };
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 bool ParseLocation(const TCHAR *src, GeoPoint &p) { Angle lon, lat; if (!ParseAngle(src, lat)) return false; if (!ParseAngle(src + 17, lon)) return false; p.longitude = lon; p.latitude = lat; // ensure longitude is within -180:180 p.Normalize(); return true; }
static bool ParseCoordsTNP(const TCHAR *buffer, GeoPoint &point) { // Format: N542500 E0105000 bool negative = false; long deg = 0, min = 0, sec = 0; TCHAR *ptr; if (buffer[0] == _T('S') || buffer[0] == _T('s')) negative = true; sec = _tcstol(&buffer[1], &ptr, 10); deg = labs(sec / 10000); min = labs((sec - deg * 10000) / 100); sec = sec - min * 100 - deg * 10000; point.latitude = Angle::DMS(deg, min, sec); if (negative) point.latitude.Flip(); negative = false; if (ptr[0] == _T(' ')) ptr++; if (ptr[0] == _T('W') || ptr[0] == _T('w')) negative = true; sec = _tcstol(&ptr[1], &ptr, 10); deg = labs(sec / 10000); min = labs((sec - deg * 10000) / 100); sec = sec - min * 100 - deg * 10000; point.longitude = Angle::DMS(deg, min, sec); if (negative) point.longitude.Flip(); point.Normalize(); // ensure longitude is within -180:180 return true; }
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 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; }
/** * Set the GeoPoint that relates to the ScreenOrigin * @param g The new GeoPoint */ void SetGeoLocation(GeoPoint g) { geo_location = g; geo_location.Normalize(); }
static bool ReadCoords(const TCHAR *buffer, GeoPoint &point) { // Format: 53:20:41 N 010:24:41 E // Alternative Format: 53:20.68 N 010:24.68 E TCHAR *endptr; // ToDo, add more error checking and making it more tolerant/robust double deg = ParseDouble(buffer, &endptr); if ((buffer == endptr) || (*endptr == '\0')) return false; if (*endptr == ':') { endptr++; double min = ParseDouble(endptr, &endptr); if (*endptr == '\0') return false; deg += min / 60; if (*endptr == ':') { endptr++; double sec = ParseDouble(endptr, &endptr); if (*endptr == '\0') return false; deg += sec / 3600; } } point.latitude = Angle::Degrees(deg); if (*endptr == ' ') endptr++; if (*endptr == '\0') return false; if ((*endptr == 'S') || (*endptr == 's')) point.latitude.Flip(); endptr++; if (*endptr == '\0') return false; deg = ParseDouble(endptr, &endptr); if ((buffer == endptr) || (*endptr == '\0')) return false; if (*endptr == ':') { endptr++; double min = ParseDouble(endptr, &endptr); if (*endptr == '\0') return false; deg += min / 60; if (*endptr == ':') { endptr++; double sec = ParseDouble(endptr, &endptr); if (*endptr == '\0') return false; deg += sec / 3600; } } point.longitude = Angle::Degrees(deg); if (*endptr == ' ') endptr++; if (*endptr == '\0') return false; if ((*endptr == 'W') || (*endptr == 'w')) point.longitude.Flip(); point.Normalize(); // ensure longitude is within -180:180 return true; }
bool WaypointReaderSeeYou::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &waypoints) { TCHAR ctemp[4096]; const TCHAR *params[20]; static const unsigned int max_params = ARRAY_SIZE(params); size_t n_params; const unsigned iName = 0; const unsigned iLatitude = 3, iLongitude = 4, iElevation = 5; const unsigned iStyle = 6, iRWDir = 7, iRWLen = 8; const unsigned iFrequency = 9, iDescription = 10; static bool ignore_following; if (linenum == 0) ignore_following = false; // 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; 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 n_params = ExtractParameters(line, ctemp, params, max_params, true, _T('"')); // Check if the basic fields are provided if (iName >= n_params) return false; if (iLatitude >= n_params) return false; if (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(location); 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) /// @todo include peaks with peak symbols etc. if (iStyle < n_params) ParseStyle(params[iStyle], new_waypoint); // 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; }