int main(int argc, char **argv) { Args args(argc, argv, "PATH"); const char *path = args.ExpectNext(); args.ExpectEnd(); FileLineReader reader(path, ConvertLineReader::AUTO); if (reader.error()) { fprintf(stderr, "Failed to open input file\n"); return 1; } Airspaces airspaces; AirspaceParser parser(airspaces); NullOperationEnvironment operation; if (!parser.Parse(reader, operation)) { fprintf(stderr, "Failed to parse input file\n"); return 1; } airspaces.Optimise(); printf("OK\n"); return 0; }
void scan_airspaces(const AircraftState state, const Airspaces& airspaces, const AirspaceAircraftPerformance& perf, bool do_report, const GeoPoint &target) { const fixed range(20000.0); Directory::Create(Path(_T("output/results"))); { AirspaceVisitorPrint pvisitor("output/results/res-bb-range.txt", do_report); for (const auto &i : airspaces.QueryWithinRange(state.location, range)) { const AbstractAirspace &airspace = i.GetAirspace(); pvisitor.Visit(airspace); } } { AirspaceVisitorClosest pvisitor("output/results/res-bb-closest.txt", airspaces.GetProjection(), state, perf); for (const auto &i : airspaces.QueryWithinRange(state.location, range)) { const AbstractAirspace &airspace = i.GetAirspace(); pvisitor.Visit(airspace); } } { AirspaceVisitorPrint pvi("output/results/res-bb-inside.txt", do_report); for (const auto &a : airspaces.QueryInside(state)) pvi.Visit(a.GetAirspace()); } { AirspaceIntersectionVisitorPrint ivisitor("output/results/res-bb-intersects.txt", "output/results/res-bb-intersected.txt", "output/results/res-bb-intercepts.txt", do_report, state, perf); airspaces.VisitIntersecting(state.location, target, ivisitor); } { const auto *as = FindSoonestAirspace(airspaces, state, perf, AirspacePredicateTrue()); if (do_report) { std::ofstream fout("output/results/res-bb-sortedsoonest.txt"); if (as) { fout << *as << "\n"; } else { fout << "# no soonest found\n"; } } } }
bool test_airspace_extra(Airspaces &airspaces) { // try adding a null polygon AbstractAirspace* as; std::vector<GeoPoint> pts; as = new AirspacePolygon(pts); airspaces.Add(as); // try clearing now (we haven't called optimise()) airspaces.Clear(); return true; }
void scan_airspaces(const AircraftState state, const Airspaces& airspaces, const AirspaceAircraftPerformance& perf, bool do_report, const GeoPoint &target) { const fixed range(20000.0); Directory::Create(Path(_T("output/results"))); { AirspaceVisitorPrint pvisitor("output/results/res-bb-range.txt", do_report); airspaces.VisitWithinRange(state.location, range, pvisitor); } { AirspaceVisitorClosest pvisitor("output/results/res-bb-closest.txt", airspaces.GetProjection(), state, perf); airspaces.VisitWithinRange(state.location, range, pvisitor); } { const std::vector<Airspace> vi = airspaces.FindInside(state); AirspaceVisitorPrint pvi("output/results/res-bb-inside.txt", do_report); std::for_each(vi.begin(), vi.end(), CallVisitor<AirspaceVisitor>(pvi)); } { AirspaceIntersectionVisitorPrint ivisitor("output/results/res-bb-intersects.txt", "output/results/res-bb-intersected.txt", "output/results/res-bb-intercepts.txt", do_report, state, perf); airspaces.VisitIntersecting(state.location, target, ivisitor); } { const auto *as = FindSoonestAirspace(airspaces, state, perf, AirspacePredicateTrue()); if (do_report) { std::ofstream fout("output/results/res-bb-sortedsoonest.txt"); if (as) { fout << *as << "\n"; } else { fout << "# no soonest found\n"; } } } }
void setup_airspaces(Airspaces& airspaces, const GeoPoint& center, const unsigned n) { std::ofstream *fin = NULL; if (verbose) { Directory::Create(Path(_T("output/results"))); fin = new std::ofstream("output/results/res-bb-in.txt"); } for (unsigned i=0; i<n; i++) { AbstractAirspace* as; if (rand()%4!=0) { GeoPoint c; c.longitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.longitude; c.latitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.latitude; fixed radius(10000.0*(0.2+(rand()%12)/12.0)); as = new AirspaceCircle(c,radius); } else { // just for testing, create a random polygon from a convex hull around // random points const unsigned num = rand()%10+5; GeoPoint c; c.longitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.longitude; c.latitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.latitude; std::vector<GeoPoint> pts; for (unsigned j=0; j<num; j++) { GeoPoint p=c; p.longitude += Angle::Degrees(fixed((rand()%200)/1000.0)); p.latitude += Angle::Degrees(fixed((rand()%200)/1000.0)); pts.push_back(p); } as = new AirspacePolygon(pts,true); } airspace_random_properties(*as); airspaces.Add(as); if (fin) *fin << *as; } delete fin; // try inserting nothing airspaces.Add(NULL); airspaces.Optimise(); }
bool Airspaces::SynchroniseInRange(const Airspaces &master, const GeoPoint &location, const double range, const AirspacePredicate &condition) { qnh = master.qnh; activity_mask = master.activity_mask; task_projection = master.task_projection; AirspaceVector contents_master; for (const auto &i : master.QueryWithinRange(location, range)) if (condition(i.GetAirspace())) contents_master.push_back(i); if (CompareAirspaceVectors(contents_master, AsVector())) return false; for (auto &i : QueryAll()) i.ClearClearance(); airspace_tree.clear(); for (const auto &i : contents_master) airspace_tree.insert(i); ++serial; return true; }
void AddPolygon(Airspaces &airspace_database) { AbstractAirspace *as = new AirspacePolygon(points); as->set_properties(Name, Type, Base, Top); airspace_database.insert(as); }
void MapItemListBuilder::AddVisibleAirspace( const Airspaces &airspaces, const ProtectedAirspaceWarningManager *warning_manager, const AirspaceComputerSettings &computer_settings, const AirspaceRendererSettings &renderer_settings, const MoreData &basic, const DerivedInfo &calculated) { AirspaceWarningList warnings; if (warning_manager != nullptr) warnings.Fill(*warning_manager); const AircraftState aircraft = ToAircraftState(basic, calculated); AirspaceAtPointPredicate predicate(computer_settings, renderer_settings, aircraft, warnings, location); for (const auto &i : airspaces.QueryWithinRange(location, 100)) { if (list.full()) break; const AbstractAirspace &airspace = i.GetAirspace(); if (predicate(airspace)) list.append(new AirspaceMapItem(airspace)); } }
void AddCircle(Airspaces &airspace_database) { AbstractAirspace *as = new AirspaceCircle(Center, Radius); as->set_properties(Name, Type, Base, Top); airspace_database.insert(as); }
bool Airspaces::SynchroniseInRange(const Airspaces& master, const GeoPoint &location, const fixed range, const AirspacePredicate &condition) { bool changed = false; const AirspaceVector contents_master = master.ScanRange(location, range, condition); AirspaceVector contents_self; contents_self.reserve(std::max(airspace_tree.size(), contents_master.size())); task_projection = master.task_projection; // ensure these are up to date for (const auto &v : airspace_tree) contents_self.push_back(v); // find items to add for (const auto &v : contents_master) { const AbstractAirspace* other = v.GetAirspace(); bool found = false; for (auto s = contents_self.begin(); s != contents_self.end(); ++s) { const AbstractAirspace* self = s->GetAirspace(); if (self == other) { found = true; contents_self.erase(s); break; } } if (!found && other->IsActive()) { Add(v.GetAirspace()); changed = true; } } // anything left in the self list are items that were not in the query, // so delete them --- including the clearances! for (auto v = contents_self.begin(); v != contents_self.end();) { bool found = false; for (auto t = airspace_tree.begin(); t != airspace_tree.end(); ) { if (t->GetAirspace() == v->GetAirspace()) { AirspaceTree::const_iterator new_t = t; ++new_t; airspace_tree.erase_exact(*t); t = new_t; found = true; } else { ++t; } } assert(found); v->ClearClearance(); v = contents_self.erase(v); changed = true; } if (changed) Optimise(); return changed; }
void AddPolygon(Airspaces &airspace_database) { AbstractAirspace *as = new AirspacePolygon(points); as->set_properties(Name, Type, Base, Top); as->set_radio(Radio); as->set_days(days_of_operation); airspace_database.insert(as); }
void AddPolygon(Airspaces &airspace_database) { AbstractAirspace *as = new AirspacePolygon(points); as->SetProperties(name, type, base, top); as->SetRadio(radio); as->SetDays(days_of_operation); airspace_database.Add(as); }
void AddCircle(Airspaces &airspace_database) { AbstractAirspace *as = new AirspaceCircle(center, radius); as->SetProperties(std::move(name), type, base, top); as->SetRadio(radio); as->SetDays(days_of_operation); airspace_database.Add(as); }
AirspaceSelectInfoVector FilterAirspaces(const Airspaces &airspaces, const GeoPoint &location, const AirspaceFilterData &filter) { AirspaceFilterVisitor visitor(location, airspaces.GetProjection(), filter); if (!negative(filter.distance)) airspaces.VisitWithinRange(location, filter.distance, visitor); else for (const auto &i : airspaces) visitor.Visit(i.GetAirspace()); if (filter.direction.IsNegative() && negative(filter.distance)) SortByName(visitor.result); else SortByDistance(visitor.result, location, airspaces.GetProjection()); return visitor.result; }
void AirspaceNearestSort::populate_queue(const Airspaces &airspaces, const fixed range) { AirspacesInterface::AirspaceVector vectors = airspaces.ScanRange(m_location, range, m_condition); for (const Airspace &airspace : vectors) { const AbstractAirspace &as = airspace.GetAirspace(); const AirspaceInterceptSolution ais = solve_intercept(as, airspaces.GetProjection()); const fixed value = metric(ais); if (!negative(value)) m_q.push(std::make_pair(value, std::make_pair(ais, &as))); } }
void ReadAirspace(Airspaces &airspaces, RasterTerrain *terrain, const AtmosphericPressure &press, OperationEnvironment &operation) { LogStartUp(_T("ReadAirspace")); operation.SetText(_("Loading Airspace File...")); bool airspace_ok = false; // Read the airspace filenames from the registry TLineReader *reader = OpenConfiguredTextFile(szProfileAirspaceFile, _T("airspace.txt")); if (reader != NULL) { if (!ReadAirspace(airspaces, *reader, operation)) LogStartUp(_T("No airspace file 1")); else airspace_ok = true; delete reader; } reader = OpenConfiguredTextFile(szProfileAdditionalAirspaceFile); if (reader != NULL) { if (!ReadAirspace(airspaces, *reader, operation)) LogStartUp(_T("No airspace file 2")); else airspace_ok = true; delete reader; } if (airspace_ok) { airspaces.optimise(); airspaces.set_flight_levels(press); if (terrain != NULL) airspaces.set_ground_levels(*terrain); } else // there was a problem airspaces.clear(); }
void setup_airspaces(Airspaces& airspaces, const unsigned n) { #ifdef DO_PRINT std::ofstream fin("results/res-bb-in.txt"); #endif for (unsigned i=0; i<n; i++) { AbstractAirspace* as; if (rand()%4!=0) { GeoPoint c; c.Longitude = Angle::degrees(fixed((rand()%1200-600)/1000.0+0.5)); c.Latitude = Angle::degrees(fixed((rand()%1200-600)/1000.0+0.5)); fixed radius(10000.0*(0.2+(rand()%12)/12.0)); as = new AirspaceCircle(c,radius); } else { // just for testing, create a random polygon from a convex hull around // random points const unsigned num = rand()%10+5; GeoPoint c; c.Longitude = Angle::degrees(fixed((rand()%1200-600)/1000.0+0.5)); c.Latitude = Angle::degrees(fixed((rand()%1200-600)/1000.0+0.5)); std::vector<GeoPoint> pts; for (unsigned j=0; j<num; j++) { GeoPoint p=c; p.Longitude += Angle::degrees(fixed((rand()%200)/1000.0)); p.Latitude += Angle::degrees(fixed((rand()%200)/1000.0)); pts.push_back(p); } as = new AirspacePolygon(pts,true); } airspace_random_properties(*as); airspaces.insert(as); #ifdef DO_PRINT fin << *as; #endif } // try inserting nothing airspaces.insert(NULL); airspaces.optimise(); }
void AddPolygon(Airspaces &airspace_database) { if (points.size() < 3) return; AbstractAirspace *as = new AirspacePolygon(points); as->SetProperties(std::move(name), type, base, top); as->SetRadio(radio); as->SetDays(days_of_operation); airspace_database.Add(as); }
void AirspaceNearestSort::populate_queue(const Airspaces &airspaces, const fixed range) { AirspacesInterface::AirspaceVector vectors = airspaces.ScanRange(m_location, range, m_condition); for (auto v = vectors.begin(); v != vectors.end(); ++v) { const AbstractAirspace *as = v->get_airspace(); if (as != NULL) { const AirspaceInterceptSolution ais = solve_intercept(*as, airspaces.GetProjection()); const fixed value = metric(ais); if (!negative(value)) { m_q.push(std::make_pair(m_reverse? -value:value, std::make_pair(ais, *v))); } } } }
gcc_pure static NearestAirspace FindHorizontal(const GeoPoint &location, const Airspaces &airspace_database, const AirspacePredicate &predicate) { const auto &projection = airspace_database.GetProjection(); return FindMinimum(airspace_database, location, 30000, predicate, [&location, &projection](const AbstractAirspace &airspace){ return CalculateNearestAirspaceHorizontal(location, projection, airspace); }, CompareNearestAirspace()); }
static void LoadFiles(Airspaces &airspace_database) { NullOperationEnvironment operation; std::unique_ptr<TLineReader> reader(OpenConfiguredTextFile(ProfileKeys::AirspaceFile, Charset::AUTO)); if (reader) { AirspaceParser parser(airspace_database); parser.Parse(*reader, operation); airspace_database.Optimise(); } }
gcc_pure NearestAirspace NearestAirspace::FindVertical(const MoreData &basic, const DerivedInfo &calculated, const ProtectedAirspaceWarningManager &airspace_warnings, const Airspaces &airspace_database) { if (!basic.location_available || (!basic.baro_altitude_available && !basic.gps_altitude_available)) /* can't check for airspaces without a GPS fix and altitude value */ return NearestAirspace(); /* find the nearest airspace */ AltitudeState altitude; altitude.altitude = basic.nav_altitude; altitude.altitude_agl = calculated.altitude_agl; const AbstractAirspace *nearest = nullptr; double nearest_delta = 100000; const ActiveAirspacePredicate active_predicate(&airspace_warnings); for (const auto &i : airspace_database.QueryInside(basic.location)) { const AbstractAirspace &airspace = i.GetAirspace(); if (!active_predicate(airspace)) continue; /* check delta below */ auto base = airspace.GetBase().GetAltitude(altitude); auto base_delta = base - altitude.altitude; if (base_delta >= 0 && base_delta < fabs(nearest_delta)) { nearest = &airspace; nearest_delta = base_delta; } /* check delta above */ auto top = airspace.GetTop().GetAltitude(altitude); auto top_delta = altitude.altitude - top; if (top_delta >= 0 && top_delta < fabs(nearest_delta)) { nearest = &airspace; nearest_delta = -top_delta; } } if (nearest == nullptr) return NearestAirspace(); return NearestAirspace(*nearest, nearest_delta); }
static void LoadFiles(Airspaces &airspace_database) { NullOperationEnvironment operation; TLineReader *reader = OpenConfiguredTextFile(szProfileAirspaceFile); if (reader != NULL) { AirspaceParser parser(airspace_database); parser.Parse(*reader, operation); delete reader; airspace_database.optimise(); } }
static bool ParseFile(Path path, Airspaces &airspaces) { FileLineReader reader(path, Charset::AUTO); AirspaceParser parser(airspaces); NullOperationEnvironment operation; if (!ok1(parser.Parse(reader, operation))) return false; airspaces.Optimise(); return true; }
void AirspaceXSRenderer::Draw(Canvas &canvas, const ChartRenderer &chart, const Airspaces &database, const GeoPoint &start, const GeoVector &vec, const AircraftState &state) const { canvas.Select(*look.name_font); // Create IntersectionVisitor to render to the canvas AirspaceIntersectionVisitorSlice ivisitor( canvas, chart, settings, look, start, state); // Call visitor with intersecting airspaces database.VisitIntersecting(start, vec.EndPoint(start), ivisitor); }
void ReadAirspace(Airspaces &airspaces, RasterTerrain *terrain, const AtmosphericPressure &press, OperationEnvironment &operation) { LogFormat("ReadAirspace"); operation.SetText(_("Loading Airspace File...")); bool airspace_ok = false; AirspaceParser parser(airspaces); // Read the airspace filenames from the registry auto path = Profile::GetPath(ProfileKeys::AirspaceFile); if (!path.IsNull()) airspace_ok |= ParseAirspaceFile(parser, path, operation); path = Profile::GetPath(ProfileKeys::AdditionalAirspaceFile); if (!path.IsNull()) airspace_ok |= ParseAirspaceFile(parser, path, operation); auto archive = OpenMapFile(); if (archive) airspace_ok |= ParseAirspaceFile(parser, archive->get(), "airspace.txt", operation); if (airspace_ok) { airspaces.Optimise(); airspaces.SetFlightLevels(press); if (terrain != NULL) airspaces.SetGroundLevels(*terrain); } else // there was a problem airspaces.Clear(); }
gcc_pure NearestAirspace NearestAirspace::FindHorizontal(const MoreData &basic, const ProtectedAirspaceWarningManager &airspace_warnings, const Airspaces &airspace_database) { if (!basic.location_available) /* can't check for airspaces without a GPS fix */ return NearestAirspace(); /* find the nearest airspace */ //consider only active airspaces const WrapAirspacePredicate<ActiveAirspacePredicate> active_predicate(&airspace_warnings); const WrapAirspacePredicate<OutsideAirspacePredicate> outside_predicate(AGeoPoint(basic.location, RoughAltitude(0))); const AndAirspacePredicate outside_and_active_predicate(active_predicate, outside_predicate); const Airspace *airspace; //if altitude is available, filter airspaces in same height as airplane if (basic.NavAltitudeAvailable()) { /* check altitude; hard-coded margin of 50m (for now) */ WrapAirspacePredicate<AirspacePredicateHeightRange> height_range_predicate(RoughAltitude(basic.nav_altitude-fixed(50)), RoughAltitude(basic.nav_altitude+fixed(50))); AndAirspacePredicate and_predicate(outside_and_active_predicate, height_range_predicate); airspace = airspace_database.FindNearest(basic.location, and_predicate); } else //only filter outside and active airspace = airspace_database.FindNearest(basic.location, outside_and_active_predicate); if (airspace == nullptr) return NearestAirspace(); const AbstractAirspace &as = airspace->GetAirspace(); /* calculate distance to the nearest point */ const GeoPoint closest = as.ClosestPoint(basic.location, airspace_database.GetProjection()); return NearestAirspace(as, basic.location.Distance(closest)); }
AirspaceSorter::AirspaceSorter(const Airspaces &airspaces, const GeoPoint &Location, const fixed distance_factor) { airspaces.lock(); m_airspaces_all.reserve(airspaces.size()); for (Airspaces::AirspaceTree::const_iterator it = airspaces.begin(); it != airspaces.end(); ++it) { AirspaceSelectInfo info; const AbstractAirspace &airspace = *it->get_airspace(); info.airspace = &airspace; const GeoPoint closest_loc = airspace.closest_point(Location); const GeoVector vec(Location, closest_loc); info.Distance = vec.Distance*distance_factor; info.Direction = vec.Bearing; tstring Name = airspace.get_name_text(true); info.FourChars = ((Name.c_str()[0] & 0xff) << 24) +((Name.c_str()[1] & 0xff) << 16) +((Name.c_str()[2] & 0xff) << 8) +((Name.c_str()[3] & 0xff)); m_airspaces_all.push_back(info); } airspaces.unlock(); sort_name(m_airspaces_all); }
gcc_pure static inline Result FindMinimum(const Airspaces &airspaces, const GeoPoint &location, double range, const AirspacePredicate &predicate, Func &&func, Cmp &&cmp=Cmp()) { Result minimum; for (const auto &i : airspaces.QueryWithinRange(location, range)) { const AbstractAirspace &aa = i.GetAirspace(); Result result = func(aa); if (cmp(result, minimum)) minimum = result; } return minimum; }
static bool ParseFile(const TCHAR *path, Airspaces &airspaces) { FileLineReader reader(path, ConvertLineReader::AUTO); if (!ok1(!reader.error())) { skip(1, 0, "Failed to read input file"); return false; } AirspaceParser parser(airspaces); NullOperationEnvironment operation; if (!ok1(parser.Parse(reader, operation))) return false; airspaces.Optimise(); return true; }