bool 
AirspaceWarningManager::update_inside(const AIRCRAFT_STATE& state)
{
  bool found = false;

  AirspacePredicateAircraftInside condition(state);

  Airspaces::AirspaceVector results = m_airspaces.find_inside(state, condition);
  for (Airspaces::AirspaceVector::iterator it = results.begin();
       it != results.end(); ++it) {

    const AbstractAirspace& airspace = *it->get_airspace();
    if (!config.class_enabled(airspace.get_type()))
        continue;

    AirspaceWarning& warning = get_warning(airspace);

    if (warning.state_accepted(AirspaceWarning::WARNING_INSIDE)) {
      GeoPoint c = airspace.closest_point(state.Location);
      GeoVector vector_exit(state.Location, c);
      AirspaceInterceptSolution solution;
      airspace.intercept(state, vector_exit, m_perf_glide, solution); 

      warning.update_solution(AirspaceWarning::WARNING_INSIDE, solution);
      found = true;
    }
  }

  return found;
}
Beispiel #2
0
PyObject* xcsoar_Airspaces_findIntrusions(Pyxcsoar_Airspaces *self, PyObject *args) {
  PyObject *py_flight = nullptr;

  if (!PyArg_ParseTuple(args, "O", &py_flight)) {
    PyErr_SetString(PyExc_AttributeError, "Can't parse argument.");
    return nullptr;
  }

  DebugReplay *replay = ((Pyxcsoar_Flight*)py_flight)->flight->Replay();

  if (replay == nullptr) {
    PyErr_SetString(PyExc_IOError, "Can't start replay - file not found.");
    return nullptr;
  }

  PyObject *py_result = PyDict_New();
  Airspaces::AirspaceVector last_airspaces;

  while (replay->Next()) {
    const MoreData &basic = replay->Basic();

    if (!basic.time_available || !basic.location_available ||
        !basic.NavAltitudeAvailable())
      continue;

    Airspaces::AirspaceVector airspaces = self->airspace_database->FindInside(
      ToAircraftState(basic, replay->Calculated())
    );

    for (auto it = airspaces.begin(); it != airspaces.end(); it++) {
      PyObject *py_name = PyString_FromString((*it).GetAirspace().GetName());
      PyObject *py_airspace = nullptr,
               *py_period = nullptr;

      if (PyDict_Contains(py_result, py_name) == 0) {
        // this is the first fix inside this airspace
        py_airspace = PyList_New(0);
        PyDict_SetItem(py_result, py_name, py_airspace);

        py_period = PyList_New(0);
        PyList_Append(py_airspace, py_period);
        Py_DECREF(py_period);

      } else {
        // this airspace was hit some time before...
        py_airspace = PyDict_GetItem(py_result, py_name);

        // check if the last fix was already inside this airspace
        auto in_last = std::find(last_airspaces.begin(), last_airspaces.end(), *it);

        if (in_last == last_airspaces.end()) {
          // create a new period
          py_period = PyList_New(0);
          PyList_Append(py_airspace, py_period);
          Py_DECREF(py_period);
        } else {
          py_period = PyList_GET_ITEM(py_airspace, PyList_GET_SIZE(py_airspace) - 1);
        }
      }

      PyList_Append(py_period, Py_BuildValue("{s:N,s:N}",
        "time", Python::BrokenDateTimeToPy(basic.date_time_utc),
        "location", Python::WriteLonLat(basic.location)));
    }

    last_airspaces.swap(airspaces);
  }

  delete replay;

  return py_result;
}