static bool ParseArcTNP(const TCHAR *buffer, TempAirspaceType &temp_area) { if (temp_area.points.empty()) return false; // (ANTI-)CLOCKWISE RADIUS=34.95 CENTRE=N523333 E0131603 TO=N522052 E0122236 GeoPoint from = temp_area.points.back(); const TCHAR* parameter; if ((parameter = _tcsstr(buffer, _T(" "))) == nullptr) return false; if ((parameter = StringAfterPrefixCI(parameter, _T(" CENTRE="))) == nullptr) return false; if (!ParseCoordsTNP(parameter, temp_area.center)) return false; if ((parameter = _tcsstr(parameter, _T(" "))) == nullptr) return false; parameter++; if ((parameter = _tcsstr(parameter, _T(" "))) == nullptr) return false; if ((parameter = StringAfterPrefixCI(parameter, _T(" TO="))) == nullptr) return false; GeoPoint to; if (!ParseCoordsTNP(parameter, to)) return false; temp_area.AppendArc(from, to); return true; }
static void ParseArcBearings(const TCHAR *buffer, TempAirspaceType &temp_area) { // Determine radius and start/end bearing TCHAR *endptr; temp_area.radius = Units::ToSysUnit(fixed(_tcstod(&buffer[2], &endptr)), Unit::NAUTICAL_MILES); Angle start_bearing = Angle::Degrees(_tcstod(&endptr[1], &endptr)).AsBearing(); Angle end_bearing = Angle::Degrees(_tcstod(&endptr[1], &endptr)).AsBearing(); temp_area.AppendArc(start_bearing, end_bearing); }
static bool ParseArcPoints(const TCHAR *buffer, TempAirspaceType &temp_area) { // Read start coordinates GeoPoint start; if (!ReadCoords(&buffer[3], start)) return false; // Skip comma character const TCHAR* comma = _tcschr(buffer, ','); if (!comma) return false; // Read end coordinates GeoPoint end; if (!ReadCoords(&comma[1], end)) return false; temp_area.AppendArc(start, end); return true; }
static bool ParseLineTNP(Airspaces &airspace_database, TCHAR *line, TempAirspaceType &temp_area, bool &ignore) { // Strip comments TCHAR *comment = _tcschr(line, _T('*')); if (comment != nullptr) *comment = _T('\0'); const TCHAR* parameter; if ((parameter = StringAfterPrefixCI(line, _T("INCLUDE="))) != nullptr) { if (StringStartsWithIgnoreCase(parameter, _T("YES"))) ignore = false; else if (StringStartsWithIgnoreCase(parameter, _T("NO"))) ignore = true; return true; } if (ignore) return true; if ((parameter = StringAfterPrefixCI(line, _T("POINT="))) != nullptr) { GeoPoint temp_point; if (!ParseCoordsTNP(parameter, temp_point)) return false; temp_area.points.push_back(temp_point); } else if ((parameter = StringAfterPrefixCI(line, _T("CIRCLE "))) != nullptr) { if (!ParseCircleTNP(parameter, temp_area)) return false; temp_area.AddCircle(airspace_database); temp_area.ResetTNP(); } else if ((parameter = StringAfterPrefixCI(line, _T("CLOCKWISE "))) != nullptr) { temp_area.rotation = 1; if (!ParseArcTNP(parameter, temp_area)) return false; } else if ((parameter = StringAfterPrefixCI(line, _T("ANTI-CLOCKWISE "))) != nullptr) { temp_area.rotation = -1; if (!ParseArcTNP(parameter, temp_area)) return false; } else if ((parameter = StringAfterPrefixCI(line, _T("TITLE="))) != nullptr) { temp_area.AddPolygon(airspace_database); temp_area.ResetTNP(); temp_area.name = parameter; } else if ((parameter = StringAfterPrefixCI(line, _T("TYPE="))) != nullptr) { temp_area.AddPolygon(airspace_database); temp_area.ResetTNP(); temp_area.type = ParseTypeTNP(parameter); } else if ((parameter = StringAfterPrefixCI(line, _T("CLASS="))) != nullptr) { temp_area.type = ParseClassTNP(parameter); } else if ((parameter = StringAfterPrefixCI(line, _T("TOPS="))) != nullptr) { ReadAltitude(parameter, temp_area.top); } else if ((parameter = StringAfterPrefixCI(line, _T("BASE="))) != nullptr) { ReadAltitude(parameter, temp_area.base); } else if ((parameter = StringAfterPrefixCI(line, _T("RADIO="))) != nullptr) { temp_area.radio = parameter; } else if ((parameter = StringAfterPrefixCI(line, _T("ACTIVE="))) != nullptr) { if (StringIsEqualIgnoreCase(parameter, _T("WEEKEND"))) temp_area.days_of_operation.SetWeekend(); else if (StringIsEqualIgnoreCase(parameter, _T("WEEKDAY"))) temp_area.days_of_operation.SetWeekdays(); else if (StringIsEqualIgnoreCase(parameter, _T("EVERYDAY"))) temp_area.days_of_operation.SetAll(); } return true; }
static bool ParseLine(Airspaces &airspace_database, TCHAR *line, TempAirspaceType &temp_area) { const TCHAR *value; // Strip comments TCHAR *comment = _tcschr(line, _T('*')); if (comment != nullptr) *comment = _T('\0'); // Only return expected lines switch (line[0]) { case _T('D'): case _T('d'): switch (line[1]) { case _T('P'): case _T('p'): value = ValueAfterSpace(line + 2); if (value == nullptr) break; { GeoPoint temp_point; if (!ReadCoords(value, temp_point)) return false; temp_area.points.push_back(temp_point); break; } case _T('C'): case _T('c'): temp_area.radius = Units::ToSysUnit(fixed(ParseDouble(&line[2])), Unit::NAUTICAL_MILES); temp_area.AddCircle(airspace_database); temp_area.Reset(); break; case _T('A'): case _T('a'): ParseArcBearings(line, temp_area); break; case _T('B'): case _T('b'): return ParseArcPoints(line, temp_area); default: return true; } break; case _T('V'): case _T('v'): // Need to set these while in count mode, or DB/DA will crash if ((value = StringAfterPrefixCI(SkipSpaces(line + 1), _T("X="))) != nullptr) { if (!ReadCoords(value, temp_area.center)) return false; } else if (StringAfterPrefixCI(SkipSpaces(line + 1), _T("D=-"))) { temp_area.rotation = -1; } else if (StringAfterPrefixCI(SkipSpaces(line + 1), _T("D=+"))) { temp_area.rotation = +1; } break; case _T('A'): case _T('a'): switch (line[1]) { case _T('C'): case _T('c'): value = ValueAfterSpace(line + 2); if (value == nullptr) break; temp_area.AddPolygon(airspace_database); temp_area.Reset(); temp_area.type = ParseType(value); break; case _T('N'): case _T('n'): value = ValueAfterSpace(line + 2); if (value != nullptr) temp_area.name = value; break; case _T('L'): case _T('l'): value = ValueAfterSpace(line + 2); if (value != nullptr) ReadAltitude(value, temp_area.base); break; case _T('H'): case _T('h'): value = ValueAfterSpace(line + 2); if (value != nullptr) ReadAltitude(value, temp_area.top); break; case _T('R'): case _T('r'): value = ValueAfterSpace(line + 2); if (value != nullptr) temp_area.radio = value; break; default: return true; } break; } return true; }
static bool ParseLineTNP(Airspaces &airspace_database, const TCHAR *line, TempAirspaceType &temp_area, bool &ignore) { const TCHAR* parameter; if ((parameter = string_after_prefix_ci(line, _T("INCLUDE="))) != NULL) { if (_tcsicmp(parameter, _T("YES")) == 0) ignore = false; else if (_tcsicmp(parameter, _T("NO")) == 0) ignore = true; return true; } if (ignore) return true; if ((parameter = string_after_prefix_ci(line, _T("TITLE="))) != NULL) { temp_area.Name = parameter; } else if ((parameter = string_after_prefix_ci(line, _T("RADIO="))) != NULL) { temp_area.Radio = parameter; } else if ((parameter = string_after_prefix_ci(line, _T("ACTIVE="))) != NULL) { if (_tcsicmp(parameter, _T("WEEKEND")) == 0) temp_area.days_of_operation.set_weekend(); else if (_tcsicmp(parameter, _T("WEEKDAY")) == 0) temp_area.days_of_operation.set_weekdays(); else if (_tcsicmp(parameter, _T("EVERYDAY")) == 0) temp_area.days_of_operation.set_all(); } else if ((parameter = string_after_prefix_ci(line, _T("TYPE="))) != NULL) { if (!temp_area.Waiting) temp_area.AddPolygon(airspace_database); temp_area.reset(); temp_area.Type = ParseTypeTNP(parameter); temp_area.Waiting = false; } else if ((parameter = string_after_prefix_ci(line, _T("CLASS="))) != NULL) { if (temp_area.Type == OTHER) temp_area.Type = ParseClassTNP(parameter); } else if ((parameter = string_after_prefix_ci(line, _T("TOPS="))) != NULL) { ReadAltitude(parameter, &temp_area.Top); } else if ((parameter = string_after_prefix_ci(line, _T("BASE="))) != NULL) { ReadAltitude(parameter, &temp_area.Base); } else if ((parameter = string_after_prefix_ci(line, _T("POINT="))) != NULL) { GeoPoint TempPoint; if (!ParseCoordsTNP(parameter, TempPoint)) return false; temp_area.points.push_back(TempPoint); } else if ((parameter = string_after_prefix_ci(line, _T("CIRCLE "))) != NULL) { if (!ParseCircleTNP(parameter, temp_area)) return false; temp_area.AddCircle(airspace_database); } else if ((parameter = string_after_prefix_ci(line, _T("CLOCKWISE "))) != NULL) { temp_area.Rotation = 1; if (!ParseArcTNP(parameter, temp_area)) return false; } else if ((parameter = string_after_prefix_ci(line, _T("ANTI-CLOCKWISE "))) != NULL) { temp_area.Rotation = -1; if (!ParseArcTNP(parameter, temp_area)) return false; } return true; }
static bool ParseLine(Airspaces &airspace_database, const TCHAR *line, TempAirspaceType &temp_area) { const TCHAR *value; // Only return expected lines switch (line[0]) { case _T('A'): case _T('a'): switch (line[1]) { case _T('C'): case _T('c'): value = value_after_space(line + 2); if (value == NULL) break; if (!temp_area.Waiting) temp_area.AddPolygon(airspace_database); temp_area.reset(); temp_area.Type = ParseType(value); temp_area.Waiting = false; break; case _T('N'): case _T('n'): value = value_after_space(line + 2); if (value != NULL) temp_area.Name = value; break; case _T('R'): case _T('r'): value = value_after_space(line + 2); if (value != NULL) temp_area.Radio = value; break; case _T('L'): case _T('l'): value = value_after_space(line + 2); if (value != NULL) ReadAltitude(value, &temp_area.Base); break; case _T('H'): case _T('h'): value = value_after_space(line + 2); if (value != NULL) ReadAltitude(value, &temp_area.Top); break; default: return true; } break; case _T('D'): case _T('d'): switch (line[1]) { case _T('A'): case _T('a'): CalculateSector(line, temp_area); break; case _T('B'): case _T('b'): CalculateArc(line, temp_area); break; case _T('C'): case _T('c'): temp_area.Radius = Units::ToSysUnit(fixed(_tcstod(&line[2], NULL)), unNauticalMiles); temp_area.AddCircle(airspace_database); temp_area.reset(); break; case _T('P'): case _T('p'): value = value_after_space(line + 2); if (value == NULL) break; { GeoPoint TempPoint; if (!ReadCoords(value, TempPoint)) return false; temp_area.points.push_back(TempPoint); break; } default: return true; } break; case _T('V'): case _T('v'): // Need to set these while in count mode, or DB/DA will crash if (string_after_prefix_ci(&line[2], _T("X="))) { if (!ReadCoords(&line[4],temp_area.Center)) return false; } else if (string_after_prefix_ci(&line[2], _T("D=-"))) { temp_area.Rotation = -1; } else if (string_after_prefix_ci(&line[2], _T("D=+"))) { temp_area.Rotation = +1; } break; } return true; }