6

I have a vector full of Lat Long coordinates in this format

82.0000000, -180.0000000

I am trying to convert them into an X and a Y coordinate to plot them to a map using this code, which as far as i can see is right...

X:

double testClass::getX(double lon)
{
    // Convert long to X coordinate (2043 = map width)
    double x =  lon;
    // Scale
    x =         x * 2043.0 / 360.0;
    // Center
    x +=        2043.0/2.0;
    return x;
}

Y:

double testClass::getY(double lat)
{
    // Convert lat to Y coordinate (1730 = map height)
    double y =  -1 * lat;
    // Scale
    y =         y * 1730.0 / 180.0;
    // Center
    y +=        1730.0/2.0;
    return y;
}

However when plotted on my map i can see the points do resemble a world map but they are all off by x amount and i think its something to do with my scaling

any ideas?

AngryDuck
  • 4,358
  • 13
  • 57
  • 91
  • 2
    I think you are running afoul of [map projections](https://en.wikipedia.org/wiki/Map_projection). You need to use the same projective transform in your code as was used for generating the map. – indeterminately sequenced Apr 18 '13 at 10:25
  • I am using a world map that has lat long lines and i know what the lat long is for the top left and bottom right of the map is, is that what your saying? – AngryDuck Apr 18 '13 at 10:28
  • Are the offsets uniform for all points or do they vary? – indeterminately sequenced Apr 18 '13 at 10:36
  • they seem to vary the further away from 0 they get. eg dots that should be in Britain are above it and dots that should be on Australia are slightly below it but not by as much as some others etc. – AngryDuck Apr 18 '13 at 10:39
  • 6
    The Earth is round, lines of latitude are closer together at the top and bottom than they are in the middle. You need a transform function (projection) to map the points from the surface of a sphere to two dimensions. – Jonathan Potter Apr 18 '13 at 10:57
  • ok i cant really work out how to do this if someone could point me in the right direction that would be great, a link to a formula a small code sample? – AngryDuck Apr 18 '13 at 11:01
  • 1
    Maybe start with http://mathworld.wolfram.com/MercatorProjection.html – Jonathan Potter Apr 18 '13 at 11:11
  • ok so yea that link has maths thats just beyond a joke, theres no way that there isnt a more simple formula to display lat lon as XY than that. – AngryDuck Apr 18 '13 at 11:31
  • What type of projection does the map that you want to put these points on use? – Nate Kohl Apr 18 '13 at 12:18
  • 3
    @AngryDuck Don't be discouraged by all the maths. The relevant formulas at that Wolfram page are just the first two, `x=...` and `y=...`, and while formulas for `y` may seem confusing, it's nothing but several alternative formulas which should give same result. – hyde Apr 18 '13 at 12:20
  • its not so much the maths as i cannot even see where lat long goes into any of those equations its just a mess of symbols – AngryDuck Apr 18 '13 at 12:24
  • 1
    @AngryDuck: In the above link, lambda is your longitude and phi is your latitude. You must pick a lambda_0 as the center longitude of the map. From these three values you get x and y. X is the horizontal map position of your lat/long and is between -180 and +180 degrees, and y is the vertical map position between -90 and +90 degrees. I trust you to seamlessly convert between radians and degrees. – mars Apr 18 '13 at 12:39
  • Yes it probably is a possible duplicate however the answer i have given here is far more concise and easy to understand i think most people looking for an answer would want this as opposed to the one on the question you linked – AngryDuck Sep 26 '13 at 12:49
  • @AngryDuck - you would be better posting your answer on the duplicate question. – ChrisF Oct 02 '13 at 18:34

1 Answers1

7

Ok i found the answer to this

double testClass::getX(double lon, int width)
{
    // width is map width
    double x = fmod((width*(180+lon)/360), (width +(width/2)));

    return x;
}

double testClass::getY(double lat, int height, int width)
{
    // height and width are map height and width
    double PI = 3.14159265359;
    double latRad = lat*PI/180;

    // get y value
    double mercN = log(tan((PI/4)+(latRad/2)));
    double y     = (height/2)-(width*mercN/(2*PI));
    return y;
}

so yea this works perfectly when using a mercator map

AngryDuck
  • 4,358
  • 13
  • 57
  • 91
  • 3
    Looks good. I hope you can see how these functions correspond to the formulas (this uses the first formula for `y`) shown at that page http://mathworld.wolfram.com/MercatorProjection.html – hyde Apr 18 '13 at 12:51