/// <summary> /// Returns the maximum elevation angle Epsilon of all objects on an elevation path are seen from an observer(h1) /// If the maxixum elevation angle is higher than an object with maxelv could reach the path is cut to this length /// </summary> /// <param name="h1">The height of the observer [m].</param> /// <param name="elv">The array with elevation data [m].</param> /// <param name="dist">The full path distance [km].</param> /// <param name="stepwidth">The stepwidth in [m].</param> /// <param name="freq">The frequency in [GHz].</param> /// <param name="f1_clearance">The Fresenl Zone F1 clearance [].</param> /// <param name="maxelv">The maximal elevation an object could have [m].</param> /// <param name="re">The equivalent earth radius [km].</param> /// <returns>The HorizonPoint with distance, epsmax and elevation.</returns> public static HorizonPoint EpsilonMaxFromPath(double h1, ref short[] elv, double dist, double stepwidth, double freq, double f1_clearance, double maxelv, double re) { HorizonPoint hp = new HorizonPoint(); stepwidth = stepwidth / 1000.0; double d = 0; for (int i = 0; i < elv.Length; i++) { double f1 = ScoutBase.Core.Propagation.F1Radius(freq, d, dist - d); double h2 = elv[i] + f1 * f1_clearance; double eps = ScoutBase.Core.Propagation.EpsilonFromHeights(h1, d, h2, re); if (eps > hp.Epsmin) { // ignore first 100m if (d > 0.1) { hp.Epsmin = eps; hp.Dist = d; hp.Elv = elv[i]; } } if (maxelv > 0) { double epsmax = ScoutBase.Core.Propagation.EpsilonFromHeights(h1, d, maxelv, re); if (epsmax < hp.Epsmin) { Array.Resize <short>(ref elv, i); return(hp); } } d += stepwidth; } return(hp); }
public PropagationHorizonDesignator() { Lat = 0; Lon = 0; h = 0; Dist = 0; StepWidth = 0; QRG = 0; F1_Clearance = 0; Radius = 0; Horizon = new HorizonPoint[360]; for (int i = 0; i < Horizon.Length; i++) { Horizon[i] = new HorizonPoint(0, 0, 0); } LastUpdated = DateTime.MinValue.ToUniversalTime(); }
public PropagationHorizonDesignator(double lat, double lon, double h, double dist, double qrg, double radius, double f1_clearance, double stepwidth, HorizonPoint[] horizon, DateTime lastupdated, LocalObstructionDesignator localobstruction) { Lat = lat; Lon = lon; this.h = h; Dist = dist; StepWidth = stepwidth; QRG = qrg; F1_Clearance = f1_clearance; Radius = radius; if (horizon == null) { // initialize new horizon array if null Horizon = new HorizonPoint[360]; for (int i = 0; i < Horizon.Length; i++) { Horizon[i] = new HorizonPoint(0, 0, 0); } } else { Horizon = horizon; } LocalObstruction = localobstruction; LastUpdated = lastupdated; if (Horizon == null) { return; } if (LocalObstruction == null) { return; } for (int i = 0; i > 360; i++) { if ((Horizon[i] != null) && (Horizon[i].Epsmin < LocalObstruction.GetObstruction(h, i))) { LocalObstructed = true; } } }
public PropagationHorizonDesignator PropagationHorizonCreate(BackgroundWorker caller, double lat, double lon, double h, double dist, double qrg, double radius, double f1_clearance, double stepwidth, ELEVATIONMODEL model, LocalObstructionDesignator localobstruction, bool savetodatabase = true) { // calculate propagation horizon // report status messages and single data points if called from background thread HorizonPoint[] hor = new HorizonPoint[360]; bool valid = true; PropagationHorizonDesignator hd = new PropagationHorizonDesignator(lat, lon, h, dist, qrg, radius, f1_clearance, stepwidth, hor, localobstruction); for (int j = 0; j < 360; j++) { // report progress if called from background worker if (caller != null) { if (caller.WorkerReportsProgress) { caller.ReportProgress(-1, "Calculating horizon " + j.ToString() + "° of 360°"); } } double eps_min = double.MinValue; double eps_dist = 0; short eps_elv = 0; // find or create elevation path ElevationPathDesignator ep = ElevationData.Database.ElevationPathFindOrCreateFromBearing(caller, lat, lon, j, dist, stepwidth, model, false); for (int i = 0; i < ep.Count; i++) { double d = i * stepwidth / 1000.0; double nf = NearFieldSuppression / 1000.0; double eps; if (d > nf) { double f1c = ScoutBase.Core.Propagation.F1Radius(qrg, d, dist) * f1_clearance; eps = ScoutBase.Core.Propagation.EpsilonFromHeights(h, d, ep.Path[i] + f1c, radius); } else { double f1c = ScoutBase.Core.Propagation.F1Radius(qrg, nf, dist) * f1_clearance; eps = ScoutBase.Core.Propagation.EpsilonFromHeights(h, nf, ep.Path[i] + f1c, radius); } if (eps > eps_min) { eps_min = eps; eps_dist = d; eps_elv = ep.Path[i]; } } hor[j] = new HorizonPoint(eps_dist, eps_min, eps_elv); // report current horizon if called from background worker if (caller != null) { if (caller.WorkerReportsProgress) { caller.ReportProgress(j, hor[j]); } } // take status from elevation path if (!ep.Valid) { valid = false; } // abort calculation if called from background worker and cancellation pending if (caller != null) { if (caller.WorkerSupportsCancellation && caller.CancellationPending) { return(null); } } } // copy over the horizon and status hd.Horizon = hor; hd.Valid = valid; // store in database if valid if ((hd != null) && hd.Valid && savetodatabase) { this.PropagationHorizonInsertOrUpdateIfNewer(hd, model); } return(hd); }