protected override void OnDoWork(DoWorkEventArgs e) { // get all parameters BACKGROUNDUPDATERSTARTOPTIONS Options = (BACKGROUNDUPDATERSTARTOPTIONS)e.Argument; // get update interval int interval = (int)Properties.Settings.Default.Background_Update_Period * 60; do { if (Properties.Settings.Default.Background_Calculations_Enable) { // get all parameters // set name and stepwidth according to model switch (Model) { case ELEVATIONMODEL.GLOBE: Name = "GLOBE"; StepWidth = ElevationData.Database.GetDefaultStepWidth(ELEVATIONMODEL.GLOBE); break; case ELEVATIONMODEL.SRTM3: Name = "SRTM3"; StepWidth = ElevationData.Database.GetDefaultStepWidth(ELEVATIONMODEL.SRTM3); break; case ELEVATIONMODEL.SRTM1: Name = "SRTM1"; StepWidth = ElevationData.Database.GetDefaultStepWidth(ELEVATIONMODEL.SRTM1); break; } // name the thread for debugging if (String.IsNullOrEmpty(Thread.CurrentThread.Name)) { Thread.CurrentThread.Name = Name + "_" + this.GetType().Name; } this.ReportProgress(0, Name + " started."); try { // iterate through all locations in the database and calculate the propagation path // chek if databases are ready and changes reported first while (!ElevationData.Database.GetDBStatusBit(Model, DATABASESTATUS.UPTODATE) || !StationData.Database.GetDBStatusBit(DATABASESTATUS.UPTODATE) || !HasDatabaseChanged()) { // sleep 10 sec int i = 0; while (!this.CancellationPending && (i < 10)) { Thread.Sleep(1000); i++; if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } this.ReportProgress(0, Name + " getting locations..."); // get all locations in covered area but don't report progress this.WorkerReportsProgress = false; List <LocationDesignator> lds = StationData.Database.LocationGetAll(this, Properties.Settings.Default.MinLat, Properties.Settings.Default.MinLon, Properties.Settings.Default.MaxLat, Properties.Settings.Default.MaxLon); this.WorkerReportsProgress = true; // start over again with main loog when lds = null for some reason if (lds == null) { continue; } // iterate through locations QRVDesignator myqrv = null; QRVDesignator dxqrv = null; this.ReportProgress(0, Name + " checking locations..."); foreach (LocationDesignator ld in lds) { Stopwatch st = new Stopwatch(); st.Start(); try { // leave the iteration when something went wrong --> start new if (ld == null) { break; } // check lat/lon if valid if (!GeographicalPoint.Check(Properties.Settings.Default.MyLat, Properties.Settings.Default.MyLon)) { continue; } // check lat/lon if valid if (!GeographicalPoint.Check(ld.Lat, ld.Lon)) { continue; } // chek for path < MaxDistance double dist = LatLon.Distance(Properties.Settings.Default.MyLat, Properties.Settings.Default.MyLon, ld.Lat, ld.Lon); if (dist <= Properties.Settings.Default.Path_MaxLength) { // start calculation for each band foreach (BAND band in Bands.GetValuesExceptNoneAndAll()) { PropagationPathDesignator pp; // get my lat/lon from settings string mycall = Properties.Settings.Default.MyCall; double mylat = Properties.Settings.Default.MyLat; double mylon = Properties.Settings.Default.MyLon; string myloc = MaidenheadLocator.LocFromLatLon(mylat, mylon, false, 3); double myelv = ElevationData.Database[mylat, mylon, Model]; // modify location in case of best case elevation is selected --> but do not store in database or settings! if (Properties.Settings.Default.Path_BestCaseElevation) { if (!MaidenheadLocator.IsPrecise(mylat, mylon, 3)) { ElvMinMaxInfo maxinfo = ElevationData.Database.ElevationTileFindMinMaxInfo(myloc, Model); if (maxinfo != null) { mylat = maxinfo.MaxLat; mylon = maxinfo.MaxLon; myelv = maxinfo.MaxElv; } } } myqrv = StationData.Database.QRVFind(mycall, myloc, band); double myheight = ((myqrv != null) && (myqrv.AntennaHeight != 0)) ? myqrv.AntennaHeight : StationData.Database.QRVGetDefaultAntennaHeight(band); string dxcall = ld.Call; // get my lat/lon from settings double dxlat = ld.Lat; double dxlon = ld.Lon; string dxloc = MaidenheadLocator.LocFromLatLon(dxlat, dxlon, false, 3); double dxelv = ElevationData.Database[dxlat, dxlon, Model]; // modify location in case of best case elevation is selected --> but do not store in database or settings! if (Properties.Settings.Default.Path_BestCaseElevation) { if (!MaidenheadLocator.IsPrecise(dxlat, dxlon, 3)) { ElvMinMaxInfo maxinfo = ElevationData.Database.ElevationTileFindMinMaxInfo(dxloc, Model); if (maxinfo != null) { dxlat = maxinfo.MaxLat; dxlon = maxinfo.MaxLon; dxelv = maxinfo.MaxElv; } } } dxqrv = StationData.Database.QRVFind(dxcall, dxloc, band); double dxheight = ((dxqrv != null) && (dxqrv.AntennaHeight != 0)) ? dxqrv.AntennaHeight : StationData.Database.QRVGetDefaultAntennaHeight(band); LocalObstructionDesignator o = ElevationData.Database.LocalObstructionFind(mylat, mylon, Model); double myobstr = (o != null) ? o.GetObstruction(myheight, LatLon.Bearing(mylat, mylon, dxlat, dxlon)) : double.MinValue; pp = PropagationData.Database.PropagationPathFind( mylat, mylon, myelv + myheight, dxlat, dxlon, dxelv + dxheight, Bands.ToGHz(band), LatLon.Earth.Radius * Properties.Settings.Default.Path_Band_Settings[band].K_Factor, Properties.Settings.Default.Path_Band_Settings[band].F1_Clearance, ElevationData.Database.GetDefaultStepWidth(Model), Model, myobstr); // skip if path already in database if (pp != null) { Thread.Sleep(Properties.Settings.Default.Background_Calculations_ThreadWait); continue; } // create new propagation path pp = PropagationData.Database.PropagationPathCreateFromLatLon( this, mylat, mylon, myelv + myheight, dxlat, dxlon, dxelv + dxheight, Bands.ToGHz(band), LatLon.Earth.Radius * Properties.Settings.Default.Path_Band_Settings[band].K_Factor, Properties.Settings.Default.Path_Band_Settings[band].F1_Clearance, ElevationData.Database.GetDefaultStepWidth(Model), Model, myobstr); st.Stop(); this.ReportProgress(0, Name + " calculating path[ " + Bands.GetStringValue(band) + "]: " + Properties.Settings.Default.MyCall + "<>" + ld.Call + ", " + st.ElapsedMilliseconds.ToString() + " ms."); } if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } } catch (Exception ex) { Log.WriteMessage(Name + " error processing call [" + ld.Call + "]: " + ex.ToString()); } // keep cpu load low --> TODO: find better solution here Thread.Sleep(10); } // save station database timestamp SaveDatabaseTimeStamp(); // wait to keep cpu load low Thread.Sleep(Properties.Settings.Default.Background_Calculations_ThreadWait); this.ReportProgress(0, Name + " finished."); } catch (Exception ex) { Log.WriteMessage(ex.ToString(), LogLevel.Error); } } // sleep when running periodically if (Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY) { int i = 0; while (!this.CancellationPending && (i < interval)) { Thread.Sleep(1000); i++; } } }while (Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY); if (this.CancellationPending) { this.ReportProgress(0, Name + " cancelled."); Log.WriteMessage(Name + " cancelled."); } else { this.ReportProgress(0, Name + " finished."); Log.WriteMessage(Name + " finished."); } }
protected override void OnDoWork(DoWorkEventArgs e) { BACKGROUNDUPDATERSTARTOPTIONS Options = (BACKGROUNDUPDATERSTARTOPTIONS)e.Argument; // name the thread for debugging if (String.IsNullOrEmpty(Thread.CurrentThread.Name)) { Thread.CurrentThread.Name = this.Name + "_" + this.GetType().Name; } this.ReportProgress(0, this.Name + " started."); Log.WriteMessage(this.Name + " started."); // get update interval int interval = (int)Properties.Settings.Default.Background_Update_Period * 60; // get mpst simple elevation model if (Properties.Settings.Default.Elevation_GLOBE_Enabled) { Model = ELEVATIONMODEL.GLOBE; } else if (Properties.Settings.Default.Elevation_SRTM3_Enabled) { Model = ELEVATIONMODEL.SRTM3; } else if (Properties.Settings.Default.Elevation_SRTM1_Enabled) { Model = ELEVATIONMODEL.SRTM1; } // return if no elevation model selected if (Model == ELEVATIONMODEL.NONE) { return; } // setting User Agent to fix Open Street Map issue 2016-09-20 GMap.NET.MapProviders.GMapProvider.UserAgent = "AirScout"; // clearing referrer URL issue 2019-12-14 gm_Map.MapProvider.RefererUrl = ""; // set initial settings for main map gm_Map.MapProvider = GMapProviders.Find(Properties.Settings.Default.Map_Provider); gm_Map.MinZoom = 0; gm_Map.MaxZoom = 20; // get database filename int i = 0; int count = 0; int total = 0; do { i = 0; count = 0; total = 0; // checks if elevation database is complete try { this.ReportProgress(0, this.Name + " getting tiles from database."); int zmin = 5; int zmax = 11; List <MapPreloaderTile> l = new List <MapPreloaderTile>(); for (int z = zmin; z <= zmax; z++) { int xmin = long2tilex(Properties.Settings.Default.MinLon, z); int xmax = long2tilex(Properties.Settings.Default.MaxLon, z); int ymin = lat2tiley(Properties.Settings.Default.MaxLat, z); int ymax = lat2tiley(Properties.Settings.Default.MinLat, z); for (int x = xmin; x <= xmax; x++) { for (int y = ymin; y <= ymax; y++) { // check if tile already in database --> add it to list to get it from the web if (!MapData.Database.TileExists(x, y, z, gm_Map.MapProvider.DbId)) { MapPreloaderTile t = new MapPreloaderTile(x, y, z, gm_Map.MapProvider.DbId); l.Add(t); } total++; if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } count = l.Count(); Random rng = new Random(); // shuffle the list int n = l.Count; while (n > 1) { n--; int k = rng.Next(n + 1); MapPreloaderTile value = l[k]; l[k] = l[n]; l[n] = value; } n = 0; foreach (MapPreloaderTile t in l) { Exception ex = null; this.ReportProgress(0, "Preloading " + "/" + t.Z.ToString() + "/" + t.X.ToString() + "/" + t.Y.ToString() + ".png"); try { // try to donwload from www.airscout.eu first if (gm_Map.MapProvider.GetType() == typeof(OpenStreetMapProvider)) { LoadOSM(t.X, t.Y, t.Z); } else { PureImage img = gm_Map.Manager.GetImageFrom(gm_Map.MapProvider, new GPoint(t.X, t.Y), t.Z, out ex); // wait until cache is written to database } if (ex == null) { Console.WriteLine("Preload tile [" + i.ToString() + " of " + count.ToString() + "] x=" + t.X + ", y=" + t.Y + ", z=" + t.Z + ": OK"); } else { Console.WriteLine("Preload tile [" + i.ToString() + " of " + count.ToString() + "] x=" + t.X + ", y=" + t.Y + ", z=" + t.Z + ": " + ex.ToString()); } } catch (Exception e1) { Console.WriteLine(this.Name + ": " + e1.ToString()); } Thread.Sleep(100); i++; n++; if (n > 100) { while (GMaps.Instance.tileCacheQueue.Count > 0) { Application.DoEvents(); if (this.CancellationPending) { break; } } n = 0; } if (this.CancellationPending) { break; } } if (this.CancellationPending) { break; } } catch (Exception ex) { this.ReportProgress(-1, ex.ToString()); } // sleep when running periodically if (Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY) { int l = 0; while (!this.CancellationPending && (l < interval)) { Thread.Sleep(1000); l++; } } if (this.CancellationPending) { break; } }while (Options == BACKGROUNDUPDATERSTARTOPTIONS.RUNPERIODICALLY); if (this.CancellationPending) { this.ReportProgress(0, Name + " cancelled."); Log.WriteMessage(Name + " cancelled."); } else { this.ReportProgress(0, Name + " finished, total " + total.ToString() + " tile(s), " + (count - i).ToString() + " left."); Log.WriteMessage(Name + " finished, total " + total.ToString() + " tile(s), " + (count - i).ToString() + " left."); } }