예제 #1
0
const Airspaces::AirspaceVector
Airspaces::find_inside(const AIRCRAFT_STATE &state,
                       const AirspacePredicate &condition) const
{
  Airspace bb_target(state.Location, task_projection);

  AirspaceVector vectors;
  airspace_tree.find_within_range(bb_target, 0, std::back_inserter(vectors));

#ifdef INSTRUMENT_TASK
  n_queries++;
#endif

  for (AirspaceVector::iterator v = vectors.begin(); v != vectors.end();) {

#ifdef INSTRUMENT_TASK
    count_intersections++;
#endif
    
    if (!condition(*v->get_airspace()) || !(*v).inside(state))
      vectors.erase(v);
    else
      ++v;
  }

  return vectors;
}
예제 #2
0
bool
Airspaces::synchronise_in_range(const Airspaces& master,
                                const GeoPoint &location,
                                const fixed range,
                                const AirspacePredicate &condition)
{
  bool changed = false;
  const AirspaceVector contents_master = master.scan_range(location, range, condition);
  AirspaceVector contents_self;
  contents_self.reserve(max(airspace_tree.size(), contents_master.size()));

  task_projection = master.task_projection; // ensure these are up to date

  for (auto t = airspace_tree.begin(); t != airspace_tree.end(); ++t)
    contents_self.push_back(*t);

  // find items to add
  for (auto v = contents_master.begin(); v != contents_master.end(); ++v) {
    const AbstractAirspace* other = v->get_airspace();

    bool found = false;
    for (auto s = contents_self.begin(); s != contents_self.end(); ++s) {
      const AbstractAirspace* self = s->get_airspace();
      if (self == other) {
        found = true;
        contents_self.erase(s);
        break;
      }
    }
    if (!found && other->IsActive()) {
      insert(v->get_airspace());
      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->get_airspace() == v->get_airspace()) {
        AirspaceTree::const_iterator new_t = t;
        ++new_t;
        airspace_tree.erase_exact(*t);
        t = new_t;
        found = true;
      } else {
        ++t;
      }
    }
    assert(found);
    v->clear_clearance();
    v = contents_self.erase(v);
    changed = true;
  }
  if (changed)
    optimise();
  return changed;
}
예제 #3
0
void
Airspaces::visit_inside(const GeoPoint &loc,
                        AirspaceVisitor& visitor) const
{
  if (empty()) return; // nothing to do

  Airspace bb_target(loc, task_projection);
  AirspaceVector vectors;
  airspace_tree.find_within_range(bb_target, 0, std::back_inserter(vectors));

  for (auto v = vectors.begin(); v != vectors.end(); ++v) {
    if ((*v).inside(loc))
      visitor.Visit(*v);
  }
}