Calculating the Distance Between Two Coordinates in C#

By FoxLearn 12/21/2024 2:55:43 AM   10
Imagine you’re standing in the middle of Millennium Park in Chicago, looking for a cup of coffee.

You pull up an app on your phone and discover several nearby coffee shops offering exclusive deals. You wonder, "How does this app know how far each coffee shop is from me?"

In this article, we will show you how to calculate the distance between two coordinates (like your current location and a nearby coffee shop) using built-in functions in SQL and C#.

Before diving into code, it’s important to understand the Haversine formula, which is used to calculate the shortest distance between two points on the Earth's surface. This formula takes into account the spherical shape of the Earth and computes the distance between two latitude/longitude coordinates.

Luckily, both SQL and C# have built-in functions to calculate distances using this formula, so we don’t need to implement it from scratch. By using these functions, we can efficiently find nearby locations, such as coffee shops, based on the user's current location.

SQL Server provides the geography data type and the STDistance() function to help you calculate distances between geographical coordinates.

To begin, you need to store the latitude and longitude of each coffee shop as a geography object in your database. This can be done by adding a column with the geography data type.

-- Create a table to store coffee shop locations
CREATE TABLE CoffeeShops
(
    CoffeeShopID INT,
    CoffeeShopName NVARCHAR(100),
    City NVARCHAR(50),
    LatLong GEOGRAPHY
);

Next, insert the coffee shop’s coordinates into the table using the geography::Point() function. Each point is created by passing the latitude, longitude, and the SRID (Spatial Reference System Identifier), which is 4326 for WGS 84 coordinates.

-- Insert some coffee shops with their geographical coordinates
INSERT INTO CoffeeShops
           (CoffeeShopID, CoffeeShopName, City, LatLong)
     VALUES
           (1, 'Cafe Mocha', 'Chicago', geography::Point(41.885, -87.624, 4326));

INSERT INTO CoffeeShops
           (CoffeeShopID, CoffeeShopName, City, LatLong)
     VALUES
           (2, 'Java House', 'Chicago', geography::Point(41.884, -87.625, 4326));

INSERT INTO CoffeeShops
           (CoffeeShopID, CoffeeShopName, City, LatLong)
     VALUES
           (3, 'Brewed Awakenings', 'Chicago', geography::Point(41.883, -87.626, 4326));

Now that we have the data, we can query for all coffee shops that are within 0.1 miles of a given location. We use the STDistance() function to find the distance between two geographical points.

This function returns the distance in meters, so we need to divide it by the number of meters per mile (1,609.344 meters per mile) to convert the result to miles.

DECLARE @currentLocation GEOGRAPHY = geography::Point(41.883, -87.623, 4326);  -- Current location in Chicago
DECLARE @METERS_PER_MILE NUMERIC(19,5) = 1609.344;  -- Conversion factor from meters to miles

-- Find all coffee shops within 0.1 miles
SELECT CoffeeShopID, CoffeeShopName, LatLong.STDistance(@currentLocation) / @METERS_PER_MILE AS DistanceInMiles
FROM CoffeeShops
WHERE LatLong.STDistance(@currentLocation) / @METERS_PER_MILE < 0.1
ORDER BY LatLong.STDistance(@currentLocation);

This query will return all coffee shops within 0.1 miles of your current location, ordered by proximity.

In C#, you can use the GeoCoordinate class from the System.Device.Location namespace to work with geographic coordinates and calculate distances.

Before you can use the GeoCoordinate class, you need to add a reference to System.Device in your project.

You can do this in Visual Studio by right-clicking on "References," selecting "Add Reference," and then choosing System.Device.

Now, let's implement a C# program to find coffee shops within 0.1 miles from a given location.

using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Linq;

namespace FindNearbyCoffeeShops
{
    public class Program
    {
        static void Main(string[] args)
        {
            // List of coffee shops with their coordinates
            var stores = new StoreRepository()
            {
                new Store("Cafe Mocha", 41.885, -87.624),
                new Store("Java House", 41.884, -87.625),
                new Store("Brewed Awakenings", 41.883, -87.626)
            };

            // Find coffee shops within 0.1 miles of the given location
            var nearbyStores = stores.GetStoresWithinXMiles(41.883, -87.623, 0.1);
            foreach (var store in nearbyStores)
            {
                Console.WriteLine(store.StoreName);
            }
        }
    }

    public class Store
    {
        public string StoreName { get; set; }
        public GeoCoordinate Location { get; set; }

        public Store(string storeName, double latitude, double longitude)
        {
            StoreName = storeName;
            Location = new GeoCoordinate(latitude, longitude);
        }
    }

    public class StoreRepository : List<Store>
    {
        private const double METERS_PER_MILE = 1609.344;

        public IEnumerable<Store> GetStoresWithinXMiles(double latitude, double longitude, double miles)
        {
            var userLocation = new GeoCoordinate(latitude, longitude);
            return this.Where(store => store.Location.GetDistanceTo(userLocation) / METERS_PER_MILE <= miles);
        }
    }
}

Whether you're working with a database in SQL or building an application in C#, both approaches can efficiently calculate the distance between geographical coordinates.

By using SQL’s geography data type and STDistance() function or C#'s GeoCoordinate class, you can easily find nearby locations based on the user's current position.