using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Microsoft.SqlServer.Server;
using Neo.Afx.ComponentModel;
namespace Neo.Afx.Helpers
{
///
/// A helper for geo data related functoins
///
public class GeoLocationHelper
{
///
/// Does check digit validation on an RSA id number
///
/// The from longitude.
/// The from latitude.
/// The to longitude.
/// The to latitude.
///
/// True/False
[SqlFunction(
IsDeterministic = true,
IsPrecise = true,
DataAccess = DataAccessKind.Read,
SystemDataAccess = SystemDataAccessKind.Read
)]
public static SqlDouble GetDistanceBetweenPoints(SqlDouble fromLongitude, SqlDouble fromLatitude, SqlDouble toLongitude, SqlDouble toLatitude)
{
if (fromLongitude == 0 || fromLatitude == 0 || toLongitude == 0 || toLatitude == 0)
{
new SqlDouble(-1);
}
double distance = -1;
try
{
if ((fromLatitude.Value == toLatitude.Value) && (fromLongitude.Value == toLongitude.Value))
{
return 0;
}
else
{
//See https://www.geodatasource.com/developers/c-sharp for more info
double theta = fromLongitude.Value - toLongitude.Value;
distance = Math.Sin(deg2rad(fromLatitude.Value)) * Math.Sin(deg2rad(toLatitude.Value)) + Math.Cos(deg2rad(fromLatitude.Value)) * Math.Cos(deg2rad(toLatitude.Value)) * Math.Cos(deg2rad(theta));
distance = Math.Acos(distance);
distance = rad2deg(distance);
distance = distance * 60 * 1.1515;
distance = distance * 1.609344;
}
}
catch {
distance = -1;
}
return new SqlDouble(distance);
}
//This function converts decimal degrees to radians
private static double deg2rad(double deg)
{
return (deg * Math.PI / 180.0);
}
//This function converts radians to decimal degrees
private static double rad2deg(double rad)
{
return (rad / Math.PI * 180.0);
}
}
}