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); } } }