Calculate the distance of two geometry points in km C #

I need to calculate the distance between two points of geometry. points are given in longitude and latitude.

coordinates:

point 1: 36.578581, -118.291994

point 2: 36.23998, -116.83171

here is a website for comparing the results:

http://www.movable-type.co.uk/scripts/latlong.html

here is the code that I used at this link: Calculate the distance between two points on Google V3 maps

const double PIx = Math.PI; const double RADIO = 6378.16; /// <summary> /// Convert degrees to Radians /// </summary> /// <param name="x">Degrees</param> /// <returns>The equivalent in radians</returns> public static double Radians(double x) { return x * PIx / 180; } /// <summary> /// Calculate the distance between two places. /// </summary> /// <param name="lon1"></param> /// <param name="lat1"></param> /// <param name="lon2"></param> /// <param name="lat2"></param> /// <returns></returns> public static double DistanceBetweenPlaces(double lon1, double lat1, double lon2, double lat2) { double R = 6371; // km double dLat = Radians(lat2 - lat1); double dLon = Radians(lon2 - lon1); lat1 = Radians(lat1); lat2 = Radians(lat2); double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2); double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); double d = R * c; return d; } Console.WriteLine(DistanceAlgorithm.DistanceBetweenPlaces(36.578581, -118.291994, 36.23998, -116.83171)); 

the problem is that I get two different results.

my result: 163,307 km

website result: 136 km

any suggestions

Torti

+13
source share
7 answers

Your formula is almost correct, but you need to change the parameters for longitude to latitude

 Console.WriteLine(DistanceAlgorithm.DistanceBetweenPlaces(-118.291994, 36.578581, -116.83171, 36.23998)); // = 136 km 

I use a simplified formula:

 // cos(d) = sin(φ)·sin(φB) + cos(φ)·cos(φB)·cos(λ − λB), // where φ, φB are latitudes and λ, λB are longitudes // Distance = d * R public static double DistanceBetweenPlaces(double lon1, double lat1, double lon2, double lat2) { double R = 6371; // km double sLat1 = Math.Sin(Radians(lat1)); double sLat2 = Math.Sin(Radians(lat2)); double cLat1 = Math.Cos(Radians(lat1)); double cLat2 = Math.Cos(Radians(lat2)); double cLon = Math.Cos(Radians(lon1) - Radians(lon2)); double cosD = sLat1*sLat2 + cLat1*cLat2*cLon; double d = Math.Acos(cosD); double dist = R * d; return dist; } 

Testing:

(Distance at the equator): Positions 0, 100; Latitude = 0.0; DistanceB betweenPlaces (0, 0, 100, 0) = 11119.5 km

(Distance at the North Pole): Positions 0, 100; Latitude = 90.90; Distance B BetweenPlaces (0, 90, 100, 90) = 0 km

Longitude: -118.291994, -116.83171; Latitude: 36.578581, 36.23998 = 135.6 km

Longitude: 36.578581, 36.23998; Latitude: -118.291994, -116.83171 = 163.2 km

Best wishes

PS On the website that you use to compare the results, for each first text field the points are latitude, the second is longitude

+21
source

Since you are using framework 4.0, I would suggest the GeoCoordinate class.

 // using System.Device.Location; GeoCoordinate c1 = new GeoCoordinate(36.578581, -118.291994); GeoCoordinate c2 = new GeoCoordinate(36.23998, -116.83171); double distanceInKm = c1.GetDistanceTo(c2) / 1000; // Your result is: 136,111419742602 

You must add a link to System.Device.dll.

+18
source

In my article a few years ago (link: http://www.codeproject.com/Articles/469500/Edumatter-School-Math-Calculators-and-Equation-Sol ) I described 3 useful Functions for calculating the distance between 2 geo -points (in other words, a large circular (orthodromic) distance on Earth between 2 geo-points), which differs in terms of accuracy / performance:

 // Haversine formula to calculate great-circle distance between two points on Earth private const double _radiusEarthMiles = 3959; private const double _radiusEarthKM = 6371; private const double _m2km = 1.60934; private const double _toRad = Math.PI / 180; /// <summary> /// Haversine formula to calculate /// great-circle (orthodromic) distance on Earth /// High Accuracy, Medium speed /// </summary> /// <param name="Lat1">double: 1st point Latitude</param> /// <param name="Lon1">double: 1st point Longitude</param> /// <param name="Lat2">double: 2nd point Latitude</param> /// <param name="Lon2">double: 2nd point Longitude</param> /// <returns>double: distance in miles</returns> public static double DistanceMilesHaversine(double Lat1, double Lon1, double Lat2, double Lon2) { try { double _radLat1 = Lat1 * _toRad; double _radLat2 = Lat2 * _toRad; double _dLatHalf = (_radLat2 - _radLat1) / 2; double _dLonHalf = Math.PI * (Lon2 - Lon1) / 360; // intermediate result double _a = Math.Sin(_dLatHalf); _a *= _a; // intermediate result double _b = Math.Sin(_dLonHalf); _b *= _b * Math.Cos(_radLat1) * Math.Cos(_radLat2); // central angle, aka arc segment angular distance double _centralAngle = 2 * Math.Atan2(Math.Sqrt(_a + _b), Math.Sqrt(1 - _a - _b)); // great-circle (orthodromic) distance on Earth between 2 points return _radiusEarthMiles * _centralAngle; } catch { throw; } } // Spherical law of cosines formula to calculate great-circle distance between two points on Earth /// <summary> /// Spherical Law of Cosines formula to calculate /// great-circle (orthodromic) distance on Earth; /// High Accuracy, Medium speed /// http://en.wikipedia.org/wiki/Spherical_law_of_cosines /// </summary> /// <param name="Lat1">double: 1st point Latitude</param> /// <param name="Lon1">double: 1st point Longitude</param> /// <param name="Lat2">double: 2nd point Latitude</param> /// <param name="Lon2">double: 2nd point Longitude</param> /// <returns>double: distance in miles</returns> public static double DistanceMilesSLC( double Lat1, double Lon1, double Lat2, double Lon2) { try { double _radLat1 = Lat1 * _toRad; double _radLat2 = Lat2 * _toRad; double _radLon1 = Lon1 * _toRad; double _radLon2 = Lon2 * _toRad; // central angle, aka arc segment angular distance double _centralAngle = Math.Acos(Math.Sin(_radLat1) * Math.Sin(_radLat2) + Math.Cos(_radLat1) * Math.Cos(_radLat2) * Math.Cos(_radLon2 - _radLon1)); // great-circle (orthodromic) distance on Earth between 2 points return _radiusEarthMiles * _centralAngle; } catch { throw; } } // Great-circle distance calculation using Spherical Earth projection formula** /// <summary> /// Spherical Earth projection to a plane formula (using Pythagorean Theorem) /// to calculate great-circle (orthodromic) distance on Earth. /// http://en.wikipedia.org/wiki/Geographical_distance /// central angle = /// Sqrt((_radLat2 - _radLat1)^2 + (Cos((_radLat1 + _radLat2)/2) * (Lon2 - Lon1))^2) /// Medium Accuracy, Fast, /// relative error less than 0.1% in search area smaller than 250 miles /// </summary> /// <param name="Lat1">double: 1st point Latitude</param> /// <param name="Lon1">double: 1st point Longitude</param> /// <param name="Lat2">double: 2nd point Latitude</param> /// <param name="Lon2">double: 2nd point Longitude</param> /// <returns>double: distance in miles</returns> public static double DistanceMilesSEP(double Lat1, double Lon1, double Lat2, double Lon2) { try { double _radLat1 = Lat1 * _toRad; double _radLat2 = Lat2 * _toRad; double _dLat = (_radLat2 - _radLat1); double _dLon = (Lon2 - Lon1) * _toRad; double _a = (_dLon) * Math.Cos((_radLat1 + _radLat2) / 2); // central angle, aka arc segment angular distance double _centralAngle = Math.Sqrt(_a * _a + _dLat * _dLat); // great-circle (orthodromic) distance on Earth between 2 points return _radiusEarthMiles * _centralAngle; } catch { throw; } } 

Functions return results in miles; to find the distance in km, multiply the result by 1.60934 (see private const double _m2km = 1.60934 ).

Regarding the sample: find the distance point1 (36.578581, -118.291994) and point 2 (36.23998, -116.83171), the three above-mentioned functions produced the following results (km):

 136.00206654936932 136.00206654937023 136.00374497149613 

and a calculator (link: http://www.movable-type.co.uk/scripts/latlong.html ) gave the result: 136.0

Hope this helps. Best wishes,

+2
source

I used the formula from Wikipedia and put it in a lambda function:

 Func<double, double, double, double, double> CalcDistance = (lat1, lon1, lat2, lon2) => { Func<double, double> Radians = (angle) => { return angle * (180.0 / Math.PI); }; const double radius = 6371; double delataSigma = Math.Acos(Math.Sin(Radians(lat1)) * Math.Sin(Radians(lat2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * Math.Cos(Math.Abs(Radians(lon2) - Radians(lon1)))); double distance = radius * delataSigma; return distance; }; 
+1
source

try this ... I've used this application before - it's pretty accurate. Forgive me for not giving credit to the brilliant soul that originally published this, I moved it from java to C #:

 namespace Sample.Geography { using System; public class GeodesicDistance { private static double DegsToRadians(double degrees) { return (0.017453292519943295 * degrees); } public static double? GetDistance(double lat1, double lon1, double lat2, double lon2) { long num = 0x615299L; double num2 = 6356752.3142; double num3 = 0.0033528106647474805; double num4 = DegsToRadians(lon2 - lon1); double a = Math.Atan((1 - num3) * Math.Tan(DegsToRadians(lat1))); double num6 = Math.Atan((1 - num3) * Math.Tan(DegsToRadians(lat2))); double num7 = Math.Sin(a); double num8 = Math.Sin(num6); double num9 = Math.Cos(a); double num10 = Math.Cos(num6); double num11 = num4; double num12 = 6.2831853071795862; int num13 = 20; double y = 0; double x = 0; double num18 = 0; double num20 = 0; double num22 = 0; while ((Math.Abs((double) (num11 - num12)) > 1E-12) && (--num13 > 0)) { double num14 = Math.Sin(num11); double num15 = Math.Cos(num11); y = Math.Sqrt(((num10 * num14) * (num10 * num14)) + (((num9 * num8) - ((num7 * num10) * num15)) * ((num9 * num8) - ((num7 * num10) * num15)))); if (y == 0) { return 0; } x = (num7 * num8) + ((num9 * num10) * num15); num18 = Math.Atan2(y, x); double num19 = ((num9 * num10) * num14) / y; num20 = 1 - (num19 * num19); if (num20 == 0) { num22 = 0; } else { num22 = x - (((2 * num7) * num8) / num20); } double num21 = ((num3 / 16) * num20) * (4 + (num3 * (4 - (3 * num20)))); num12 = num11; num11 = num4 + ((((1 - num21) * num3) * num19) * (num18 + ((num21 * y) * (num22 + ((num21 * x) * (-1 + ((2 * num22) * num22))))))); } if (num13 == 0) { return null; } double num23 = (num20 * ((num * num) - (num2 * num2))) / (num2 * num2); double num24 = 1 + ((num23 / 16384) * (4096 + (num23 * (-768 + (num23 * (320 - (175 * num23))))))); double num25 = (num23 / 1024) * (256 + (num23 * (-128 + (num23 * (74 - (47 * num23)))))); double num26 = (num25 * y) * (num22 + ((num25 / 4) * ((x * (-1 + ((2 * num22) * num22))) - ((((num25 / 6) * num22) * (-3 + ((4 * y) * y))) * (-3 + ((4 * num22) * num22)))))); return new double?((num2 * num24) * (num18 - num26)); } } } 
0
source

I just tried to code in GeoDataSource and it worked perfectly: http://www.geodatasource.com/developers/c-sharp

0
source

I think you are changing the latitude and longitude values. Try to fix them or change the sequence of parameters.

0
source

Source: https://habr.com/ru/post/954950/


All Articles