Skip to content

Instantly share code, notes, and snippets.

@oliverheilig
Last active August 29, 2015 14:13
Show Gist options
  • Save oliverheilig/3808a17393053054b015 to your computer and use it in GitHub Desktop.
Save oliverheilig/3808a17393053054b015 to your computer and use it in GitHub Desktop.
// Calcluate airline distance for two mercator points.
// This approximation formula is sufficiently accurate for
// our needs for distances of up to 600 km and
// 80° latitude (the error is never more than 5% even for extreme values).
using System;
public class Program
{
public static void Main()
{
// our latitude/longitude values for test
double lat1 = 49.0;
double lon1 = 8.0;
double lat2 = 50.0;
double lon2 = 9.0;
// convert to PTV Mercator, so assume we have Mercator as input
double x1, y1, x2, y2;
LatLonToSphereMercator(lat1, lon1, out x1, out y1);
LatLonToSphereMercator(lat2, lon2, out x2, out y2);
// calclate mercator distance with Pythagoras
double mercDist = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
// the center of the y values to apply the correction factor
double centerY = (y1 + y2) / 2;
// calculate the corresponding latitude
double centerLat = LatFromMercator(centerY);
// the latitude determines our correction factor
double correctionFactor = Math.Cos(centerLat * Math.PI / 180.0);
// apply the correction factor to real distance
double realDist = mercDist * correctionFactor;
Console.WriteLine("Distance Between {0}/{1} and {2}/{3}", x1, y1, x2, y2);
Console.WriteLine("Pythagoras: {0}", mercDist);
Console.WriteLine("Correction Factor: {0}", correctionFactor);
Console.WriteLine("Real: {0}", realDist);
}
// Project a geographic coordinate on the (spherical) Mercator map.
// Using the mean between major and minor axis here ("PTV standard").
// You could also use the major axis 6378137 ("Google standard").
public static void LatLonToSphereMercator(
double latitude, double longitude, out double x, out double y)
{
x = 6371000.0 * longitude * Math.PI / 180;
y = 6371000.0 * Math.Log(Math.Tan(Math.PI / 4 + latitude * Math.PI / 360));
}
// Caclculate the latitude for a mercator Y
public static double LatFromMercator(double y)
{
return (360 / Math.PI) * (Math.Atan(Math.Exp(y / 6371000.0)) - (Math.PI / 4));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment