Beispiel #1
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;
}
Beispiel #2
0
const Airspaces::AirspaceVector
Airspaces::find_inside(const AircraftState &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 (auto 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;
}
Beispiel #3
0
const Airspaces::AirspaceVector
Airspaces::scan_range(const GeoPoint &location,
                      const fixed range,
                      const AirspacePredicate &condition) const
{
  if (empty()) return AirspaceVector(); // nothing to do

  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 (auto 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;
}
void 
AirspaceNearestSort::populate_queue(const Airspaces &airspaces,
                                    const fixed range)
{
  AirspacesInterface::AirspaceVector vectors = 
    airspaces.scan_range(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);
      const fixed value = metric(ais);
      if (!negative(value)) {
        m_q.push(std::make_pair(m_reverse? -value:value, std::make_pair(ais, *v)));
      }
    }
  }
}
Beispiel #5
0
void 
Airspaces::optimise()
{
  if (!m_owner || task_projection.update_fast()) {
    // dont update task_projection if not owner!

    // task projection changed, so need to push items back onto stack
    // to re-build airspace envelopes

    for (auto it = airspace_tree.begin(); it != airspace_tree.end(); ++it)
      tmp_as.push_back(it->get_airspace());

    airspace_tree.clear();
  }

  if (!tmp_as.empty()) {
    while (!tmp_as.empty()) {
      Airspace as(*tmp_as.front(), task_projection);
      airspace_tree.insert(as);
      tmp_as.pop_front();
    }
    airspace_tree.optimise();
  }
}
Beispiel #6
0
 /**
  * Equality operator, matches if contained airspace is the same
  */
 bool operator==(Airspace const& a) const {
   return (get_airspace() == a.get_airspace());
 }