2019-03-19 21:09:03 +00:00
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
2021-12-31 08:08:48 +00:00
public bool Valid = false ;
2019-03-19 21:09:03 +00:00
// 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 ) ;
2021-12-31 08:08:48 +00:00
Valid = true ;
2019-03-19 21:09:03 +00:00
LocalObstruction = localobstruction ;
if ( Eps1_Min < LocalObstruction )
LocalObstructed = true ;
}
public PropagationPathDesignator ( IDataRecord record , double localobstruction ) : this ( )
{
FillFromDataRecord ( record ) ;
2021-12-31 08:08:48 +00:00
Valid = true ;
2019-03-19 21:09:03 +00:00
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 ( ) ) ;
}
}
}
}