Here is some code I started writing, the Mercator projection is based on this answer.
using System;
using System.Drawing;
namespace CoordinatesTool
{
public class GeoPoint
{
public double Longitude { get; set; }
public double Latitude { get; set; }
public string ToString()
{
return Latitude + "," + Longitude;
}
public PointF ToMercator(int width, int height)
{
var x = (float)((Longitude + 180) * width / 360);
var latRadians = Latitude * Math.PI / 180;
var yTransformed = Math.Log(Math.Tan((latRadians / 2) + (Math.PI / 4)));
var yScaled = (float)((height / 2.0) - (width * yTransformed / (2 * Math.PI)));
return new PointF(x, yScaled);
}
public static GeoPoint FromMercator(PointF point, int width, int height)
{
return FromMercator(point.X, point.Y, width, height);
}
public static GeoPoint FromMercator(double x, double y, int width, int height)
{
// No clue what to do here
}
}
}
My goal is to use this utility class in a WinForms application. I'm using it with this map: http://en.wikipedia.org/wiki/File:Mercator-projection.jpg (width: 2048, height: 1588).
The Mercator inversion is working quite well (however, I suspect it's not very accurate in the arctic/antarctic reagions).
But the inverse Mercator projection really leaves me puzzled. I played around with the solution proposed in another question, but couldn't get anywhere. Especially I don't understand the Gudermannian (and inverse) function, the DEGREES_PER_RADIAN and RADIANS_PER_DEGREE constants, and how I should convert the y value into a latitude to call the GudermannianInv() function with.
EDIT: Here is how I tried how to do the inverse projection:
Starting with yScaled (parameter y in FromMercator function):
var yTransformed = 2 * Math.PI * (height / 2.0 - yScaled) / width;
var latRadians = Math.Arctan(Math.Pow(Math.E, yTransformed) - Math.PI / 4) / 2;
// ...