예제 #1
0
        /// <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);
        }
예제 #2
0
 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();
 }
예제 #3
0
 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;
         }
     }
 }
예제 #4
0
        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);
        }