const Airspaces::AirspaceVector Airspaces::scan_nearest(const GeoPoint &location, const AirspacePredicate &condition) const { Airspace bb_target(location, task_projection); std::pair<AirspaceTree::const_iterator, double> found = airspace_tree.find_nearest(bb_target); #ifdef INSTRUMENT_TASK n_queries++; #endif AirspaceVector res; if (found.first != airspace_tree.end()) { // also should do scan_range with range = 0 since there // could be more than one with zero dist if (found.second == 0) { return scan_range(location, fixed_zero, condition); } else { if (condition(*found.first->get_airspace())) res.push_back(*found.first); } } return res; }
const Airspaces::AirspaceVector Airspaces::scan_range(const GeoPoint &location, const fixed range, const AirspacePredicate &condition) const { Airspace bb_target(location, task_projection); int mrange = task_projection.project_range(location, range); std::deque< Airspace > vectors; airspace_tree.find_within_range(bb_target, -mrange, std::back_inserter(vectors)); #ifdef INSTRUMENT_TASK n_queries++; #endif AirspaceVector res; for (std::deque<Airspace>::iterator v = vectors.begin(); v != vectors.end(); ++v) { if (!condition(*v->get_airspace())) continue; if (fixed((*v).distance(bb_target)) > range) continue; if ((*v).inside(location) || positive(range)) res.push_back(*v); } return res; }
const Airspaces::AirspaceVector Airspaces::ScanRange(const GeoPoint &location, fixed range, const AirspacePredicate &condition) const { if (empty()) // nothing to do return AirspaceVector(); Airspace bb_target(location, task_projection); int projected_range = task_projection.ProjectRangeInteger(location, range); std::deque< Airspace > vectors; airspace_tree.find_within_range(bb_target, -projected_range, std::back_inserter(vectors)); #ifdef INSTRUMENT_TASK n_queries++; #endif AirspaceVector res; for (const auto &v : vectors) { if (!condition(*v.GetAirspace())) continue; if (fixed(v.Distance(bb_target)) > range) continue; if (v.IsInside(location) || positive(range)) res.push_back(v); } return res; }
const Airspaces::AirspaceVector Airspaces::FindInside(const AircraftState &state, const AirspacePredicate &condition) const { Airspace bb_target(state.location, task_projection); AirspaceVector vectors; #ifdef INSTRUMENT_TASK n_queries++; #endif std::function<void(const Airspace &)> visitor = [&state, &condition, &vectors](const Airspace &v){ #ifdef INSTRUMENT_TASK count_intersections++; #endif if (condition(v.GetAirspace()) && v.IsInside(state)) vectors.push_back(v); }; airspace_tree.visit_within_range(bb_target, 0, visitor); return vectors; }
const Airspaces::AirspaceVector Airspaces::ScanRange(const GeoPoint &location, fixed range, const AirspacePredicate &condition) const { if (IsEmpty()) // nothing to do return AirspaceVector(); Airspace bb_target(location, task_projection); int projected_range = task_projection.ProjectRangeInteger(location, range); #ifdef INSTRUMENT_TASK n_queries++; #endif AirspaceVector res; std::function<void(const Airspace &)> visitor = [&location, range, &condition, &bb_target, &res](const Airspace &v){ if (condition(v.GetAirspace()) && fixed(v.Distance(bb_target)) <= range && (v.IsInside(location) || positive(range))) res.push_back(v); }; airspace_tree.visit_within_range(bb_target, -projected_range, visitor); return res; }
const Airspaces::AirspaceVector Airspaces::ScanNearest(const GeoPoint &location, const AirspacePredicate &condition) const { if (empty()) // nothing to do return AirspaceVector(); Airspace bb_target(location, task_projection); std::pair<AirspaceTree::const_iterator, AirspaceTree::distance_type> found = airspace_tree.find_nearest(bb_target); #ifdef INSTRUMENT_TASK n_queries++; #endif AirspaceVector res; if (found.first != airspace_tree.end()) { // also should do scan_range with range = 0 since there // could be more than one with zero dist if (found.second.is_zero()) return ScanRange(location, fixed_zero, condition); if (condition(*found.first->GetAirspace())) res.push_back(*found.first); } return res; }
inline AirspacesInterface::AirspaceVector Airspaces::AsVector() const { AirspaceVector v; v.reserve(airspace_tree.size()); for (const auto &i : QueryAll()) v.push_back(i); return v; }