inline void RouteComputer::Reach(const MoreData &basic, DerivedInfo &calculated, const RoutePlannerConfig &config) { if (!calculated.terrain_valid) { /* without valid terrain information, we cannot calculate reachabilty, so let's skip that step completely */ calculated.terrain_base_valid = false; protected_route_planner.ClearReach(); return; } const bool do_solve = config.IsReachEnabled() && terrain != NULL; const AircraftState state = ToAircraftState(basic, calculated); const AGeoPoint start (state.location, state.altitude); const int h_ceiling(std::max((int)basic.nav_altitude + 500, (int)calculated.common_stats.height_max_working)); if (reach_clock.CheckAdvance(basic.time, PERIOD)) { protected_route_planner.SolveReach(start, config, h_ceiling, do_solve); if (do_solve) { calculated.terrain_base = route_planner.GetTerrainBase(); calculated.terrain_base_valid = true; } } }
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 AirspaceRenderer::Draw(Canvas &canvas, #ifndef ENABLE_OPENGL Canvas &stencil_canvas, #endif const WindowProjection &projection, const MoreData &basic, const DerivedInfo &calculated, const AirspaceComputerSettings &computer_settings, const AirspaceRendererSettings &settings) { if (airspaces == NULL) return; AirspaceWarningCopy awc; if (warning_manager != NULL) awc.Visit(*warning_manager); const AircraftState aircraft = ToAircraftState(basic, calculated); const AirspaceMapVisible visible(computer_settings, settings, aircraft, awc); Draw(canvas, #ifndef ENABLE_OPENGL stencil_canvas, #endif projection, settings, awc, visible); }
inline void RouteComputer::TerrainWarning(const MoreData &basic, DerivedInfo &calculated, const RoutePlannerConfig &config) { const AircraftState as = ToAircraftState(basic, calculated); const GlideResult& sol = calculated.task_stats.current_leg.solution_remaining; if (!sol.IsDefined()) { calculated.terrain_warning = false; return; } const AGeoPoint start (as.location, as.altitude); const RoughAltitude h_ceiling(std::max((int)basic.nav_altitude+500, (int)calculated.thermal_band.working_band_ceiling)); // allow at least 500m of climb above current altitude as ceiling, in case // there are no actual working band stats. GeoVector v = sol.vector; if (v.distance > fixed(200000)) /* limit to reasonable distances (200km max.) to avoid overflow in GeoVector::EndPoint() */ v.distance = fixed(200000); if (terrain) { if (sol.IsDefined()) { const AGeoPoint dest(v.EndPoint(start), sol.min_arrival_altitude); bool dirty = route_clock.CheckAdvance(basic.time); if (!dirty) { dirty = calculated.common_stats.active_taskpoint_index != last_active_tp || calculated.common_stats.task_type != last_task_type; if (dirty) { // restart clock route_clock.CheckAdvance(basic.time); route_clock.Reset(); } } last_task_type = calculated.common_stats.task_type; last_active_tp = calculated.common_stats.active_taskpoint_index; if (dirty) { protected_route_planner.SolveRoute(dest, start, config, h_ceiling); calculated.planned_route = route_planner.GetSolution(); calculated.terrain_warning = route_planner.Intersection(start, dest, calculated.terrain_warning_location); } return; } else { protected_route_planner.SolveRoute(start, start, config, h_ceiling); calculated.planned_route = route_planner.GetSolution(); } } calculated.terrain_warning = false; }
void MapWindow::DrawWaypoints(Canvas &canvas) { GlidePolar polar = get_glide_polar(); polar.set_mc(min(Calculated().common_stats.current_risk_mc, SettingsComputer().safety_mc)); way_point_renderer.render(canvas, label_block, render_projection, SettingsMap(), SettingsComputer(), polar, ToAircraftState(Basic()), task); }
static int TestOLC(DebugReplay &replay) { for (int i = 1; replay.Next(); i++) { if (i % 500 == 0) { putchar('.'); fflush(stdout); } const AircraftState state = ToAircraftState(replay.Basic(), replay.Calculated()); full_trace.append(state); sprint_trace.append(state); full_trace.optimise_if_old(); sprint_trace.optimise_if_old(); olc_sprint.UpdateIdle(); } olc_classic.SolveExhaustive(); olc_fai.SolveExhaustive(); olc_league.SolveExhaustive(); olc_plus.SolveExhaustive(); putchar('\n'); std::cout << "classic\n"; PrintHelper::print(olc_classic.GetStats().get_contest_result()); std::cout << "league\n"; PrintHelper::print(olc_league.GetStats().get_contest_result()); std::cout << "fai\n"; PrintHelper::print(olc_fai.GetStats().get_contest_result()); std::cout << "sprint\n"; PrintHelper::print(olc_sprint.GetStats().get_contest_result()); std::cout << "plus\n"; PrintHelper::print(olc_plus.GetStats().get_contest_result()); olc_classic.Reset(); olc_fai.Reset(); olc_sprint.Reset(); olc_league.Reset(); olc_plus.Reset(); full_trace.clear(); sprint_trace.clear(); return 0; }
void GlideComputerRoute::TerrainWarning(const MoreData &basic, DerivedInfo &calculated, const DerivedInfo &last_calculated, const RoutePlannerConfig &config) { const AircraftState as = ToAircraftState(basic, calculated); const GlideResult& sol = calculated.task_stats.current_leg.solution_remaining; const AGeoPoint start (as.location, as.altitude); const short h_ceiling = (short)std::max((int)basic.NavAltitude+500, (int)calculated.thermal_band.working_band_ceiling); // allow at least 500m of climb above current altitude as ceiling, in case // there are no actual working band stats. const GeoVector &v = sol.vector; if (terrain) { if (sol.IsDefined()) { const AGeoPoint dest(v.end_point(start), sol.min_height); bool dirty = route_clock.check_advance(basic.time); if (!dirty) { dirty = calculated.common_stats.active_taskpoint_index != last_calculated.common_stats.active_taskpoint_index; dirty |= calculated.common_stats.mode_abort != last_calculated.common_stats.mode_abort; dirty |= calculated.common_stats.mode_goto != last_calculated.common_stats.mode_goto; dirty |= calculated.common_stats.mode_ordered != last_calculated.common_stats.mode_ordered; if (dirty) { // restart clock route_clock.check_advance(basic.time); route_clock.reset(); } } if (dirty) { protected_route_planner.SolveRoute(dest, start, config, h_ceiling, calculated.planned_route); calculated.terrain_warning = route_planner.intersection(start, dest, calculated.terrain_warning_location); } return; } else { protected_route_planner.SolveRoute(start, start, config, h_ceiling, calculated.planned_route); } } calculated.terrain_warning = false; }
void WarningComputer::Update(const ComputerSettings &settings_computer, const MoreData &basic, const DerivedInfo &calculated, AirspaceWarningsInfo &result) { if (!basic.time_available) return; const fixed dt = delta_time.Update(basic.time, fixed(1), fixed(20)); if (negative(dt)) /* time warp */ Reset(); if (!positive(dt)) return; airspaces.SetFlightLevels(settings_computer.pressure); AirspaceActivity day(calculated.date_time_local.day_of_week); airspaces.SetActivity(day); if (!settings_computer.airspace.enable_warnings || !basic.location_available || !basic.NavAltitudeAvailable()) { if (initialised) { initialised = false; protected_manager.Clear(); } return; } const AircraftState as = ToAircraftState(basic, calculated); ProtectedAirspaceWarningManager::ExclusiveLease lease(protected_manager); lease->SetConfig(settings_computer.airspace.warnings); if (!initialised) { initialised = true; lease->Reset(as); } if (lease->Update(as, settings_computer.polar.glide_polar_task, calculated.task_stats, calculated.circling, uround(dt))) result.latest.Update(basic.clock); }
void CrossSectionWindow::PaintAirspaces(Canvas &canvas, Chart &chart) { // Quit early if no airspace database available if (airspace_database == NULL) return; // Create IntersectionVisitor to render to the canvas AirspaceIntersectionVisitorSlice ivisitor(canvas, chart, settings_map.airspace, start, ToAircraftState(Basic(), Calculated())); // Call visitor with intersecting airspaces airspace_database->visit_intersecting(start, vec, ivisitor); }
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 != NULL) warnings.Fill(*warning_manager); AirspaceAtPointPredicate predicate(computer_settings, renderer_settings, ToAircraftState(basic, calculated), warnings, location); AirspaceListBuilderVisitor builder(list); airspaces.visit_within_range(location, fixed(100.0), builder, predicate); }
void CrossSectionRenderer::Paint(Canvas &canvas, const PixelRect rc) const { DrawVerticalGradient(canvas, rc, look.sky_color, look.background_color, look.background_color); canvas.SetTextColor(look.text_color); canvas.Select(*look.grid_font); ChartRenderer chart(chart_look, canvas, rc); if (!vec.IsValid() || !start.IsValid()) { chart.DrawNoData(); return; } const fixed nav_altitude = gps_info.NavAltitudeAvailable() ? gps_info.nav_altitude : fixed(0); fixed hmin = std::max(fixed(0), nav_altitude - fixed(3300)); fixed hmax = std::max(fixed(3300), nav_altitude + fixed(1000)); chart.ResetScale(); chart.ScaleXFromValue(fixed(0)); chart.ScaleXFromValue(vec.distance); chart.ScaleYFromValue(hmin); chart.ScaleYFromValue(hmax); short elevations[NUM_SLICES]; UpdateTerrain(elevations); if (airspace_database != nullptr) { const AircraftState aircraft = ToAircraftState(Basic(), Calculated()); airspace_renderer.Draw(canvas, chart, *airspace_database, start, vec, aircraft); } terrain_renderer.Draw(canvas, chart, elevations); PaintGlide(chart); PaintAircraft(canvas, chart, rc); PaintGrid(canvas, chart); }
int main(int argc, char **argv) { Args args(argc, argv, "DRIVER FILE"); DebugReplay *replay = CreateDebugReplay(args); if (replay == NULL) return EXIT_FAILURE; args.ExpectEnd(); Trace trace; while (replay->Next()) { const AircraftState state = ToAircraftState(replay->Basic(), replay->Calculated()); trace.append(state); } delete replay; }
void InputEvents::eventNearestAirspaceDetails(gcc_unused const TCHAR *misc) { const MoreData &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings(); ProtectedAirspaceWarningManager *airspace_warnings = GetAirspaceWarnings(); if (airspace_warnings != NULL && !airspace_warnings->warning_empty()) { // Prevent the dialog from closing itself without active warning // This is relevant if there are only acknowledged airspaces in the list // AutoClose will be reset when the dialog is closed again by hand dlgAirspaceWarningsShowModal(*XCSoarInterface::main_window, *airspace_warnings); return; } const AircraftState aircraft_state = ToAircraftState(basic, calculated); AirspaceVisiblePredicate visible(settings_computer.airspace, CommonInterface::GetMapSettings().airspace, aircraft_state); GlidePolar polar = settings_computer.polar.glide_polar_task; polar.SetMC(max(polar.GetMC(),fixed_one)); AirspaceAircraftPerformanceGlide perf(polar); AirspaceSoonestSort ans(aircraft_state, perf, fixed(1800), visible); const AbstractAirspace* as = ans.find_nearest(airspace_database); if (!as) { return; } dlgAirspaceDetails(*as, airspace_warnings); // clear previous warning if any XCSoarInterface::main_window->popup.Acknowledge(PopupMessage::MSG_AIRSPACE); // TODO code: No control via status data (ala DoStatusMEssage) // - can we change this? // Message::AddMessage(5000, Message::MSG_AIRSPACE, text); }
void WarningComputer::Update(const ComputerSettings &settings_computer, const MoreData &basic, const MoreData &last_basic, const DerivedInfo &calculated, AirspaceWarningsInfo &result) { if (!basic.HasTimeAdvancedSince(last_basic) || !clock.check_advance(basic.time)) return; airspaces.set_flight_levels(settings_computer.pressure); AirspaceActivity day(calculated.date_time_local.day_of_week); airspaces.set_activity(day); if (!settings_computer.airspace.enable_warnings || !basic.location_available || !basic.NavAltitudeAvailable()) { if (initialised) { initialised = false; protected_manager.clear(); } return; } const AircraftState as = ToAircraftState(basic, calculated); ProtectedAirspaceWarningManager::ExclusiveLease lease(protected_manager); if (!initialised) { initialised = true; lease->Reset(as); } if (lease->Update(as, settings_computer.glide_polar_task, calculated.task_stats, calculated.circling, uround(basic.time - last_basic.time))) result.latest.Update(basic.clock); }
void GlideComputerRoute::Reach(const MoreData &basic, DerivedInfo &calculated, const RoutePlannerConfig &config) { if (!calculated.terrain_valid) { /* without valid terrain information, we cannot calculate reachabilty, so let's skip that step completely */ calculated.terrain_base_valid = false; return; } const bool do_solve = config.reach_enabled() && terrain != NULL; const AircraftState state = ToAircraftState(basic, calculated); const AGeoPoint start (state.location, state.altitude); if (reach_clock.check_advance(basic.time)) { protected_route_planner.SolveReach(start, do_solve); if (do_solve) { calculated.terrain_base = fixed(route_planner.get_terrain_base()); calculated.terrain_base_valid = true; } } }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool Startup() { VerboseOperationEnvironment operation; #ifdef HAVE_DOWNLOAD_MANAGER Net::DownloadManager::Initialise(); #endif LogFormat("Display dpi=%u,%u", Display::GetXDPI(), Display::GetYDPI()); // Creates the main window TopWindowStyle style; if (CommandLine::full_screen) style.FullScreen(); style.Resizable(); MainWindow *const main_window = CommonInterface::main_window = new MainWindow(); main_window->Create(SystemWindowSize(), style); if (!main_window->IsDefined()) return false; #ifdef ENABLE_OPENGL LogFormat("OpenGL: " #ifdef ANDROID #ifdef USE_EGL "egl=native " #else "egl=no " #endif #endif #ifdef HAVE_OES_DRAW_TEXTURE "oesdt=%d " #endif #ifdef HAVE_DYNAMIC_MULTI_DRAW_ARRAYS "mda=%d " #endif "npot=%d vbo=%d fbo=%d stencil=%#x", #ifdef HAVE_OES_DRAW_TEXTURE OpenGL::oes_draw_texture, #endif #ifdef HAVE_DYNAMIC_MULTI_DRAW_ARRAYS GLExt::HaveMultiDrawElements(), #endif OpenGL::texture_non_power_of_two, OpenGL::vertex_buffer_object, OpenGL::frame_buffer_object, OpenGL::render_buffer_stencil); #endif CommonInterface::SetUISettings().SetDefaults(); main_window->Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif CommonInterface::SetSystemSettings().SetDefaults(); CommonInterface::SetComputerSettings().SetDefaults(); CommonInterface::SetUIState().Clear(); const auto &computer_settings = CommonInterface::GetComputerSettings(); const auto &ui_settings = CommonInterface::GetUISettings(); auto &live_blackboard = CommonInterface::GetLiveBlackboard(); if (!LoadProfile()) return false; operation.SetText(_("Initialising")); /* create XCSoarData on the first start */ CreateDataPath(); Display::LoadOrientation(operation); main_window->CheckResize(); main_window->InitialiseConfigured(); { file_cache = new FileCache(LocalPath(_T("cache"))); } ReadLanguageFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard = new DeviceBlackboard(); devices = new MultipleDevices(); device_blackboard->SetDevices(*devices); // Initialize main blackboard data task_events = new GlideComputerTaskEvents(); task_manager = new TaskManager(computer_settings.task, way_points); task_manager->SetTaskEvents(*task_events); task_manager->Reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, computer_settings.task); // Read the terrain file operation.SetText(_("Loading Terrain File...")); LogFormat("OpenTerrain"); terrain = RasterTerrain::OpenTerrain(file_cache, operation); logger = new Logger(); glide_computer = new GlideComputer(way_points, airspace_database, *protected_task_manager, *task_events); glide_computer->ReadComputerSettings(computer_settings); glide_computer->SetTerrain(terrain); glide_computer->SetLogger(logger); glide_computer->Initialise(); replay = new Replay(logger, *protected_task_manager); #ifdef HAVE_CMDLINE_REPLAY if (CommandLine::replay_path != nullptr) { Error error; if (!replay->Start(Path(CommandLine::replay_path), error)) LogError(error); } #endif GlidePolar &gp = CommonInterface::SetComputerSettings().polar.glide_polar_task; gp = GlidePolar(0); gp.SetMC(computer_settings.task.safety_mc); gp.SetBugs(computer_settings.polar.degradation_factor); PlaneGlue::FromProfile(CommonInterface::SetComputerSettings().plane, Profile::map); PlaneGlue::Synchronize(computer_settings.plane, CommonInterface::SetComputerSettings(), gp); task_manager->SetGlidePolar(gp); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography, operation); // Read the waypoint files WaypointGlue::LoadWaypoints(way_points, terrain, operation); // Read and parse the airfield info file WaypointDetails::ReadFileFromProfile(way_points, operation); // Set the home waypoint WaypointGlue::SetHome(way_points, terrain, CommonInterface::SetComputerSettings().poi, CommonInterface::SetComputerSettings().team_code, device_blackboard, false); // ReSynchronise the blackboards here since SetHome touches them device_blackboard->Merge(); CommonInterface::ReadBlackboardBasic(device_blackboard->Basic()); // Scan for weather forecast LogFormat("RASP load"); rasp = new RaspStore(); rasp->ScanAll(); // Reads the airspace files ReadAirspace(airspace_database, terrain, computer_settings.pressure, operation); { const AircraftState aircraft_state = ToAircraftState(device_blackboard->Basic(), device_blackboard->Calculated()); ProtectedAirspaceWarningManager::ExclusiveLease lease(glide_computer->GetAirspaceWarnings()); lease->Reset(aircraft_state); } #ifdef HAVE_NOAA noaa_store = new NOAAStore(); noaa_store->LoadFromProfile(); #endif AudioVarioGlue::Initialise(); AudioVarioGlue::Configure(ui_settings.sound.vario); // Start the device thread(s) operation.SetText(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data GlidePolar::UpdatePolar(true, computer_settings); This should be done inside devStartup if it is really required */ operation.SetText(_("Initialising display")); GlueMapWindow *map_window = main_window->GetMap(); if (map_window != nullptr) { map_window->SetWaypoints(&way_points); map_window->SetTask(protected_task_manager); map_window->SetRoutePlanner(&glide_computer->GetProtectedRoutePlanner()); map_window->SetGlideComputer(glide_computer); map_window->SetAirspaces(&airspace_database); map_window->SetTopography(topography); map_window->SetTerrain(terrain); map_window->SetWeather(rasp); #ifdef HAVE_NOAA map_window->SetNOAAStore(noaa_store); #endif /* show map at home waypoint until GPS fix becomes available */ if (computer_settings.poi.home_location_available) map_window->SetLocation(computer_settings.poi.home_location); } // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL draw_thread = new DrawThread(*map_window); draw_thread->Start(true); #endif // Show the infoboxes InfoBoxManager::Show(); // Create the calculation thread CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); glide_computer_events = new GlideComputerEvents(); glide_computer_events->Reset(); live_blackboard.AddListener(*glide_computer_events); all_monitors = new AllMonitors(); if (!is_simulator() && computer_settings.logger.enable_flight_logger) { flight_logger = new GlueFlightLogger(live_blackboard); flight_logger->SetPath(LocalPath(_T("flights.log"))); } if (computer_settings.logger.enable_nmea_logger) NMEALogger::enabled = true; LogFormat("ProgramStarted"); // Give focus to the map main_window->SetDefaultFocus(); // Start calculation thread merge_thread->Start(); calculation_thread->Start(); PageActions::Update(); #ifdef HAVE_TRACKING tracking = new TrackingGlue(); tracking->SetSettings(computer_settings.tracking); #ifdef HAVE_SKYLINES_TRACKING_HANDLER if (map_window != nullptr) map_window->SetSkyLinesData(&tracking->GetSkyLinesData()); #endif #endif assert(!global_running); global_running = true; AfterStartup(); operation.Hide(); main_window->FinishStartup(); return true; }
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; }
static void Run(DebugReplay &replay, OrderedTask &task, const GlidePolar &glide_polar) { Validity last_location_available; last_location_available.Clear(); AircraftState last_as; bool last_as_valid = false; bool task_finished = false; unsigned active_taskpoint_index(-1); char time_buffer[32]; while (replay.Next()) { const MoreData &basic = replay.Basic(); const DerivedInfo &calculated = replay.Calculated(); if (!basic.location_available) { last_location_available.Clear(); continue; } const AircraftState current_as = ToAircraftState(basic, calculated); if (!last_location_available) { last_as = current_as; last_as_valid = true; last_location_available = basic.location_available; continue; } if (!basic.location_available.Modified(last_location_available)) continue; if (!last_as_valid) { last_as = current_as; last_as_valid = true; last_location_available = basic.location_available; continue; } task.Update(current_as, last_as, glide_polar); task.UpdateIdle(current_as, glide_polar); task.SetTaskAdvance().SetArmed(true); if (task.GetActiveIndex() != active_taskpoint_index) { active_taskpoint_index = task.GetActiveIndex(); FormatISO8601(time_buffer, basic.date_time_utc); printf("%s active_taskpoint_index=%u\n", time_buffer, active_taskpoint_index); } const TaskStats &task_stats = task.GetStats(); if (task_finished != task_stats.task_finished) { task_finished = true; FormatISO8601(time_buffer, basic.date_time_utc); printf("%s task finished\n", time_buffer); } last_as = current_as; last_as_valid = true; } const TaskStats &task_stats = task.GetStats(); printf("task_started=%d task_finished=%d\n", task_stats.start.task_started, task_stats.task_finished); printf("task elapsed %ds\n", (int)task_stats.total.time_elapsed); printf("task speed %1.2f kph\n", double(task_stats.total.travelled.GetSpeed() * 3.6)); printf("travelled distance %1.3f km\n", double(task_stats.total.travelled.GetDistance() / 1000)); printf("scored distance %1.3f km\n", double(task_stats.distance_scored / 1000)); if (task_stats.total.time_elapsed > 0) printf("scored speed %1.2f kph\n", double(task_stats.distance_scored / task_stats.total.time_elapsed * 3.6)); }
void dlgWayPointDetailsShowModal(SingleWindow &parent, const Waypoint& way_point, bool allow_navigation) { const NMEA_INFO &basic = CommonInterface::Basic(); const DERIVED_INFO &calculated = CommonInterface::Calculated(); const SETTINGS_COMPUTER &settings_computer = CommonInterface::SettingsComputer(); selected_waypoint = &way_point; wf = LoadDialog(CallBackTable, parent, Layout::landscape ? _T("IDR_XML_WAYPOINTDETAILS_L") : _T("IDR_XML_WAYPOINTDETAILS")); assert(wf != NULL); nTextLines = 0; TCHAR buffer[MAX_PATH]; const TCHAR *Directory = NULL; if (Profile::GetPath(szProfileWayPointFile, szWaypointFile)) Directory = DirName(szWaypointFile, buffer); if (Directory == NULL) Directory = _T(""); _stprintf(path_modis, _T("%s" DIR_SEPARATOR_S "modis-%03d.jpg"), Directory, selected_waypoint->original_id); _stprintf(path_google,_T("%s" DIR_SEPARATOR_S "google-%03d.jpg"), Directory, selected_waypoint->original_id); TCHAR sTmp[128]; _stprintf(sTmp, _T("%s: '%s'"), wf->GetCaption(), selected_waypoint->Name.c_str()); wf->SetCaption(sTmp); WndProperty *wp; wp = ((WndProperty *)wf->FindByName(_T("prpWpComment"))); wp->SetText(selected_waypoint->Comment.c_str()); Units::LongitudeToString(selected_waypoint->Location.Longitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpLongitude"))) ->SetText(sTmp); Units::LatitudeToString(selected_waypoint->Location.Latitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpLatitude"))) ->SetText(sTmp); Units::FormatUserAltitude(selected_waypoint->Altitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpAltitude"))) ->SetText(sTmp); SunEphemeris sun; sun.CalcSunTimes(selected_waypoint->Location, basic.DateTime, fixed(GetUTCOffset()) / 3600); int sunsethours = (int)sun.TimeOfSunSet; int sunsetmins = (int)((sun.TimeOfSunSet - fixed(sunsethours)) * 60); _stprintf(sTmp, _T("%02d:%02d"), sunsethours, sunsetmins); ((WndProperty *)wf->FindByName(_T("prpSunset")))->SetText(sTmp); GeoVector gv = basic.Location.distance_bearing(selected_waypoint->Location); TCHAR DistanceText[MAX_PATH]; Units::FormatUserDistance(gv.Distance, DistanceText, 10); ((WndProperty *)wf->FindByName(_T("prpDistance"))) ->SetText(DistanceText); _stprintf(sTmp, _T("%d")_T(DEG), iround(gv.Bearing.value_degrees())); ((WndProperty *)wf->FindByName(_T("prpBearing"))) ->SetText(sTmp); if (protected_task_manager != NULL) { GlidePolar glide_polar = settings_computer.glide_polar_task; const GlidePolar &safety_polar = calculated.glide_polar_safety; UnorderedTaskPoint t(way_point, settings_computer); GlideResult r; // alt reqd at current mc const AIRCRAFT_STATE aircraft_state = ToAircraftState(basic, calculated); r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc2")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } // alt reqd at mc 0 glide_polar.set_mc(fixed_zero); r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc0")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } // alt reqd at safety mc r = TaskSolution::glide_solution_remaining(t, aircraft_state, safety_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc1")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } } wf->SetKeyDownNotify(FormKeyDown); ((WndButton *)wf->FindByName(_T("cmdClose")))->SetOnClickNotify(OnCloseClicked); wInfo = ((WndFrame *)wf->FindByName(_T("frmInfos"))); wCommand = ((WndFrame *)wf->FindByName(_T("frmCommands"))); wImage = ((WndOwnerDrawFrame *)wf->FindByName(_T("frmImage"))); wDetails = (WndListFrame*)wf->FindByName(_T("frmDetails")); wDetails->SetPaintItemCallback(OnPaintDetailsListItem); assert(wInfo != NULL); assert(wCommand != NULL); assert(wImage != NULL); assert(wDetails != NULL); nTextLines = TextToLineOffsets(way_point.Details.c_str(), LineOffsets, MAXLINES); wDetails->SetLength(nTextLines); wCommand->hide(); wImage->SetOnPaintNotify(OnImagePaint); if (!allow_navigation) { WndButton* butnav = NULL; butnav = (WndButton *)wf->FindByName(_T("cmdPrev")); assert(butnav); butnav->hide(); butnav = (WndButton *)wf->FindByName(_T("cmdNext")); assert(butnav); butnav->hide(); butnav = (WndButton *)wf->FindByName(_T("cmdGoto")); assert(butnav); butnav->hide(); } WndButton *wb; wb = ((WndButton *)wf->FindByName(_T("cmdGoto"))); if (wb) wb->SetOnClickNotify(OnGotoClicked); wb = ((WndButton *)wf->FindByName(_T("cmdReplace"))); if (wb) wb->SetOnClickNotify(OnReplaceClicked); wb = ((WndButton *)wf->FindByName(_T("cmdNewHome"))); if (wb) wb->SetOnClickNotify(OnNewHomeClicked); wb = ((WndButton *)wf->FindByName(_T("cmdInserInTask"))); if (wb) wb->SetOnClickNotify(OnInsertInTaskClicked); wb = ((WndButton *)wf->FindByName(_T("cmdAppendInTask"))); if (wb) wb->SetOnClickNotify(OnAppendInTaskClicked); wb = ((WndButton *)wf->FindByName(_T("cmdRemoveFromTask"))); if (wb) wb->SetOnClickNotify(OnRemoveFromTaskClicked); /* JMW disabled until 6.2 work, see #996 wb = ((WndButton *)wf->FindByName(_T("cmdGotoAndClearTask"))); if (wb) wb->SetOnClickNotify(OnGotoAndClearTaskClicked); */ wb = ((WndButton *)wf->FindByName(_T("cmdActivatePan"))); if (wb) wb->SetOnClickNotify(OnActivatePanClicked); hasimage1 = jpgimage1.load_file(path_modis); hasimage2 = jpgimage2.load_file(path_google); page = 0; NextPage(0); // JMW just to turn proper pages on/off wf->ShowModal(); delete wf; jpgimage1.reset(); jpgimage2.reset(); }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool XCSoarInterface::Startup() { VerboseOperationEnvironment operation; // Set the application title to "XCSoar" TCHAR szTitle[] = _T("XCSoar"); //If "XCSoar" is already running, stop this instance if (MainWindow::find(szTitle)) return false; LogStartUp(_T("Display dpi=%u,%u"), Display::GetXDPI(), Display::GetYDPI()); // Creates the main window LogStartUp(_T("Create main window")); TopWindowStyle style; if (CommandLine::full_screen) style.FullScreen(); if (CommandLine::resizable) style.Resizable(); main_window.Set(szTitle, SystemWindowSize(), style); if (!main_window.IsDefined()) return false; #ifdef ENABLE_OPENGL LogStartUp(_T("OpenGL: " #ifdef HAVE_EGL "egl=%d " #endif "npot=%d vbo=%d fbo=%d"), #ifdef HAVE_EGL OpenGL::egl, #endif OpenGL::texture_non_power_of_two, OpenGL::vertex_buffer_object, OpenGL::frame_buffer_object); #endif main_window.Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { DialogLook white_look; white_look.Initialise(Fonts::map_bold, Fonts::map, Fonts::map_label, Fonts::map_bold, Fonts::map_bold); white_look.SetBackgroundColor(COLOR_WHITE); SetXMLDialogLook(white_look); SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif SetXMLDialogLook(main_window.GetLook().dialog); SetSystemSettings().SetDefaults(); SetComputerSettings().SetDefaults(); SetUISettings().SetDefaults(); SetUIState().Clear(); if (!LoadProfile()) return false; operation.SetText(_("Initialising")); /* create XCSoarData on the first start */ CreateDataPath(); Display::LoadOrientation(operation); main_window.InitialiseConfigured(); TCHAR path[MAX_PATH]; LocalPath(path, _T("cache")); file_cache = new FileCache(path); ReadLanguageFile(); status_messages.LoadFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard = new DeviceBlackboard(); DeviceListInitialise(); // Initialize Markers marks = new Markers(); protected_marks = new ProtectedMarkers(*marks); #ifdef HAVE_AYGSHELL_DLL const AYGShellDLL &ayg = main_window.ayg_shell_dll; ayg.SHSetAppKeyWndAssoc(VK_APP1, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP2, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP3, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP4, main_window); // Typical Record Button // Why you can't always get this to work // http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm // To do with the fact it is a global hotkey, but you can with code above // Also APPA is record key on some systems ayg.SHSetAppKeyWndAssoc(VK_APP5, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP6, main_window); #endif // Initialize main blackboard data task_manager = new TaskManager(GetComputerSettings().task, way_points); task_manager->SetTaskEvents(task_events); task_manager->Reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, XCSoarInterface::GetComputerSettings().task); // Read the terrain file operation.SetText(_("Loading Terrain File...")); LogStartUp(_T("OpenTerrain")); terrain = RasterTerrain::OpenTerrain(file_cache, operation); glide_computer = new GlideComputer(way_points, airspace_database, *protected_task_manager, task_events); glide_computer->ReadComputerSettings(GetComputerSettings()); glide_computer->SetTerrain(terrain); glide_computer->SetLogger(&logger); glide_computer->Initialise(); replay = new Replay(&logger, *protected_task_manager); // Load the EGM96 geoid data EGM96::Load(); GlidePolar &gp = SetComputerSettings().polar.glide_polar_task; gp = GlidePolar(fixed_zero); gp.SetMC(GetComputerSettings().task.safety_mc); gp.SetBugs(GetComputerSettings().polar.degradation_factor); PlaneGlue::FromProfile(SetComputerSettings().plane); PlaneGlue::Synchronize(GetComputerSettings().plane, SetComputerSettings(), gp); task_manager->SetGlidePolar(gp); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography, operation); // Read the waypoint files WaypointGlue::LoadWaypoints(way_points, terrain, operation); // Read and parse the airfield info file WaypointDetails::ReadFileFromProfile(way_points, operation); // Set the home waypoint WaypointGlue::SetHome(way_points, terrain, SetComputerSettings(), device_blackboard, false); // ReSynchronise the blackboards here since SetHome touches them device_blackboard->Merge(); ReadBlackboardBasic(device_blackboard->Basic()); // Scan for weather forecast LogStartUp(_T("RASP load")); RASP.ScanAll(Basic().location, operation); // Reads the airspace files ReadAirspace(airspace_database, terrain, GetComputerSettings().pressure, operation); { const AircraftState aircraft_state = ToAircraftState(device_blackboard->Basic(), device_blackboard->Calculated()); ProtectedAirspaceWarningManager::ExclusiveLease lease(glide_computer->GetAirspaceWarnings()); lease->Reset(aircraft_state); lease->SetConfig(CommonInterface::GetComputerSettings().airspace.warnings); } #ifdef HAVE_NET noaa_store = new NOAAStore(); noaa_store->LoadFromProfile(); #endif AudioVarioGlue::Initialise(); AudioVarioGlue::Configure(GetComputerSettings().sound); // Start the device thread(s) operation.SetText(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data LogStartUp(_T("GlidePolar::UpdatePolar")); GlidePolar::UpdatePolar(true, GetComputerSettings()); This should be done inside devStartup if it is really required */ operation.SetText(_("Initialising display")); GlueMapWindow *map_window = main_window.GetMap(); if (map_window != NULL) { map_window->SetWaypoints(&way_points); map_window->SetTask(protected_task_manager); map_window->SetRoutePlanner(&glide_computer->GetProtectedRoutePlanner()); map_window->SetGlideComputer(glide_computer); map_window->SetAirspaces(&airspace_database); map_window->SetTopography(topography); map_window->SetTerrain(terrain); map_window->SetWeather(&RASP); map_window->SetMarks(protected_marks); map_window->SetLogger(&logger); /* show map at home waypoint until GPS fix becomes available */ if (GetComputerSettings().poi.home_location_available) map_window->SetLocation(GetComputerSettings().poi.home_location); } // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL LogStartUp(_T("CreateDrawingThread")); draw_thread = new DrawThread(*map_window); draw_thread->Start(true); #endif // Show the infoboxes LogStartUp(_T("ShowInfoBoxes")); InfoBoxManager::Show(); // Create the calculation thread LogStartUp(_T("CreateCalculationThread")); CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); glide_computer_events.Reset(); GetLiveBlackboard().AddListener(glide_computer_events); if (CommonInterface::GetComputerSettings().logger.enable_flight_logger) { flight_logger = new GlueFlightLogger(GetLiveBlackboard()); LocalPath(path, _T("flights.log")); flight_logger->SetPath(path); } if (CommonInterface::GetComputerSettings().logger.enable_nmea_logger) NMEALogger::enabled = true; LogStartUp(_T("ProgramStarted")); // Give focus to the map main_window.SetDefaultFocus(); Pages::Initialise(GetUISettings().pages); // Start calculation thread merge_thread->Start(); calculation_thread->Start(); #ifdef HAVE_TRACKING tracking = new TrackingGlue(); tracking->SetSettings(GetComputerSettings().tracking); #endif globalRunningEvent.Signal(); AfterStartup(); operation.Hide(); main_window.ResumeThreads(); return true; }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool XCSoarInterface::Startup(HINSTANCE hInstance) { // Set the application title to "XCSoar" TCHAR szTitle[] = _T("XCSoar"); // Store instance handle in our global variable #ifdef WIN32 ResourceLoader::Init(hInstance); #endif //If "XCSoar" is already running, stop this instance if (MainWindow::find(szTitle)) return false; // Register window classes PaintWindow::register_class(hInstance); MainWindow::register_class(hInstance); // Creates the main window LogStartUp(_T("Create main window")); PixelRect WindowSize = SystemWindowSize(); main_window.set(szTitle, WindowSize.left, WindowSize.top, WindowSize.right, WindowSize.bottom); if (!main_window.defined()) return false; main_window.Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif if (!LoadProfile()) return false; ProgressGlue::Create(_("Initialising")); LoadDisplayOrientation(); main_window.InitialiseConfigured(); TCHAR path[MAX_PATH]; LocalPath(path, _T("cache")); file_cache = new FileCache(path); Graphics::InitialiseConfigured(SettingsMap()); ReadLanguageFile(); status_messages.LoadFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard.Initialise(); // Initialize Marks marks = new Marks(); // Send the SettingsMap to the DeviceBlackboard SendSettingsMap(); // Show the main and map windows LogStartUp(_T("Create map window")); main_window.show(); main_window.map.show(); #ifdef HAVE_AYGSHELL_DLL const AYGShellDLL &ayg = main_window.ayg_shell_dll; ayg.SHSetAppKeyWndAssoc(VK_APP1, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP2, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP3, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP4, main_window); // Typical Record Button // Why you can't always get this to work // http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm // To do with the fact it is a global hotkey, but you can with code above // Also APPA is record key on some systems ayg.SHSetAppKeyWndAssoc(VK_APP5, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP6, main_window); #endif // Initialize main blackboard data task_manager = new TaskManager(task_events, way_points); task_manager->reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, XCSoarInterface::SettingsComputer(), task_events, airspace_database); airspace_warning = new AirspaceWarningManager(airspace_database, *task_manager); airspace_warnings = new ProtectedAirspaceWarningManager(*airspace_warning); // Read the terrain file ProgressGlue::Create(_("Loading Terrain File...")); LogStartUp(_T("OpenTerrain")); terrain = RasterTerrain::OpenTerrain(file_cache); glide_computer = new GlideComputer(way_points, *protected_task_manager, *airspace_warnings, task_events); glide_computer->set_terrain(terrain); glide_computer->SetLogger(&logger); glide_computer->Initialise(); replay = new Replay(*protected_task_manager); // Load the EGM96 geoid data OpenGeoid(); GlidePolar &gp = SetSettingsComputer().glide_polar_task; gp = GlidePolar(fixed_zero); PolarGlue::LoadFromProfile(gp, SetSettingsComputer()); task_manager->set_glide_polar(gp); task_manager->set_contest(SettingsComputer().contest); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography); // Read the waypoint files WayPointGlue::LoadWaypoints(way_points, terrain); // Read and parse the airfield info file ReadAirfieldFile(way_points); // Set the home waypoint WayPointGlue::SetHome(way_points, terrain, SetSettingsComputer(), false); // ReSynchronise the blackboards here since SetHome touches them ReadBlackboardBasic(device_blackboard.Basic()); // Scan for weather forecast ProgressGlue::Create(_("Scanning weather forecast")); LogStartUp(_T("RASP load")); RASP.ScanAll(Basic().Location); // Reads the airspace files ReadAirspace(airspace_database, terrain, SettingsComputer().pressure); const AIRCRAFT_STATE aircraft_state = ToAircraftState(device_blackboard.Basic(), device_blackboard.Calculated()); airspace_warning->reset(aircraft_state); airspace_warning->set_config(CommonInterface::SettingsComputer().airspace.warnings); // Read the FLARM details file FlarmDetails::Load(); #ifndef DISABLEAUDIOVARIO /* VarioSound_Init(); VarioSound_EnableSound(EnableSoundVario); VarioSound_SetVdead(SoundDeadband); VarioSound_SetV(0); VarioSound_SetSoundVolume(SoundVolume); */ #endif // Start the device thread(s) ProgressGlue::Create(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data LogStartUp(_T("GlidePolar::UpdatePolar")); GlidePolar::UpdatePolar(true, SettingsComputer()); This should be done inside devStartup if it is really required */ ProgressGlue::Create(_("Initialising display")); main_window.map.set_way_points(&way_points); main_window.map.set_task(protected_task_manager); main_window.map.set_airspaces(&airspace_database, airspace_warnings); main_window.map.set_topography(topography); main_window.map.set_terrain(terrain); main_window.map.set_weather(&RASP); main_window.map.set_marks(marks); main_window.map.SetLogger(&logger); // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL LogStartUp(_T("CreateDrawingThread")); draw_thread = new DrawThread(main_window.map, main_window.flarm, main_window.ta); draw_thread->start(); #endif // Show the infoboxes LogStartUp(_T("ShowInfoBoxes")); InfoBoxManager::Show(); // Create the calculation thread LogStartUp(_T("CreateCalculationThread")); CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); LogStartUp(_T("ProgramStarted")); // Give focus to the map main_window.map.set_focus(); Pages::LoadFromProfile(); // Start calculation thread calculation_thread->start(); globalRunningEvent.trigger(); AfterStartup(); #ifndef ENABLE_OPENGL draw_thread->resume(); #endif return true; }
void dlgWayPointDetailsShowModal(SingleWindow &parent, const Waypoint& way_point) { selected_waypoint = &way_point; TCHAR sTmp[128]; double sunsettime; int sunsethours; int sunsetmins; WndProperty *wp; if (Layout::landscape) wf = LoadDialog(CallBackTable, parent, _T("IDR_XML_WAYPOINTDETAILS_L")); else wf = LoadDialog(CallBackTable, parent, _T("IDR_XML_WAYPOINTDETAILS")); nTextLines = 0; if (!wf) return; Profile::GetPath(szProfileWayPointFile, szWaypointFile); ExtractDirectory(Directory, szWaypointFile); _stprintf(path_modis, _T("%s" DIR_SEPARATOR_S "modis-%03d.jpg"), Directory, selected_waypoint->id+1); _stprintf(path_google,_T("%s" DIR_SEPARATOR_S "google-%03d.jpg"), Directory, selected_waypoint->id+1); _stprintf(sTmp, _T("%s: '%s'"), wf->GetCaption(), selected_waypoint->Name.c_str()); wf->SetCaption(sTmp); wp = ((WndProperty *)wf->FindByName(_T("prpWpComment"))); wp->SetText(selected_waypoint->Comment.c_str()); Units::LongitudeToString(selected_waypoint->Location.Longitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpLongitude"))) ->SetText(sTmp); Units::LatitudeToString(selected_waypoint->Location.Latitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpLatitude"))) ->SetText(sTmp); Units::FormatUserAltitude(selected_waypoint->Altitude, sTmp, sizeof(sTmp)-1); ((WndProperty *)wf->FindByName(_T("prpAltitude"))) ->SetText(sTmp); SunEphemeris sun; sunsettime = sun.CalcSunTimes (selected_waypoint->Location, XCSoarInterface::Basic().DateTime, GetUTCOffset()/3600); sunsethours = (int)sunsettime; sunsetmins = (int)((sunsettime - sunsethours) * 60); _stprintf(sTmp, _T("%02d:%02d"), sunsethours, sunsetmins); ((WndProperty *)wf->FindByName(_T("prpSunset")))->SetText(sTmp); fixed distance; Angle bearing; DistanceBearing(XCSoarInterface::Basic().Location, selected_waypoint->Location, &distance, &bearing); TCHAR DistanceText[MAX_PATH]; Units::FormatUserDistance(distance, DistanceText, 10); ((WndProperty *)wf->FindByName(_T("prpDistance"))) ->SetText(DistanceText); _stprintf(sTmp, _T("%d")_T(DEG), iround(bearing.value_degrees())); ((WndProperty *)wf->FindByName(_T("prpBearing"))) ->SetText(sTmp); GlidePolar glide_polar = protected_task_manager.get_glide_polar(); GlidePolar safety_polar = protected_task_manager.get_safety_polar(); UnorderedTaskPoint t(way_point, XCSoarInterface::SettingsComputer()); GlideResult r; // alt reqd at current mc const AIRCRAFT_STATE aircraft_state = ToAircraftState(XCSoarInterface::Basic()); r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc2")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } // alt reqd at mc 0 glide_polar.set_mc(fixed_zero); r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc0")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } // alt reqd at safety mc r = TaskSolution::glide_solution_remaining(t, aircraft_state, safety_polar); wp = (WndProperty *)wf->FindByName(_T("prpMc1")); if (wp) { _stprintf(sTmp, _T("%.0f %s"), (double)Units::ToUserAltitude(r.AltitudeDifference), Units::GetAltitudeName()); wp->SetText(sTmp); } wf->SetKeyDownNotify(FormKeyDown); ((WndButton *)wf->FindByName(_T("cmdClose")))->SetOnClickNotify(OnCloseClicked); wInfo = ((WndFrame *)wf->FindByName(_T("frmInfos"))); wCommand = ((WndFrame *)wf->FindByName(_T("frmCommands"))); wSpecial = ((WndFrame *)wf->FindByName(_T("frmSpecial"))); wImage = ((WndOwnerDrawFrame *)wf->FindByName(_T("frmImage"))); wDetails = (WndListFrame*)wf->FindByName(_T("frmDetails")); wDetails->SetPaintItemCallback(OnPaintDetailsListItem); assert(wInfo != NULL); assert(wCommand != NULL); assert(wSpecial != NULL); assert(wImage != NULL); assert(wDetails != NULL); nTextLines = TextToLineOffsets(way_point.Details.c_str(), LineOffsets, MAXLINES); wDetails->SetLength(nTextLines); /* TODO enhancement: wpdetails wp = ((WndProperty *)wf->FindByName(_T("prpWpDetails"))); wp->SetText(way_point.Details); */ wCommand->hide(); wSpecial->hide(); wImage->SetCaption(_("Blank!")); wImage->SetOnPaintNotify(OnImagePaint); WndButton *wb; wb = ((WndButton *)wf->FindByName(_T("cmdGoto"))); if (wb) wb->SetOnClickNotify(OnGotoClicked); wb = ((WndButton *)wf->FindByName(_T("cmdReplace"))); if (wb) wb->SetOnClickNotify(OnReplaceClicked); wb = ((WndButton *)wf->FindByName(_T("cmdNewHome"))); if (wb) wb->SetOnClickNotify(OnNewHomeClicked); wb = ((WndButton *)wf->FindByName(_T("cmdSetAlternate1"))); if (wb) wb->SetOnClickNotify(OnSetAlternate1Clicked); wb = ((WndButton *)wf->FindByName(_T("cmdSetAlternate2"))); if (wb) wb->SetOnClickNotify(OnSetAlternate2Clicked); wb = ((WndButton *)wf->FindByName(_T("cmdClearAlternates"))); if (wb) wb->SetOnClickNotify(OnClearAlternatesClicked); wb = ((WndButton *)wf->FindByName(_T("cmdTeamCode"))); if (wb) wb->SetOnClickNotify(OnTeamCodeClicked); wb = ((WndButton *)wf->FindByName(_T("cmdInserInTask"))); if (wb) wb->SetOnClickNotify(OnInsertInTaskClicked); wb = ((WndButton *)wf->FindByName(_T("cmdAppendInTask"))); if (wb) wb->SetOnClickNotify(OnAppendInTaskClicked); wb = ((WndButton *)wf->FindByName(_T("cmdRemoveFromTask"))); if (wb) wb->SetOnClickNotify(OnRemoveFromTaskClicked); hasimage1 = jpgimage1.load_file(path_modis); hasimage2 = jpgimage2.load_file(path_google); page = 0; NextPage(0); // JMW just to turn proper pages on/off wf->ShowModal(); delete wf; wf = NULL; }