public ElvMinMaxInfo GetMinMaxElevationLoc(string loc) { ElvMinMaxInfo elv = new ElvMinMaxInfo(); // try to get elevation data from distinct elevation model // start with detailed one if (Properties.Settings.Default.Elevation_SRTM1_Enabled && (elv.MaxElv == ElevationData.Database.ElvMissingFlag)) { ElvMinMaxInfo info = ElevationData.Database.GetMaxElvLoc(loc, ELEVATIONMODEL.SRTM1, false); if (info != null) { elv.MaxLat = info.MaxLat; elv.MaxLon = info.MaxLon; elv.MaxElv = info.MaxElv; elv.MinLat = info.MinLat; elv.MinLon = info.MinLon; elv.MinElv = info.MinElv; } } if (Properties.Settings.Default.Elevation_SRTM3_Enabled && (elv.MaxElv == ElevationData.Database.ElvMissingFlag)) { ElvMinMaxInfo info = ElevationData.Database.GetMaxElvLoc(loc, ELEVATIONMODEL.SRTM3, false); if (info != null) { elv.MaxLat = info.MaxLat; elv.MaxLon = info.MaxLon; elv.MaxElv = info.MaxElv; elv.MinLat = info.MinLat; elv.MinLon = info.MinLon; elv.MinElv = info.MinElv; } } if (Properties.Settings.Default.Elevation_GLOBE_Enabled && (elv.MaxElv == ElevationData.Database.ElvMissingFlag)) { ElvMinMaxInfo info = ElevationData.Database.GetMaxElvLoc(loc, ELEVATIONMODEL.GLOBE, false); if (info != null) { elv.MaxLat = info.MaxLat; elv.MaxLon = info.MaxLon; elv.MaxElv = info.MaxElv; elv.MinLat = info.MinLat; elv.MinLon = info.MinLon; elv.MinElv = info.MinElv; } } // set it to zero if still invalid if (elv.MaxElv == ElevationData.Database.ElvMissingFlag) { elv.MaxElv = 0; } if (elv.MinElv == ElevationData.Database.ElvMissingFlag) { elv.MinElv = 0; } return(elv); }
public LocationDesignator LocationFind(string call, string loc = "") { // check all parameters if (!Callsign.Check(call)) { return(null); } if (!String.IsNullOrEmpty(loc) && !MaidenheadLocator.Check(loc)) { return(null); } // get location info LocationDesignator ld = (String.IsNullOrEmpty(loc)) ? StationData.Database.LocationFind(call) : StationData.Database.LocationFind(call, loc); // return null if not found if (ld == null) { return(null); } // get elevation ld.Elevation = GetElevation(ld.Lat, ld.Lon); ld.BestCaseElevation = false; // 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(ld.Lat, ld.Lon, 3)) { ElvMinMaxInfo maxinfo = GetMinMaxElevationLoc(ld.Loc); if (maxinfo != null) { ld.Lat = maxinfo.MaxLat; ld.Lon = maxinfo.MaxLon; ld.Elevation = maxinfo.MaxElv; ld.BestCaseElevation = true; } } } return(ld); }
public List <LocationDesignator> LocationFindAll(string call) { // check all parameters if (!Callsign.Check(call)) { return(null); } // get location info List <LocationDesignator> l = StationData.Database.LocationFindAll(call); // return null if not found if (l == null) { return(null); } foreach (LocationDesignator ld in l) { // get elevation ld.Elevation = GetElevation(ld.Lat, ld.Lon); ld.BestCaseElevation = false; // 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(ld.Lat, ld.Lon, 3)) { ElvMinMaxInfo maxinfo = GetMinMaxElevationLoc(ld.Loc); if (maxinfo != null) { ld.Lat = maxinfo.MaxLat; ld.Lon = maxinfo.MaxLon; ld.Elevation = maxinfo.MaxElv; ld.BestCaseElevation = true; } } } } return(l); }
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."); } }
private void bw_History_DoWork(object sender, DoWorkEventArgs e) { // check that Stepwidth ist positive in any case if (Properties.Settings.Default.Path_History_StepWidth <= 0) { Properties.Settings.Default.Path_History_StepWidth = 1; } bw_History.ReportProgress(0, "Calculating Path...."); LocationDesignator mycall = StationData.Database.LocationFindOrCreate(Properties.Settings.Default.MyCall, MaidenheadLocator.LocFromLatLon(Properties.Settings.Default.MyLat, Properties.Settings.Default.MyLon, false, 3)); QRVDesignator myqrv = StationData.Database.QRVFindOrCreateDefault(mycall.Call, mycall.Loc, Properties.Settings.Default.Band); // set qrv defaults if zero if (myqrv.AntennaHeight == 0) { myqrv.AntennaHeight = StationData.Database.QRVGetDefaultAntennaHeight(Properties.Settings.Default.Band); } if (myqrv.AntennaGain == 0) { myqrv.AntennaGain = StationData.Database.QRVGetDefaultAntennaGain(Properties.Settings.Default.Band); } if (myqrv.Power == 0) { myqrv.Power = StationData.Database.QRVGetDefaultPower(Properties.Settings.Default.Band); } if (Properties.Settings.Default.Path_BestCaseElevation) { if (!MaidenheadLocator.IsPrecise(mycall.Lat, mycall.Lon, 3)) { ElvMinMaxInfo maxinfo = ElevationData.Database.ElevationTileFindMinMaxInfo(mycall.Loc, Properties.Settings.Default.ElevationModel); if (maxinfo != null) { mycall.Lat = maxinfo.MaxLat; mycall.Lon = maxinfo.MaxLon; } } } LocationDesignator dxcall = StationData.Database.LocationFindOrCreate(Properties.Settings.Default.DXCall, MaidenheadLocator.LocFromLatLon(Properties.Settings.Default.DXLat, Properties.Settings.Default.DXLon, false, 3)); QRVDesignator dxqrv = StationData.Database.QRVFindOrCreateDefault(dxcall.Call, dxcall.Loc, Properties.Settings.Default.Band); // set qrv defaults if zero if (dxqrv.AntennaHeight == 0) { dxqrv.AntennaHeight = StationData.Database.QRVGetDefaultAntennaHeight(Properties.Settings.Default.Band); } if (dxqrv.AntennaGain == 0) { dxqrv.AntennaGain = StationData.Database.QRVGetDefaultAntennaGain(Properties.Settings.Default.Band); } if (dxqrv.Power == 0) { dxqrv.Power = StationData.Database.QRVGetDefaultPower(Properties.Settings.Default.Band); } if (Properties.Settings.Default.Path_BestCaseElevation) { if (!MaidenheadLocator.IsPrecise(dxcall.Lat, dxcall.Lon, 3)) { ElvMinMaxInfo maxinfo = ElevationData.Database.ElevationTileFindMinMaxInfo(dxcall.Loc, Properties.Settings.Default.ElevationModel); if (maxinfo != null) { dxcall.Lat = maxinfo.MaxLat; dxcall.Lon = maxinfo.MaxLon; } } } // find local obstruction, if any LocalObstructionDesignator o = ElevationData.Database.LocalObstructionFind(mycall.Lat, mycall.Lon, Properties.Settings.Default.ElevationModel); double mybearing = LatLon.Bearing(mycall.Lat, mycall.Lon, dxcall.Lat, dxcall.Lon); double myobstr = (o != null) ? o.GetObstruction(myqrv.AntennaHeight, mybearing) : double.MinValue; // try to find propagation path in database or create new one and store PPath = PropagationData.Database.PropagationPathFindOrCreateFromLatLon( bw_History, mycall.Lat, mycall.Lon, ElevationData.Database[mycall.Lat, mycall.Lon, Properties.Settings.Default.ElevationModel] + myqrv.AntennaHeight, dxcall.Lat, dxcall.Lon, ElevationData.Database[dxcall.Lat, dxcall.Lon, Properties.Settings.Default.ElevationModel] + dxqrv.AntennaHeight, Bands.ToGHz(Properties.Settings.Default.Band), LatLon.Earth.Radius * Properties.Settings.Default.Path_Band_Settings[Properties.Settings.Default.Band].K_Factor, Properties.Settings.Default.Path_Band_Settings[Properties.Settings.Default.Band].F1_Clearance, ElevationData.Database.GetDefaultStepWidth(Properties.Settings.Default.ElevationModel), Properties.Settings.Default.ElevationModel, myobstr); DateTime time = From; lock (Crossings) { Crossings.Clear(); } lock (NearestPositions) { NearestPositions.Clear(); } // pre-select nearest positions only bw_History.ReportProgress(0, "Pre-selecting nearest positions..."); LatLon.GPoint midpoint = PPath.GetMidPoint(); double maxdist = PPath.Distance / 2; foreach (AircraftPositionDesignator ap in AllPositions) { if ((ap.LastUpdated >= From) && (ap.LastUpdated <= To) && (LatLon.Distance(ap.Lat, ap.Lon, midpoint.Lat, midpoint.Lon) <= maxdist)) { AircraftDesignator ac = null; AircraftTypeDesignator at = null; ac = AircraftData.Database.AircraftFindByHex(ap.Hex); if (ac != null) { at = AircraftData.Database.AircraftTypeFindByICAO(ac.TypeCode); } PlaneInfo plane = new PlaneInfo(ap.LastUpdated, ap.Call, ((ac != null) && (!String.IsNullOrEmpty(ac.TypeCode)))? ac.Reg : "[unknown]", ap.Hex, ap.Lat, ap.Lon, ap.Track, ap.Alt, ap.Speed, (ac != null) && (!String.IsNullOrEmpty(ac.TypeCode)) ? ac.TypeCode : "[unkomwn]", ((at != null) && (!String.IsNullOrEmpty(at.Manufacturer))) ? at.Manufacturer : "[unknown]", ((at != null) && (!String.IsNullOrEmpty(at.Model))) ? at.Model : "[unknown]", (at != null) ? at.Category : PLANECATEGORY.NONE); lock (NearestPositions) { NearestPositions.Add(plane); } if (NearestPositions.Count % 1000 == 0) { bw_History.ReportProgress(0, "Pre-selecting nearest positions..." + "[" + NearestPositions.Count.ToString() + "]"); } } if (bw_History.CancellationPending) { break; } } bw_History.ReportProgress(0, "Pre-selecting nearest positions finished, " + NearestPositions.Count.ToString() + " positions."); // return if no positions left over if (NearestPositions.Count == 0) { return; } int startindex = 0; // set timeline to first reported position time = NearestPositions[0].Time; while ((!bw_History.CancellationPending) && (time <= To)) { if (Crossings.Count % 1000 == 0) { bw_History.ReportProgress(0, "Calculating at " + time.ToString("yyyy-MM-dd HH:mm:ss") + ", " + Crossings.Count.ToString() + " crossings so far."); } // calculate from timestamp DateTime from = time.AddMinutes(-Properties.Settings.Default.Planes_Position_TTL); // fill plane position cache PlaneInfoCache ac = new PlaneInfoCache(); int i = startindex; startindex = -1; while ((!bw_History.CancellationPending) && (i < NearestPositions.Count)) { // update ap in cache if relevant if (NearestPositions[i].Time >= from) { // store first index as startindex for next iteration if (startindex == -1) { startindex = i; } lock (ac) { ac.InsertOrUpdateIfNewer(NearestPositions[i]); } } // stop if position is newer than current time if (NearestPositions[i].Time > time) { break; } i++; } List <PlaneInfo> allplanes = ac.GetAll(time, Properties.Settings.Default.Planes_Position_TTL); // get nearest planes List <PlaneInfo> nearestplanes = AircraftData.Database.GetNearestPlanes(time, PPath, allplanes, Properties.Settings.Default.Planes_Filter_Max_Circumcircle, Properties.Settings.Default.Path_Band_Settings[Properties.Settings.Default.Band].MaxDistance, Properties.Settings.Default.Planes_MaxAlt); if ((nearestplanes != null) && (nearestplanes.Count() > 0)) { // get all planes crossing the path foreach (PlaneInfo plane in nearestplanes) { if (plane.IntQRB <= Properties.Settings.Default.Path_Band_Settings[Properties.Settings.Default.Band].MaxDistance) { // check if level value is available SignalLevelDesignator ad = SignalData.Database.SignalLevelFind(plane.Time); if (ad != null) { plane.SignalStrength = ad.Level; } else { plane.SignalStrength = double.MinValue; } lock (Crossings) { if (!Properties.Settings.Default.Analysis_CrossingHistory_WithSignalLevel || (ad != null)) { Crossings.Add(plane); } } } bw_History.ReportProgress(0, "Calculating at " + time.ToString("yyyy-MM-dd HH:mm:ss") + ", " + Crossings.Count.ToString() + " crossings so far."); } } time = time.AddSeconds(Stepwidth); } bw_History.ReportProgress(100, "Calculation done."); }