AirScout/ScoutBase/ScoutBase.Propagation/PropagationPath.cs

253 wiersze
9.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Xml;
using System.Xml.Serialization;
using Newtonsoft.Json;
using ScoutBase.Core;
using ScoutBase.Stations;
namespace ScoutBase.Propagation
{
/// <summary>
/// Holds the elevation tile information
/// </summary>
[System.ComponentModel.DesignerCategory("")]
public class PropagationPathDesignator : SQLiteEntry
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// be sure to have a copy of these static members in each derived class !!
// update the tbale name to the table name according to the class
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[JsonIgnore]
public static new readonly string TableName = "PropagationPath";
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public double Bearing12
{
get
{
return LatLon.Bearing(Lat1, Lon1, Lat2, Lon2);
}
}
public double Bearing21
{
get
{
return LatLon.Bearing(Lat2, Lon2, Lat1, Lon1);
}
}
public double Distance
{
get
{
return LatLon.Distance(Lat1, Lon1, Lat2, Lon2);
}
}
public double Lat1 { get; set; }
public double Lon1 { get; set; }
public double h1 { get; set; }
public double Lat2 { get; set; }
public double Lon2 { get; set; }
public double h2 { get; set; }
public double QRG { get; set; }
public double Radius { get; set; }
public double F1_Clearance { get; set; }
public double StepWidth { get; set; }
public double Eps1_Min { get; set; }
public double Eps2_Min { get; set; }
// MEMBERS ONLY TO STORE STATUS TEMPORARLY --> NOT STORED IN DATABASE
// path status: valid / invalid
public bool Valid = false;
// path status: selected / not selected
public bool Selected = false;
// path status local obstructed / not obstructed
public bool LocalObstructed = false;
public double LocalObstruction;
// associated location info
public LocationDesignator Location1 = new LocationDesignator();
public LocationDesignator Location2 = new LocationDesignator();
// assoicated qrv info
public QRVDesignator QRV1 = new QRVDesignator();
public QRVDesignator QRV2 = new QRVDesignator();
public PropagationPathDesignator()
{
Lat1 = 0;
Lon1 = 0;
h1 = 0;
Lat2 = 0;
Lon2 = 0;
h2 = 0;
QRG = 0;
Radius = 0;
F1_Clearance = 0;
StepWidth = 0;
Eps1_Min = 0;
Eps2_Min = 0;
LocalObstruction = 0;
}
public PropagationPathDesignator(DataRow row, double localobstruction) : this()
{
FillFromDataRow(row);
Valid = true;
LocalObstruction = localobstruction;
if (Eps1_Min < LocalObstruction)
LocalObstructed = true;
}
public PropagationPathDesignator(IDataRecord record, double localobstruction) : this()
{
FillFromDataRecord(record);
Valid = true;
LocalObstruction = localobstruction;
if (Eps1_Min < LocalObstruction)
LocalObstructed = true;
}
public PropagationPathDesignator(double lat1, double lon1, double h1, double lat2, double lon2, double h2, double qrg, double radius, double f1_clearance, double stepwidth, double eps1_min, double eps2_min, double localobstruction) :
this(lat1, lon1, h1, lat2, lon2, h2, qrg, radius, f1_clearance, stepwidth, eps1_min, eps2_min, DateTime.UtcNow, localobstruction){ }
public PropagationPathDesignator(double lat1, double lon1, double h1, double lat2, double lon2, double h2, double qrg, double radius, double f1_clearance, double stepwidth, double eps1_min, double eps2_min, DateTime lastupdated, double localobstruction)
{
Lat1 = lat1;
Lon1 = lon1;
this.h1 = h1;
Lat2 = lat2;
Lon2 = lon2;
this.h2 = h2;
QRG = qrg;
Radius = radius;
F1_Clearance = f1_clearance;
Eps1_Min = eps1_min;
Eps2_Min = eps2_min;
StepWidth = stepwidth;
LastUpdated = lastupdated;
LocalObstruction = localobstruction;
if (Eps1_Min < LocalObstruction)
LocalObstructed = true;
}
/// <summary>
/// Returns an array of 1km-stepped info points for diagram/map view
/// </summary>
/// <returns>Array of info points.</returns>
public PropagationPoint[] GetInfoPoints()
{
if (StepWidth <= 0)
return null;
PropagationPoint[] d = new PropagationPoint[(int)Distance + 1];
// chek against localobstruction , if any
double eps1_min = Math.Max(Eps1_Min, LocalObstruction);
for (int i = 0; i < d.Length; i++)
{
d[i] = GetInfoPoint(i);
}
return d;
}
/// <summary>
/// Returns a single info point in a given distance from location 1
/// </summary>
/// <param name="lat">The latitude of the plane.</param>
/// <returns>The info point.</returns>
public PropagationPoint GetInfoPoint(double dist)
{
if (StepWidth <= 0)
return null;
// chek against localobstruction , if any
double eps1_min = Math.Max(Eps1_Min, LocalObstruction);
LatLon.GPoint p = LatLon.DestinationPoint(Lat1, Lon1, Bearing12, dist);
return new PropagationPoint(p.Lat, p.Lon, ScoutBase.Core.Propagation.HeightFromEpsilon(h1, dist, eps1_min, Radius), ScoutBase.Core.Propagation.HeightFromEpsilon(h2, Distance-dist, Eps2_Min, Radius), ScoutBase.Core.Propagation.F1Radius(QRG, Distance, Distance-dist));
}
/// <summary>
/// Gets the mid point of the propagation path
/// </summary>
/// <returns>The mid point of the path.</returns>
/// <summary>
public LatLon.GPoint GetMidPoint()
{
return LatLon.MidPoint(Lat1, Lon1, Lat2, Lon2);
}
/// <summary>
/// Gets an intersection point of a plane (lat, lon, bearing) with the propagation path in a suitable altitude
/// </summary>
/// <param name="lat">The latitude of the plane.</param>
/// <param name="lon">The longitude of the plane.</param>
/// <param name="bearing">The bearing of the plane.</param>
/// <param name="maxdistance">The maximum allowed distance to return a valid intersection (-1: no limits, 0: automatcally adjuts to path distance /2).</param>
/// <returns>The intersection point, if any. Null if no intersection point exists or plane does not have a suitable altitude at intersection point</returns>
/// <summary>
public IntersectionPoint GetIntersectionPoint(double lat, double lon, double bearing, double maxdistance)
{
// get an interscetion point with the propagation path
LatLon.GPoint p = LatLon.IntersectionPoint(Lat1, Lon1, Bearing12, lat, lon, bearing);
if (p == null)
// if not, return null
return null;
// get the minimum altitude a plane must have at intersection point
// get both distances to intersection point
double dist1 = LatLon.Distance(Lat1, Lon1, p.Lat, p.Lon);
double dist2 = LatLon.Distance(Lat2, Lon2, p.Lat, p.Lon);
// chek against localobstruction , if any
double eps1_min = Math.Max(Eps1_Min, LocalObstruction);
// get minimal altitude
double min_H = Math.Max(ScoutBase.Core.Propagation.HeightFromEpsilon(h1, dist1, eps1_min, Radius), ScoutBase.Core.Propagation.HeightFromEpsilon(h2, dist2, Eps2_Min, Radius));
double qrb = LatLon.Distance(p.Lat, p.Lon, lat, lon);
if (maxdistance < 0)
return new IntersectionPoint(p.Lat, p.Lon, qrb, min_H, dist1, dist2);
if ((maxdistance == 0) && (qrb > Distance / 2))
return null;
if (qrb < maxdistance)
return null;
return new IntersectionPoint(p.Lat, p.Lon, qrb, min_H, dist1, dist2);
}
/// Writes an elevation path into a csv
/// </summary>
/// <param name="filename">The filename to be created.</param>
/// <returns>Nothing.</returns>
public void ToCSV(string filename)
{
try
{
using (StreamWriter sw = new StreamWriter(filename))
{
sw.WriteLine("Distance[km];Latitude[deg];Longitude[deg];Elevation[m];Eps1_Min[deg];Eps2_Min[m];Min_H1[m];Min_H2[m]");
}
}
catch (Exception ex)
{
Console.WriteLine("Error while writing elevation path [" + filename + "]: " + ex.ToString());
}
}
}
}