# Latitude, Longitude, Bearing, Cardinal Direction, Distance, and C#

If you are looking for some examples of using latitude and longitude to get bearing and distance information with C# you have come to the right place. If you want to get straight to the code and the download click here.

I usually try to blog about things that I am working on that also could be interesting to other developers. Recently I have been working on an application that stores information about commercial buildings and there competition. Each location has a latitude and longitude which is used to display there data on a map.

To visualize the end result I have added a picture below of an application that is using using ASP.Net, Virtual Earth, while calculating bearing and distance. This was inspire by Alessandro Gallo article. If you are interesting in building a Virtual Earth mash-up using ASP.NET this is a must read article. When the user puts there mouse over a location a pop-up with the distance and bearing are shown. The distance is in miles while the bearing is represented by its cardinal value or compass direction.

### Calculating Distance between two points of Latitude and Longitude

The function below uses the Haversine formula to calculate the distance between the to coordinates and a enumeration to request the type of unit of length.

1: /// <summary>

2: /// Calculates the distance between two points of latitude and longitude.

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

4: /// </summary>

5: /// <param name="coordinate1">First coordinate.</param>

6: /// <param name="coordinate2">Second coordinate.</param>

7: /// <param name="unitsOfLength">Sets the return value unit of length.</param>

8: public static Double Distance(Coordinate coordinate1, Coordinate coordinate2, UnitsOfLength unitsOfLength)

```
9: {
```

```
10:
```

```
11: var theta = coordinate1.Longitude - coordinate2.Longitude;
```

```
12: var distance = Math.Sin(coordinate1.Latitude.ToRadian()) * Math.Sin(coordinate2.Latitude.ToRadian()) +
```

```
13: Math.Cos(coordinate1.Latitude.ToRadian()) * Math.Cos(coordinate2.Latitude.ToRadian()) *
```

```
14: Math.Cos(theta.ToRadian());
```

```
15:
```

```
16: distance = Math.Acos(distance);
```

```
17: distance = distance.ToDegree();
```

```
18: distance = distance * 60 * 1.1515;
```

```
19:
```

20: if (unitsOfLength == UnitsOfLength.Kilometer)

```
21: distance = distance * _MilesToKilometers;
```

22: else if (unitsOfLength == UnitsOfLength.NauticalMiles)

```
23: distance = distance * _MilesToNautical;
```

```
24:
```

25: return (distance);

```
26:
```

```
27: }
```

1: public class Coordinate

```
2: {
```

3: private double latitude, longitude;

```
4:
```

5: /// <summary>

6: /// Latitude in degrees. -90 to 90

7: /// </summary>

8: public Double Latitude

```
9: {
```

10: get { return latitude; }

```
11: set
```

```
12: {
```

13: if (value > 90) throw new ArgumentOutOfRangeException("value", "Latitude value cannot be greater than 90.");

14: if (value < -90) throw new ArgumentOutOfRangeException("value", "Latitude value cannot be less than -90.");

15: latitude = value;

```
16: }
```

```
17: }
```

```
18:
```

19: /// <summary>

20: /// Longitude in degree. -180 to 180

21: /// </summary>

22: public Double Longitude

```
23: {
```

24: get { return longitude; }

```
25: set
```

```
26: {
```

27: if (value > 180) throw new ArgumentOutOfRangeException("value", "Longitude value cannot be greater than 180.");

28: if (value < -180) throw new ArgumentOutOfRangeException("value", "Longitude value cannot be less than -180.");

29: longitude = value;

```
30: }
```

```
31: }
```

```
32: }
```

Here are some of the unit tests that for the coordinate class.

1: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

2: public void CoordinateLatitudeGreater90() { var coordinate = new Coordinate() { Latitude = 100, Longitude = -90 }; }

```
3:
```

4: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

5: public void CoordinateLatitudeLessN90() { var coordinate = new Coordinate() { Latitude = -91, Longitude = -90 }; }

```
6:
```

7: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

8: public void CoordinateLongitudeGreater180() { var coordinate = new Coordinate() { Latitude = 90, Longitude = 190 }; }

```
9:
```

10: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

11: public void CoordinateLongitudeLessN180() { var coordinate = new Coordinate() { Latitude = 90, Longitude = -190 }; }

1: var distance = Helper.Distance(new Coordinate() { Latitude = 45, Longitude = 0 },

2: new Coordinate() { Latitude = 0, Longitude = 45 }, UnitsOfLength.NauticalMiles);

```
3:
```

4: Assert.AreEqual(3599.8653599999993d, distance, "");

### Calculating Bearing and Cardinal Direction

First, I have to give thanks to wikipedia for explaining what a cardinal point was. I never really thought about it until I thought about writing this article. So for all of you who don't already know the location on your compass that say, "N,S,E,W" are called cardinal points. I am not generally one for being a stickler for using the correct nomenclature, but since I went and looked it up, you can benefit from it.

First things first, we need to create a function that takes two coordinates that returns a direction in degrees. Here is where my decision to encapsulate the latitude and longitude values paid some dividends. Now the code will check the latitude and longitude values before it evaluates this function.

1: /// <summary>

2: /// Accepts two coordinates in degrees.

3: /// </summary>

4: /// <returns>A double value in degrees. From 0 to 360.</returns>

5: public static Double Bearing(Coordinate coordinate1, Coordinate coordinate2)

```
6: {
```

```
7: var latitude1 = coordinate1.Latitude.ToRadian();
```

```
8: var latitude2 = coordinate2.Latitude.ToRadian();
```

```
9:
```

```
10: var longitudeDifference = (coordinate2.Longitude - coordinate1.Longitude).ToRadian();
```

```
11:
```

```
12: var y = Math.Sin(longitudeDifference) * Math.Cos(latitude2);
```

```
13: var x = Math.Cos(latitude1) * Math.Sin(latitude2) -
```

```
14: Math.Sin(latitude1) * Math.Cos(latitude2) * Math.Cos(longitudeDifference);
```

```
15:
```

16: return (Math.Atan2(y, x).ToDegree() + 360) % 360;

```
17: }
```

Now that we have a function that will return the bearing in degrees we need to convert those degrees to there cardinal value.

An enumeration to store the cardinal points.

1: public enum CardinalPoints { N, E, W, S, NE, NW, SE, SW }

1: /// <summary>

2: /// Class is used in a calculation to determin cardinal point enumeration values from degrees.

3: /// </summary>

4: private struct CardinalRanges

```
5: {
```

6: public CardinalPoints CardinalPoint;

7: /// <summary>

8: /// Low range value associated with the cardinal point.

9: /// </summary>

10: public Double LowRange;

11: /// <summary>

12: /// High range value associated with the cardinal point.

13: /// </summary>

14: public Double HighRange;

```
15: }
```

1: /// <summary>

2: /// Method extension for Doubles. Converts a degree to a cardinal point enumeration.

3: /// </summary>

4: /// <returns>Returns a cardinal point enumeration representing a compass direction.</returns>

5: public static CardinalPoints ToCardinalMark(this Double degree)

```
6: {
```

```
7:
```

8: var CardinalRanges = new List<CardinalRanges>

```
9: {
```

10: new CardinalRanges {CardinalPoint = CardinalPoints.N, LowRange = 0, HighRange = 22.5},

11: new CardinalRanges {CardinalPoint = CardinalPoints.NE, LowRange = 22.5, HighRange = 67.5},

12: new CardinalRanges {CardinalPoint = CardinalPoints.E, LowRange = 67.5, HighRange = 112.5},

13: new CardinalRanges {CardinalPoint = CardinalPoints.SE, LowRange = 112.5, HighRange = 157.5},

14: new CardinalRanges {CardinalPoint = CardinalPoints.S, LowRange = 157.5, HighRange = 202.5},

15: new CardinalRanges {CardinalPoint = CardinalPoints.SW, LowRange = 202.5, HighRange = 247.5},

16: new CardinalRanges {CardinalPoint = CardinalPoints.W, LowRange = 247.5, HighRange = 292.5},

17: new CardinalRanges {CardinalPoint = CardinalPoints.NW, LowRange = 292.5, HighRange = 337.5},

18: new CardinalRanges {CardinalPoint = CardinalPoints.N, LowRange = 337.5, HighRange = 360.1}

```
19: };
```

```
20:
```

```
21:
```

22: if (!(degree >= 0 && degree <= 360))

23: throw new ArgumentOutOfRangeException("degree",

24: "Degree value must be greater than or equal to 0 and less than or equal to 360.");

```
25:
```

```
26:
```

27: return CardinalRanges.Find(p => (degree >= p.LowRange && degree < p.HighRange)).CardinalPoint;

```
28:
```

```
29:
```

```
30: }
```

### Unit tests

1: /// <summary>

2: /// Summary description for UnitTest1

3: /// </summary>

```
4: [TestFixture]
```

5: public class Maps

```
6: {
```

```
7:
```

```
8: [Test]
```

9: public void DistanceSamePoint0()

```
10: {
```

11: var distance = Helper.Distance(new Coordinate() { Latitude = 90, Longitude = -90 },

12: new Coordinate() { Latitude = 90, Longitude = -90 }, UnitsOfLength.Mile);

```
13:
```

14: Assert.AreEqual(0, distance, "");

```
15:
```

```
16: }
```

```
17:
```

```
18: [Test]
```

19: public void DistanceSampleDataNauticalMiles()

```
20: {
```

21: var distance = Helper.Distance(new Coordinate() { Latitude = 45, Longitude = 0 },

22: new Coordinate() { Latitude = 0, Longitude = 45 }, UnitsOfLength.NauticalMiles);

```
23:
```

24: Assert.AreEqual(3599.8653599999993d, distance, "");

```
25: }
```

```
26:
```

```
27:
```

```
28: [Test]
```

29: public void DistanceSampleDataMiles()

```
30: {
```

31: var distance = Helper.Distance(new Coordinate() { Latitude = 45, Longitude = 0 },

32: new Coordinate() { Latitude = 0, Longitude = 45 }, UnitsOfLength.Mile);

```
33:
```

34: Assert.AreEqual(4145.3999999999996d, distance, "");

```
35: }
```

```
36:
```

```
37: [Test]
```

38: public void DistanceSampleDataKilometer()

```
39: {
```

40: var distance = Helper.Distance(new Coordinate() { Latitude = 45, Longitude = 0 },

41: new Coordinate() { Latitude = 0, Longitude = 45 }, UnitsOfLength.Kilometer);

```
42:
```

43: Assert.AreEqual(6671.3746175999995d, distance, "");

```
44: }
```

```
45:
```

```
46: [Test]
```

47: public void BearingsTests()

```
48: {
```

49: var bearing = Helper.Bearing(new Coordinate() { Latitude = 45, Longitude = 1 },

50: new Coordinate() { Latitude = 45, Longitude = 0 });

```
51:
```

52: Assert.AreEqual(270.35355787806577d, bearing, "");

```
53: Assert.AreEqual(CardinalPoints.W, bearing.ToCardinalMark());
```

```
54:
```

```
55: }
```

```
56:
```

```
57: [Test]
```

58: public void CardinalMarkValues()

```
59: {
```

```
60: Assert.AreEqual(CardinalPoints.N, 2D.ToCardinalMark());
```

```
61: Assert.AreEqual(CardinalPoints.NE, 46D.ToCardinalMark());
```

```
62: Assert.AreEqual(CardinalPoints.SE, 120D.ToCardinalMark());
```

```
63: Assert.AreEqual(CardinalPoints.S, 170D.ToCardinalMark());
```

```
64: Assert.AreEqual(CardinalPoints.SW, 220D.ToCardinalMark());
```

```
65: Assert.AreEqual(CardinalPoints.W, 273D.ToCardinalMark());
```

```
66: Assert.AreEqual(CardinalPoints.NW, 320D.ToCardinalMark());
```

```
67:
```

```
68: }
```

```
69:
```

```
70:
```

```
71:
```

72: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

73: public void ToCardinalMarkOutOfRange() { 390D.ToCardinalMark(); }

```
74:
```

75: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

76: public void CoordinateLatitudeGreater90() { var coordinate = new Coordinate() { Latitude = 100, Longitude = -90 }; }

```
77:
```

78: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

79: public void CoordinateLatitudeLessN90() { var coordinate = new Coordinate() { Latitude = -91, Longitude = -90 }; }

```
80:
```

81: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

82: public void CoordinateLongitudeGreater180() { var coordinate = new Coordinate() { Latitude = 90, Longitude = 190 }; }

```
83:
```

84: [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]

85: public void CoordinateLongitudeLessN180() { var coordinate = new Coordinate() { Latitude = 90, Longitude = -190 }; }

```
86:
```

```
87:
```

```
88: }
```

### Summary

Hope this helps someone out there. Let me know if there is anything I left out.

Mick Walker

Thursday, June 04, 2009 11:13 PM

I like you're code, I was just wondering if you would have any examples of converting X and Y coordinates to Lat and Long

ChuckC

Tuesday, August 11, 2009 3:03 PM

Bryan, thank you! I have a .net app that calculates the distance from a billboard to the scene of an accident. The company I work for owns digital billboards and also a traffic reporting service. kind of cool! anyway, I needed something to calculate the distance from the billboard to the accident... I have done that... but then they said...well we want to know if the accident is in front of the billboard, or behind it. SO, I googled for this info, and yours was the first hit. I hope to try it out tomorrow. This is a static .exe app, not asp net but I am sure it would still work. I am not mapping anything, but I might want to do that later. It seems you need to do Java to do the mapping, is that correct? I can host a asp .net app, but for the most part, I just need an exe that runs on a server as this is a utility app, not a forward facing web app.

Divyesh Chapaneri

Thursday, November 26, 2009 7:38 PM

Hi,

There is one coordinate as for example 19.447754, 72.75541 now I want list or coordinates that covers circular area and it has center coordinate as I have given above.

Means it should give me circumference or diameter and I will pass miles/kilometers.

Is there any api/web services or any method/function/formula to achieve this?

Help me out !

Thanks,

Divyesh Chapaneri