Skip to content

Instantly share code, notes, and snippets.

@blemoine
Last active August 3, 2023 15:18
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blemoine/e6045ed93b3d90a52891 to your computer and use it in GitHub Desktop.
Save blemoine/e6045ed93b3d90a52891 to your computer and use it in GitHub Desktop.
Convert Lambert 93 to GPS Coordinates Latitude / Longitude (wgs84)
Math.tanh = Math.tanh || function(x) {
if(x === Infinity) {
return 1;
} else if(x === -Infinity) {
return -1;
} else {
return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x));
}
};
Math.atanh = Math.atanh || function(x) {
return Math.log((1+x)/(1-x)) / 2;
};
function lambert93toWGPS(lambertE, lambertN) {
var constantes = {
GRS80E: 0.081819191042816,
LONG_0: 3,
XS: 700000,
YS: 12655612.0499,
n: 0.7256077650532670,
C: 11754255.4261
}
var delX = lambertE - constantes.XS;
var delY = lambertN - constantes.YS;
var gamma = Math.atan(-delX / delY);
var R = Math.sqrt(delX * delX + delY * delY);
var latiso = Math.log(constantes.C / R) / constantes.n;
var sinPhiit0 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * Math.sin(1)));
var sinPhiit1 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit0));
var sinPhiit2 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit1));
var sinPhiit3 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit2));
var sinPhiit4 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit3));
var sinPhiit5 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit4));
var sinPhiit6 = Math.tanh(latiso + constantes.GRS80E * Math.atanh(constantes.GRS80E * sinPhiit5));
var longRad = Math.asin(sinPhiit6);
var latRad = gamma / constantes.n + constantes.LONG_0 / 180 * Math.PI;
var longitude = latRad / Math.PI * 180;
var latitude = longRad / Math.PI * 180;
return {longitude: longitude, latitude: latitude};
}
@achouippe
Copy link

Very useful, thank you !

@blemoine
Copy link
Author

blemoine commented Feb 2, 2016

To convert for other Lambert Projection, you can change constantes with value found here :

http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/notice/NTG_71.pdf

LONG_0 == λ0 ; GRS80E == e

@jerkso
Copy link

jerkso commented Jan 23, 2018

THX, u save my life today. I will be forever grateful.

@guillim
Copy link

guillim commented Feb 28, 2018

work well! Thanks a lot

@Bouguerra-S
Copy link

Hello blemoine, I am working on a project and I need to write this function in python. I never used javascript therefore I don't understand what you did before the function keyword. Merci d'avance.

@blemoine
Copy link
Author

if you talk about Math.tanh = ... and Math.atanh = ... , it's only to define the hyperbolic tangent and hyperbolic arctangent if they don't already exist.

Because JavaScript can be run in many different browsers, you never know if every function that you need will already be present or not.

@bleucitron
Copy link

Thx a lot !
Would you consider make it an NPM package ?

@blemoine
Copy link
Author

blemoine commented Sep 3, 2019

Hi,

If you need an npm package, you can user proj4js , a project that has the goal to convert from "any" coordinate system to any other coordinate system. To help you further, you can find here https://spatialreference.org/ref/epsg/rgf93-lambert-93/
the definition of lambert 93 for proj4s (https://spatialreference.org/ref/epsg/rgf93-lambert-93/proj4js/ to be precise ),

so you can after that probably do something like (pseudo-code, I haven't tested):

proj4.defs["EPSG:2154"] = "+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";

function lambert93toWGPS(lambertE, lambertN) {
    return proj4('EPSG:2154', 'WGS84', [lambertE, lambertN]);
}

Otherwise, a good old copy/pasta will do the job (and you will even be able to rename constantes to constants) :)

@hAbd0u
Copy link

hAbd0u commented Apr 6, 2020

Thanks, this will save me time to convert it to C#.

@Thibzzz
Copy link

Thibzzz commented Apr 7, 2021

Hello I've had to make a Lambert CC Zone 49 version today in ES6 so here it is.

Thanks a lot. I grabbed the constants from your link and updated it accordingly.

// Référentiel IAG GRS 80 / Constantes Lambert-CC zone 49
const geodesicReferential = {
  GRS80E: 0.08181919112,
  LONG_0: 3, // OK
  XS: 1700000.00, // OK
  YS: 13754395.745, // OK
  n: 0.75473138518, // OK
  C: 11626445.901, // OK
};

const findGPSFromLambertCC = (lambertE, lambertN) => {
  const delX = lambertE - geodesicReferential.XS;
  const delY = lambertN - geodesicReferential.YS;
  const gamma = Math.atan(-delX / delY);
  const R = Math.sqrt(delX * delX + delY * delY);
  const latiso = Math.log(geodesicReferential.C / R) / geodesicReferential.n;
  const sinPhiit0 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * Math.sin(1))
  );
  const sinPhiit1 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit0)
  );
  const sinPhiit2 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit1)
  );
  const sinPhiit3 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit2)
  );
  const sinPhiit4 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit3)
  );
  const sinPhiit5 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit4)
  );
  const sinPhiit6 = Math.tanh(
    latiso +
      geodesicReferential.GRS80E *
        Math.atanh(geodesicReferential.GRS80E * sinPhiit5)
  );

  const longRad = Math.asin(sinPhiit6);
  const latRad =
    gamma / geodesicReferential.n +
    (geodesicReferential.LONG_0 / 180) * Math.PI;

  const longitude = (latRad / Math.PI) * 180;
  const latitude = (longRad / Math.PI) * 180;

  return { lon: longitude, lat: latitude };
  
};
export { findGPSFromLambertCC, geodesicReferential };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment