using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
public class Program
{
public class Coordinate
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
// Helper class to store coordinate and its calculated distance
private class CoordinateDistance
{
public Coordinate Coordinate { get; set; }
public double Distance { get; set; }
}
private static readonly List<Coordinate> _predefinedCoordinates = new List<Coordinate>
{
new Coordinate { Latitude = -26.2041, Longitude = 28.0473 }, // Johannesburg
new Coordinate { Latitude = -33.8688, Longitude = 151.2093 },// Sydney
new Coordinate { Latitude = 40.7128, Longitude = -74.0060 }, // New York
new Coordinate { Latitude = -25.771394283754905, Longitude = 28.235580364439038 }, // Brooklyn Mall
new Coordinate { Latitude = 35.6895, Longitude = 139.6917 }, // Tokyo
new Coordinate { Latitude = 48.8566, Longitude = 2.3522 }, // Paris
new Coordinate { Latitude = 55.7558, Longitude = 37.6173 }, // Moscow
new Coordinate { Latitude = -25.78263134020646, Longitude = 28.275175392408805 } // Menlyn Park Shopping Centre
};
/// <summary>
/// Calculates the distance between two sets of coordinates using the Haversine formula.
/// </summary>
/// <param name="lat1">Latitude of the first point.</param>
/// <param name="lon1">Longitude of the first point.</param>
/// <param name="lat2">Latitude of the second point.</param>
/// <param name="lon2">Longitude of the second point.</param>
/// <returns>Distance in kilometers, or -1 if an error occurs.</returns>
private static double CalculateHaversineDistance(double lat1, double lon1, double lat2, double lon2)
{
try
{
const double R = 6371; // Earth's radius in kilometers
double dLat = ToRadians(lat2 - lat1);
double dLon = ToRadians(lon2 - lon1);
double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
Math.Cos(ToRadians(lat1)) * Math.Cos(ToRadians(lat2)) *
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return R * c; // Distance in kilometers
}
catch (ArithmeticException ex)
{
Console.Error.WriteLine($"Mathematical error during Haversine calculation: {ex.Message}");
return -1; // Indicate an error
}
catch (Exception ex)
{
Console.Error.WriteLine($"An unexpected error occurred during Haversine calculation: {ex.Message}");
return -1; // Indicate an error
}
}
/// <summary>
/// Converts an angle from degrees to radians.
/// </summary>
/// <param name="angle">The angle in degrees.</param>
/// <returns>The angle in radians.</returns>
private static double ToRadians(double angle)
{
return Math.PI * angle / 180.0;
}
public static void Main()
{
// Define the request coordinate
Coordinate requestCoordinate = new Coordinate() { Latitude = -25.754511453940673, Longitude = 28.181179918201046 }; // Tshwane Mail Centre
// Basic validation for the request coordinate
if (requestCoordinate.Latitude < -90 || requestCoordinate.Latitude > 90 ||
requestCoordinate.Longitude < -180 || requestCoordinate.Longitude > 180)
{
Console.Error.WriteLine("Error: Invalid request coordinate provided. Latitude must be between -90 and 90, and Longitude between -180 and 180.");
return;
}
double targetLatitude = requestCoordinate.Latitude;
double targetLongitude = requestCoordinate.Longitude;
// Use a list to store the results of the LINQ query
List<CoordinateDistance> nearestCoordinatesWithDistance = new List<CoordinateDistance>();
try
{
// Select, order, and take the top 3 nearest coordinates
nearestCoordinatesWithDistance = _predefinedCoordinates
.Select(coord => new CoordinateDistance
{
Coordinate = coord,
Distance = CalculateHaversineDistance(targetLatitude, targetLongitude, coord.Latitude, coord.Longitude)
})
.Where(item => item.Distance != -1) // Filter out items where distance calculation failed
.OrderBy(item => item.Distance)
.Take(3)
.ToList();
// Extract just the Coordinate objects for serialization
List<Coordinate> nearestCoordinates = nearestCoordinatesWithDistance
.Select(item => item.Coordinate)
.ToList();
// Serialize and print the result
JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true };
string jsonOutput = JsonSerializer.Serialize(nearestCoordinates, options);
Console.WriteLine(jsonOutput);
}
catch (InvalidOperationException ex)
{
Console.Error.WriteLine($"Error during LINQ operations: {ex.Message}");
}
catch (JsonException ex)
{
Console.Error.WriteLine($"Error serializing coordinates to JSON: {ex.Message}");
}
catch (Exception ex)
{
Console.Error.WriteLine($"An unexpected error occurred in Main: {ex.Message}");
}
}
}
Last active
July 7, 2025 10:47
-
-
Save tshego3/43b55106a1b47297da41ddf02f53569b to your computer and use it in GitHub Desktop.
Haversine formula-based Coordinate Distance Calculator
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment