static bool WaypointInTerrainRange(WAYPOINT *List, RasterTerrain &terrain) { if (WaypointOutOfTerrainRangeDontAskAgain == 1){ return(true); } if (!terrain.isTerrainLoaded()) { return(true); } if (terrain.WaypointIsInTerrainRange(List->Location)) { return true; } else { if (WaypointOutOfTerrainRangeDontAskAgain == 0){ TCHAR sTmp[250]; int res; _stprintf(sTmp, gettext(TEXT("Waypoint #%d \"%s\" \r\nout of Terrain bounds\r\n\r\nLoad anyway?")), List->Number, List->Name); res = dlgWaypointOutOfTerrain(sTmp); switch(res){ case wpTerrainBoundsYes: return true; case wpTerrainBoundsNo: return false; case wpTerrainBoundsYesAll: WaypointOutOfTerrainRangeDontAskAgain = 1; WaypointsOutOfRange = 1; SetToRegistry(szRegistryWaypointsOutOfRange, WaypointsOutOfRange); Profile::StoreRegistry(); return true; case mrCancel: case wpTerrainBoundsNoAll: WaypointOutOfTerrainRangeDontAskAgain = 2; WaypointsOutOfRange = 2; SetToRegistry(szRegistryWaypointsOutOfRange, WaypointsOutOfRange); Profile::StoreRegistry(); return false; } } else { if (WaypointOutOfTerrainRangeDontAskAgain == 2) return(false); if (WaypointOutOfTerrainRangeDontAskAgain == 1) return(true); } return false; } }
void AirspaceDatabase::UpdateAGL(const RasterTerrain &terrain) { const RasterMap *map = terrain.GetMap(); if (map == NULL) /* XXX: complain */ return; // want most accurate rounding here const RasterRounding rounding(*map, 0, 0); for (unsigned i = 0; i < NumberOfAirspaceAreas; i++) { AIRSPACE_AREA &area = AirspaceArea[i]; GEOPOINT center; center.Latitude = (area.maxBound.Latitude + area.minBound.Latitude) / 2; center.Longitude = (area.maxBound.Longitude + area.minBound.Longitude) / 2; ::UpdateAGL(AirspaceArea[i], center, terrain, rounding); } for (unsigned i = 0; i < NumberOfAirspaceCircles; i++) { AIRSPACE_CIRCLE &circle = AirspaceCircle[i]; ::UpdateAGL(circle, circle.Location, terrain, rounding); } }
static void GenerateBlackboard(MapWindow &map) { NMEA_INFO nmea_info; DERIVED_INFO derived_info; SETTINGS_COMPUTER settings_computer; memset(&nmea_info, 0, sizeof(nmea_info)); nmea_info.Connected = 2; nmea_info.SatellitesUsed = 4; nmea_info.Location.Latitude = 51.2; nmea_info.Location.Longitude = 7.7; nmea_info.TrackBearing = 90; nmea_info.Speed = 50; nmea_info.Altitude = 1500; memset(&derived_info, 0, sizeof(derived_info)); derived_info.TerrainValid = true; memset(&settings_computer, 0, sizeof(settings_computer)); terrain.ServiceFullReload(nmea_info.Location); for (unsigned i = 0; i <AIRSPACECLASSCOUNT; ++i) settings_computer.iAirspaceMode[i] = 3; map.ReadBlackboard(nmea_info, derived_info, settings_computer, blackboard.SettingsMap()); map.UpdateProjection(); }
static void LoadFiles() { topology = new TopologyStore(NULL); topology->Open(); terrain.OpenTerrain(); ReadWayPoints(way_points, &terrain); TCHAR tpath[MAX_PATH]; GetRegistryString(szRegistryAirspaceFile, tpath, MAX_PATH); if (tpath[0] != 0) { ExpandLocalPath(tpath); char path[MAX_PATH]; unicode2ascii(tpath, path, sizeof(path)); if (!ReadAirspace(airspace_database, path)) StartupStore(TEXT("No airspace file 1\n")); } FindAirspaceAreaBounds(airspace_database); FindAirspaceCircleBounds(airspace_database); }
void WaypointAltitudeFromTerrain(WAYPOINT* Temp, RasterTerrain &terrain) { double myalt = -1; if (terrain.GetMap()) { RasterRounding rounding(*terrain.GetMap(),0,0); myalt = terrain.GetTerrainHeight(Temp->Location, rounding); } if (myalt>0) { Temp->Altitude = myalt; } else { // error, can't find altitude for waypoint! } }
RasterTerrain * RasterTerrain::OpenTerrain(FileCache *cache, OperationEnvironment &operation) try { const auto path = Profile::GetPath(ProfileKeys::MapFile); if (path.IsNull()) return nullptr; RasterTerrain *rt = new RasterTerrain(ZipArchive(path)); if (!rt->Load(path, cache, operation)) { delete rt; return nullptr; } return rt; } catch (const std::runtime_error &e) { operation.SetErrorMessage(UTF8ToWideConverter(e.what())); return nullptr; }
void Airspaces::SetGroundLevels(const RasterTerrain &terrain) { for (auto v = airspace_tree.begin(); v != airspace_tree.end(); ++v) { FlatGeoPoint c_flat = v->GetCenter(); GeoPoint g = task_projection.unproject(c_flat); short h = terrain.GetTerrainHeight(g); if (!RasterBuffer::IsSpecial(h)) v->set_ground_level((fixed)h); } }
void Airspaces::SetGroundLevels(const RasterTerrain &terrain) { for (auto &v : airspace_tree) { // If we don't need the ground level we don't have to calculate it if (!v.NeedGroundLevel()) continue; FlatGeoPoint c_flat = v.GetCenter(); GeoPoint g = task_projection.Unproject(c_flat); short h = terrain.GetTerrainHeight(g); if (!RasterBuffer::IsSpecial(h)) v.SetGroundLevel((fixed)h); } }
static void UpdateAGL(AIRSPACE_ALT &altitude, const GEOPOINT &location, const RasterTerrain &terrain, const RasterRounding &rounding) { if (altitude.Base != abAGL) return; double terrain_height = terrain.GetTerrainHeight(location, rounding); if (altitude.AGL>=0) { altitude.Altitude = altitude.AGL + terrain_height; } else { // surface, set to zero altitude.AGL = 0; altitude.Altitude = 0; } }
void XCSoarInterface::Shutdown(void) { CreateProgressDialog(gettext(TEXT("Shutdown, please wait..."))); StartHourglassCursor(); StartupStore(TEXT("Entering shutdown...\n")); StartupLogFreeRamAndStorage(); // turn off all displays globalRunningEvent.reset(); StartupStore(TEXT("dlgAirspaceWarningDeInit\n")); dlgAirspaceWarningDeInit(); CreateProgressDialog(gettext(TEXT("Shutdown, saving logs..."))); // stop logger logger.guiStopLogger(Basic(),true); CreateProgressDialog(gettext(TEXT("Shutdown, saving profile..."))); // Save settings Profile::StoreRegistry(); // Stop sound StartupStore(TEXT("SaveSoundSettings\n")); Profile::SaveSoundSettings(); #ifndef DISABLEAUDIOVARIO // VarioSound_EnableSound(false); // VarioSound_Close(); #endif // Stop drawing CreateProgressDialog(gettext(TEXT("Shutdown, please wait..."))); StartupStore(TEXT("CloseDrawingThread\n")); closeTriggerEvent.trigger(); calculation_thread->join(); StartupStore(TEXT("- calculation thread returned\n")); instrument_thread->join(); StartupStore(TEXT("- instrument thread returned\n")); draw_thread->join(); StartupStore(TEXT("- draw thread returned\n")); delete draw_thread; // Clear data CreateProgressDialog(gettext(TEXT("Shutdown, saving task..."))); StartupStore(TEXT("Resume abort task\n")); task.ResumeAbortTask(SettingsComputer(), -1); // turn off abort if it was on. StartupStore(TEXT("Save default task\n")); task.SaveDefaultTask(); StartupStore(TEXT("Clear task data\n")); task.ClearTask(); StartupStore(TEXT("Close airspace\n")); CloseAirspace(); StartupStore(TEXT("Close waypoints\n")); way_points.clear(); CreateProgressDialog(gettext(TEXT("Shutdown, please wait..."))); StartupStore(TEXT("CloseTerrainTopology\n")); RASP.Close(); terrain.CloseTerrain(); delete topology; delete marks; devShutdown(); SaveCalculationsPersist(Basic(),Calculated()); #if (EXPERIMENTAL > 0) // CalibrationSave(); #endif #if defined(GNAV) && !defined(PCGNAV) StartupStore(TEXT("Altair shutdown\n")); Sleep(2500); StopHourglassCursor(); InputEvents::eventDLLExecute(TEXT("altairplatform.dll SetShutdown 1")); while(1) { Sleep(100); // free time up for processor to perform shutdown } #endif CloseFLARMDetails(); // Kill windows StartupStore(TEXT("Destroy Info Boxes\n")); InfoBoxManager::Destroy(); StartupStore(TEXT("Destroy Button Labels\n")); ButtonLabel::Destroy(); StartupStore(TEXT("Delete Objects\n")); // Kill graphics objects DeleteFonts(); DeleteAirspace(); StartupStore(TEXT("Close Progress Dialog\n")); CloseProgressDialog(); CloseGeoid(); StartupStore(TEXT("Close Windows - main \n")); main_window.reset(); StartupStore(TEXT("Close Graphics\n")); MapGfx.Destroy(); #ifdef DEBUG_TRANSLATIONS StartupStore(TEXT("Writing missing translations\n")); WriteMissingTranslations(); #endif StartupLogFreeRamAndStorage(); StartupStore(TEXT("Finished shutdown\n")); StopHourglassCursor(); }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool XCSoarInterface::Startup(HINSTANCE hInstance, LPTSTR lpCmdLine) { // The title bar text TCHAR szTitle[MAX_LOADSTRING]; // Store instance handle in our global variable hInst = hInstance; // IDS_APP_TITLE = XCSoar (see XCSoar.rc) LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); //If it is already running, then focus on the window if (MainWindow::find(szTitle)) return false; // Send the SettingsMap to the DeviceBlackboard SendSettingsMap(); // Register window classes PaintWindow::register_class(hInst); MainWindow::register_class(hInst); MapWindow::register_class(hInst); // Fill the fast(co)sine table InitSineTable(); PreloadInitialisation(true); // Send the SettingsMap to the DeviceBlackboard SendSettingsMap(); // Creates the main window StartupStore(TEXT("Create main window\n")); RECT WindowSize = SystemWindowSize(); main_window.set(szTitle, WindowSize.left, WindowSize.top, WindowSize.right, WindowSize.bottom); if (!main_window.defined()) { return false; } main_window.install_timer(); // Initialize DeviceBlackboard device_blackboard.Initialise(); // Initialize Marks marks = new Marks("xcsoar-marks"); topology = new TopologyStore(marks->GetTopology()); // Show the main and map windows StartupStore(TEXT("Create map window\n")); main_window.show(); main_window.map.show(); #ifdef HAVE_ACTIVATE_INFO SHSetAppKeyWndAssoc(VK_APP1, main_window); SHSetAppKeyWndAssoc(VK_APP2, main_window); SHSetAppKeyWndAssoc(VK_APP3, main_window); 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 SHSetAppKeyWndAssoc(VK_APP5, main_window); SHSetAppKeyWndAssoc(VK_APP6, main_window); #endif // Initialize main blackboard data task.ClearTask(); glide_computer.Initialise(); logger.LinkGRecordDLL(); // try to link DLL if it exists // Load the EGM96 geoid data OpenGeoid(); PreloadInitialisation(false); Profile::LoadWindFromRegistry(); // TODO TB: seems to be out of date?! CalculateNewPolarCoef(); // Calculate polar-related data and saves it to the cache StartupStore(TEXT("GlidePolar::UpdatePolar\n")); GlidePolar::UpdatePolar(false, SettingsComputer()); // Show startup info depending on device StartupInfo(); // Read the topology file(s) topology->Open(); // Read the terrain file terrain.OpenTerrain(); // Read the waypoint files ReadWayPoints(way_points, terrain); // Read and parse the airfield info file ReadAirfieldFile(); // Set the home waypoint SetHome(way_points, terrain, SetSettingsComputer(), false, true); // ReSynchronise the blackboards here since SetHome touches them ReadBlackboardBasic(device_blackboard.Basic()); terrain.ServiceFullReload(Basic().Location); // Scan for weather forecast CreateProgressDialog(gettext(TEXT("Scanning weather forecast"))); StartupStore(TEXT("RASP load\n")); RASP.ScanAll(Basic().Location); // Reads the airspace files ReadAirspace(); // Sorts the airspaces by priority SortAirspace(); // Read the FLARM details file OpenFLARMDetails(); #ifndef DISABLEAUDIOVARIO /* VarioSound_Init(); VarioSound_EnableSound(EnableSoundVario); VarioSound_SetVdead(SoundDeadband); VarioSound_SetV(0); VarioSound_SetSoundVolume(SoundVolume); */ #endif // Start the device thread(s) CreateProgressDialog(gettext(TEXT("Starting devices"))); devStartup(lpCmdLine); // Reset polar in case devices need the data StartupStore(TEXT("GlidePolar::UpdatePolar\n")); GlidePolar::UpdatePolar(true, SettingsComputer()); CreateProgressDialog(gettext(TEXT("Initialising display"))); // Finally ready to go.. all structures must be present before this. // Create the drawing thread StartupStore(TEXT("CreateDrawingThread\n")); draw_thread = new DrawThread(main_window.map, main_window.flarm); draw_thread->start(); // Show the infoboxes StartupStore(TEXT("ShowInfoBoxes\n")); InfoBoxManager::Show(); // Create the calculation thread StartupStore(TEXT("CreateCalculationThread\n")); CreateCalculationThread(); #ifdef NEWTASK { // NEWTASK PeriodClock t; t.reset(); t.update(); CreateProgressDialog(gettext(TEXT("Running test 0"))); test_newtask(0); StartupStore(TEXT("test 0 %d\n"),t.elapsed()); /* t.update(); CreateProgressDialog(gettext(TEXT("Running test 1"))); test_newtask(1); StartupStore(TEXT("test 1 %d\n"),t.elapsed()); t.update(); CreateProgressDialog(gettext(TEXT("Running test 2"))); test_newtask(2); StartupStore(TEXT("test 2 %d\n"),t.elapsed()); t.update(); CreateProgressDialog(gettext(TEXT("Running test 3"))); test_newtask(3); StartupStore(TEXT("test 3 %d\n"),t.elapsed()); t.update(); CreateProgressDialog(gettext(TEXT("Running test 4"))); test_newtask(4); StartupStore(TEXT("test 4 %d\n"),t.elapsed()); */ CreateProgressDialog(gettext(TEXT("test complete"))); } #endif // Initialise the airspace warning dialog StartupStore(TEXT("dlgAirspaceWarningInit\n")); dlgAirspaceWarningInit(); // Find unique ID of this PDA ReadAssetNumber(); StartupStore(TEXT("ProgramStarted\n")); // Give focus to the map main_window.map.set_focus(); // Start calculation thread calculation_thread->start(); // Start instrument thread instrument_thread->start(); globalRunningEvent.trigger(); return true; }
void SetHome(const WayPointList &way_points, RasterTerrain &terrain, SETTINGS_COMPUTER &settings, const bool reset, const bool set_location) { StartupStore(TEXT("SetHome\n")); // check invalid home waypoint or forced reset due to file change // VENTA3 if (reset || !way_points.verify_index(0) || !way_points.verify_index(settings.HomeWaypoint)) { settings.HomeWaypoint = -1; } // VENTA3 -- reset Alternates if (reset || !way_points.verify_index(settings.Alternate1) || !way_points.verify_index(settings.Alternate2)) { settings.Alternate1= -1; settings.Alternate2= -1; } // check invalid task ref waypoint or forced reset due to file change if (reset || !way_points.verify_index(settings.TeamCodeRefWaypoint)) { settings.TeamCodeRefWaypoint = -1; } if (!way_points.verify_index(settings.HomeWaypoint)) { // search for home in waypoint list, if we don't have a home settings.HomeWaypoint = -1; for (unsigned i = 0; way_points.verify_index(i); ++i) { if ((way_points.get(i).Flags & HOME) == HOME) { if (settings.HomeWaypoint== -1) { settings.HomeWaypoint = i; break; // only search for one } } } } // set team code reference waypoint if we don't have one if (settings.TeamCodeRefWaypoint== -1) { settings.TeamCodeRefWaypoint = settings.HomeWaypoint; } if (set_location) { if (way_points.verify_index(settings.HomeWaypoint)) { // OK, passed all checks now StartupStore(TEXT("Start at home waypoint\n")); const WAYPOINT &home = way_points.get(settings.HomeWaypoint); device_blackboard.SetStartupLocation(home.Location, home.Altitude); } else { // no home at all, so set it from center of terrain if available GEOPOINT loc; if (terrain.GetTerrainCenter(&loc)) { StartupStore(TEXT("Start at terrain center\n")); device_blackboard.SetStartupLocation(loc, 0); } } } // // Save the home waypoint number in the resgistry // // VENTA3> this is probably useless, since HomeWayPoint &c were currently // just loaded from registry. SetToRegistry(szRegistryHomeWaypoint,settings.HomeWaypoint); SetToRegistry(szRegistryAlternate1,settings.Alternate1); SetToRegistry(szRegistryAlternate2,settings.Alternate2); SetToRegistry(szRegistryTeamcodeRefWaypoint,settings.TeamCodeRefWaypoint); }
double FinalGlideThroughTerrain(const double this_bearing, const NMEA_INFO &basic, const DERIVED_INFO &calculated, const SETTINGS_COMPUTER &settings, const RasterTerrain &terrain, GEOPOINT *retloc, const double max_range, bool *out_of_range, double *TerrainBase) { double mc = GlidePolar::GetMacCready(); double irange = GlidePolar::MacCreadyAltitude(mc, 1.0, this_bearing, calculated.WindSpeed, calculated.WindBearing, 0, 0, true, 0); const GEOPOINT start_loc = basic.Location; if (retloc) { *retloc = start_loc; } *out_of_range = false; if (irange <= 0.0 || calculated.NavAltitude <= 0) // can't make progress in this direction at the current windspeed/mc return 0; const RasterMap *map = terrain.GetMap(); if (map == NULL) return 0; const double glide_max_range = calculated.NavAltitude/irange; // returns distance one would arrive at altitude in straight glide // first estimate max range at this altitude GEOPOINT loc, last_loc; double h=0.0, dh=0.0; // int imax=0; double last_dh=0; double altitude; double retval = 0; int i=0; bool start_under = false; // calculate terrain rounding factor FindLatitudeLongitude(start_loc, 0, glide_max_range/NUMFINALGLIDETERRAIN, &loc); double Xrounding = fabs(loc.Longitude-start_loc.Longitude)/2; double Yrounding = fabs(loc.Latitude-start_loc.Latitude)/2; const RasterRounding rounding(*map, Xrounding, Yrounding); loc = last_loc = start_loc; altitude = calculated.NavAltitude; h = max(0, terrain.GetTerrainHeight(loc,rounding)); dh = altitude - h - settings.SafetyAltitudeTerrain; last_dh = dh; if (dh<0) { start_under = true; // already below safety terrain height // retval = 0; // goto OnExit; } // find grid GEOPOINT dloc; FindLatitudeLongitude(loc, this_bearing, glide_max_range, &dloc); dloc.Latitude -= start_loc.Latitude; dloc.Longitude -= start_loc.Longitude; double f_scale = 1.0/NUMFINALGLIDETERRAIN; if ((max_range>0) && (max_range<glide_max_range)) { f_scale *= max_range/glide_max_range; } double delta_alt = -f_scale * calculated.NavAltitude; dloc.Latitude *= f_scale; dloc.Longitude *= f_scale; for (i=1; i<=NUMFINALGLIDETERRAIN; i++) { double f; bool solution_found = false; double fi = i*f_scale; // fraction of glide_max_range if ((max_range>0)&&(fi>=1.0)) { // early exit *out_of_range = true; return max_range; } if (start_under) { altitude += 2.0*delta_alt; } else { altitude += delta_alt; } // find lat, lon of point of interest loc.Latitude += dloc.Latitude; loc.Longitude += dloc.Longitude; // find height over terrain h = max(0,terrain.GetTerrainHeight(loc, rounding)); dh = altitude - h - settings.SafetyAltitudeTerrain; if (TerrainBase && (dh>0) && (h>0)) { *TerrainBase = min(*TerrainBase, h); } if (start_under) { if (dh>last_dh) { // better solution found, ok to continue... if (dh>0) { // we've now found a terrain point above safety altitude, // so consider rest of track to search for safety altitude start_under = false; } } else { f= 0.0; solution_found = true; } } else if (dh<=0) { if ((dh<last_dh) && (last_dh>0)) { f = max(0,min(1,(-last_dh)/(dh-last_dh))); } else { f = 0.0; } solution_found = true; } if (solution_found) { loc.Latitude = last_loc.Latitude*(1.0-f)+loc.Latitude*f; loc.Longitude = last_loc.Longitude*(1.0-f)+loc.Longitude*f; if (retloc) { *retloc = loc; } return Distance(start_loc, loc); } last_dh = dh; last_loc = loc; } *out_of_range = true; retval = glide_max_range; return retval; }
short WayPointFile::AltitudeFromTerrain(GeoPoint &location, const RasterTerrain &terrain) { return terrain.GetTerrainHeight(location); }