[OSM-dev] Code to convert lat/lon to metres in Mercator projection?

Christopher Schmidt crschmidt at metacarta.com
Tue Jan 9 22:21:14 GMT 2007


On Tue, Jan 09, 2007 at 09:47:29PM +0000, Nick Whitelegg wrote:
> Hello everyone,
> 
> Has anyone written any code to convert lat/lon to Mercator projection in metre 
> units (metres east and north of the intersection of the Greenwich meridian 
> and equator)? There's plenty of lat/lon to Mercator converters around (e.g. 
> that in JOSM) but they give the answer in obscure units, e.g:


There's code in the wiki somewhere to do this,but I don't know if it's
up to date. The tried and tested code that I'm using (tried and tested
in over a half-dozen applications) is in
http://labs.metacarta.com/osm/osm.js . Javascript code follows.

(This code is a direct port of the proj4 code for projection.)

function rad_deg(ang) {
    return ang * (180.0/Math.PI)
}
function deg_rad(ang) {
    return ang * (Math.PI/180.0)
}
function merc_x(lon) {
    var r_major = 6378137.000;
    return r_major * deg_rad(lon);
}
function unmerc_x(lon) {
    var r_major = 6378137.000;
    return rad_deg(lon) / r_major;
}

function unmerc_y(y) {
   var r_major = 6378137.000;
    var r_minor = 6356752.3142;
    var temp = r_minor / r_major;
    var es = 1.0 - (temp * temp);
    var eccent = Math.sqrt(es);
    var eccnth = .5 * eccent;
    var ts = Math.exp(- y / r_major);
    var phi = Math.PI/2 - 2 * Math.atan(ts);
    var i = 0;
    dphi = 1;
    var M_PI_2 = Math.PI/2;
    while(Math.abs(dphi) > 0.000000001 && i < 15) {
      var con = eccent * Math.sin (phi);
      dphi = M_PI_2 - 2. * Math.atan (ts * Math.pow((1. - con) / 
                                            (1. + con), eccnth)) - phi;
      phi += dphi;
      i++;
    } 
    return rad_deg(phi); 
}
function merc_y(lat) {
    if (lat > 89.5)
        lat = 89.5;
    if (lat < -89.5)
        lat = -89.5;
    var r_major = 6378137.000;
    var r_minor = 6356752.3142;
    var temp = r_minor / r_major;
    var es = 1.0 - (temp * temp);
    var eccent = Math.sqrt(es);
    var phi = deg_rad(lat);
    var sinphi = Math.sin(phi);
    var con = eccent * sinphi;
    var com = .5 * eccent; 
    con = Math.pow(((1.0-con)/(1.0+con)), com);
    var ts = Math.tan(.5 * ((Math.PI*0.5) - phi))/con;
    var y = 0 - r_major * Math.log(ts);
    return y;
}
function merc(x,y) {
    return [merc_x(x),merc_y(y)]; 
}


Regards,
-- 
Christopher Schmidt
MetaCarta




More information about the dev mailing list