public double SphericalDistance(Coords me, Coords item) { double degreesToRadians = Math.PI / 180.0; // phi = 90deg - latitude double mePhi = (90.0 - me.Latitude) * degreesToRadians; double itemPhi = (90.0 - item.Latitude) * degreesToRadians; // theta = longitude double meTheta = me.Longitude * degreesToRadians; double itemTheta = item.Longitude * degreesToRadians; // Compute spherical distance from spherical coordinates // For two locations in spherical coordinates // (1, theta, phi) and (1, theta, phi) // cosine( arc length ) = // sin phi sin phi' cos(theta-theta') + cos phi cos phi' // distance = rho * arc length double cos = (Math.Sin(mePhi) * Math.Sin(itemPhi) * Math.Cos(meTheta - itemTheta) + Math.Cos(mePhi) * Math.Cos(itemPhi)); double arc = Math.Acos(cos); // Remember to multiply arc by the radius of the earth // in your favorite set of units to get length. return arc; }
public static double CalculateBearing(Coords pointA, Coords pointB) { double lat1 = pointA.Latitude.ToRadian(); double lat2 = pointB.Latitude.ToRadian(); double deltaLong = (pointB.Longitude - pointA.Longitude).ToRadian(); double y = Math.Sin(deltaLong) * Math.Cos(lat2); double x = Math.Cos(lat1) * Math.Sin(lat2) - (Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(deltaLong)); double initialBearing = Math.Atan2(y, x).ToDegrees(); double compassBearing = (initialBearing + 360) % 360; return compassBearing; }
public void FindNearest(Coords me, out Coords nearestItem, out double nearestDistance) { nearestItem = new Coords(); nearestDistance = double.NaN; foreach (Coords item in this.Coordinates) { double itemDistance = SphericalDistance(me, item) * 3963.1676; // earth radius in miles if (double.IsNaN(nearestDistance) || itemDistance < nearestDistance) { nearestItem = item; nearestDistance = itemDistance; } } }
public void SphericalDistance_Should_Return_10() { TestCoordinateResource resource = new TestCoordinateResource(); Coords here = new Coords { Latitude = 39.928780, Longitude = -105.139314 }; Coords there = new Coords { Latitude = 39.927733, Longitude = -105.147360 }; // these two coords are ~ less than 1/2 mile apart var distance = resource.SphericalDistance(here, there) * 3963.1676; // earth radius in miles Assert.That(distance <= 0.5); }