Skip to content

Commit 1100657

Browse files
committed
Merge pull request #3 from eservent/master
Add Conversion From WGS84 To Lambert
2 parents 28d1598 + 3c12d0a commit 1100657

File tree

5 files changed

+317
-59
lines changed

5 files changed

+317
-59
lines changed

docs/NTG_71.pdf

68 KB
Binary file not shown.

docs/NTG_80.pdf

65.4 KB
Binary file not shown.
745 KB
Binary file not shown.

src/main/java/net/yageek/lambert/Lambert.java

+183-53
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,137 @@
11
package net.yageek.lambert;
22

33

4+
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
5+
46
import static java.lang.Math.*;
57
import static net.yageek.lambert.LambertZone.*;
68

7-
public class Lambert {
9+
/*
10+
https://github.com/yageek/lambert-java
11+
https://bintray.com/yageek/maven/lambert-java/view/files/net/yageek/lambert/lambert-java/1.1
12+
13+
Online samples :
14+
http://geofree.fr/gf/coordinateConv.asp#listSys
15+
16+
--------------------------------------------------------------------------------------
17+
Install cs2cs on Ubuntu :
18+
http://www.sarasafavi.com/installing-gdalogr-on-ubuntu.html
19+
20+
--------------------------------------------------------------------------------------
21+
http://cs2cs.mygeodata.eu/
22+
Conversion From Lambert Zone II to WGS 84 :
23+
$>cs2cs +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs +to +proj=longlat +datum=WGS84 +no_defs -f "%.11f" <<EOF
24+
> 618115 2430676
25+
> EOF
26+
27+
2.58331732871 48.87414278182 43.05512374267
28+
29+
--------------------------------------------------------------------------------------
30+
Conversion From WGS 84 To Lambert Zone II:
31+
$>cs2cs +proj=longlat +datum=WGS84 +no_defs +to +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs -f "%.11f" <<EOF
32+
2.58331732871 48.8741427818
33+
EOF
34+
618115.00035284588 2430676.00004872493 -43.05512374081
35+
*/
836

9-
/*
10-
* ALGO0002
37+
38+
/*
39+
Documentations :
40+
http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/notice/NTG_71.pdf
41+
http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/notice/NTG_80.pdf
42+
http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/TransformationsCoordonneesGeodesiques.pdf
1143
*/
12-
private static double latitudeFromLatitudeISO(double latISo, double e, double eps)
13-
{
44+
public class Lambert {
45+
46+
/*
47+
* ALGO0001
48+
*/
49+
public static double latitudeISOFromLat(double lat, double e) {
50+
double elt11 = Math.PI / 4d;
51+
double elt12 = lat / 2d;
52+
double elt1 = tan(elt11 + elt12);
53+
54+
double elt21 = e * sin(lat);
55+
double elt2 = pow((1 - elt21) / (1 + elt21), e / 2d);
56+
57+
return log(elt1 * elt2);
58+
}
59+
1460

15-
double phi0 = 2* atan(exp(latISo)) - M_PI_2;
16-
double phiI = 2*atan(pow((1+e*sin(phi0))/(1-e*sin(phi0)),e/2.0)*exp(latISo)) - M_PI_2;
61+
/*
62+
* ALGO0002
63+
*/
64+
private static double latitudeFromLatitudeISO(double latISo, double e, double eps) {
65+
66+
double phi0 = 2 * atan(exp(latISo)) - M_PI_2;
67+
double phiI = 2 * atan(pow((1 + e * sin(phi0)) / (1 - e * sin(phi0)), e / 2d) * exp(latISo)) - M_PI_2;
1768
double delta = abs(phiI - phi0);
1869

19-
while(delta > eps)
20-
{
70+
while (delta > eps) {
2171
phi0 = phiI;
22-
phiI = 2*atan(pow((1+e*sin(phi0))/(1-e*sin(phi0)),e/2.0)*exp(latISo)) - M_PI_2;
72+
phiI = 2 * atan(pow((1 + e * sin(phi0)) / (1 - e * sin(phi0)), e / 2d) * exp(latISo)) - M_PI_2;
2373
delta = abs(phiI - phi0);
2474
}
2575

2676
return phiI;
77+
}
78+
79+
80+
/*
81+
* ALGO0003
82+
*/
83+
public static LambertPoint geographicToLambertAlg003(double latitude, double longitude, LambertZone zone, double lonMeridian, double e) {
84+
85+
double n = zone.n();
86+
double C = zone.c();
87+
double xs = zone.xs();
88+
double ys = zone.ys();
89+
90+
double latIso = latitudeISOFromLat(latitude, e);
91+
92+
double eLatIso = exp(-n * latIso);
93+
94+
double nLon = n * (longitude - lonMeridian);
95+
96+
double x = xs + C * eLatIso * sin(nLon);
97+
double y = ys - C * eLatIso * cos(nLon);
98+
99+
return new LambertPoint(x, y, 0);
100+
}
101+
102+
/*
103+
* http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/TransformationsCoordonneesGeodesiques.pdf
104+
* 3.4 Coordonnées géographiques Lambert
105+
*/
106+
public static LambertPoint geographicToLambert(double latitude, double longitude, LambertZone zone, double lonMeridian, double e) {
107+
108+
double n = zone.n();
109+
double C = zone.c();
110+
double xs = zone.xs();
111+
double ys = zone.ys();
112+
113+
double sinLat = sin(latitude);
114+
double eSinLat = (e * sinLat);
115+
double elt1 = (1 + sinLat) / (1 - sinLat);
116+
double elt2 = (1 + eSinLat) / (1 - eSinLat);
117+
118+
double latIso = (1 / 2d) * log(elt1) - (e / 2d) * log(elt2);
27119

120+
double R = C * exp(-(n * latIso));
121+
122+
double LAMBDA = n * (longitude - lonMeridian);
123+
124+
double x = xs + (R * sin(LAMBDA));
125+
double y = ys - (R * cos(LAMBDA));
126+
127+
return new LambertPoint(x, y, 0);
28128
}
29129

30130
/*
31131
* ALGO0004 - Lambert vers geographiques
32132
*/
33133

34-
private static LambertPoint lambertToGeographic(LambertPoint org, LambertZone zone, double lonMeridian, double e, double eps)
35-
{
134+
public static LambertPoint lambertToGeographic(LambertPoint org, LambertZone zone, double lonMeridian, double e, double eps) {
36135
double n = zone.n();
37136
double C = zone.c();
38137
double xs = zone.xs();
@@ -46,43 +145,40 @@ private static LambertPoint lambertToGeographic(LambertPoint org, LambertZone zo
46145

47146
R = sqrt((x - xs) * (x - xs) + (y - ys) * (y - ys));
48147

49-
gamma = atan((x-xs)/(ys-y));
148+
gamma = atan((x - xs) / (ys - y));
50149

51-
lon = lonMeridian + gamma/n;
150+
lon = lonMeridian + gamma / n;
52151

53-
latIso = -1/n*log(abs(R/C));
152+
latIso = -1 / n * log(abs(R / C));
54153

55154
double lat = latitudeFromLatitudeISO(latIso, e, eps);
56155

57-
LambertPoint dest = new LambertPoint(lon,lat,0);
58-
return dest;
156+
return new LambertPoint(lon, lat, 0);
59157
}
60158

61159
/*
62160
* ALGO0021 - Calcul de la grande Normale
63161
*
64162
*/
65163

66-
private static double lambertNormal(double lat, double a, double e)
67-
{
164+
private static double lambertNormal(double lat, double a, double e) {
68165

69-
return a/sqrt(1-e*e*sin(lat)*sin(lat));
166+
return a / sqrt(1 - e * e * sin(lat) * sin(lat));
70167
}
71168

72169
/*
73170
* ALGO0009 - Transformations geographiques -> cartésiennes
74171
*
75172
*/
76173

77-
private static LambertPoint geographicToCartesian(double lon, double lat, double he, double a, double e)
78-
{
174+
private static LambertPoint geographicToCartesian(double lon, double lat, double he, double a, double e) {
79175
double N = lambertNormal(lat, a, e);
80176

81-
LambertPoint pt = new LambertPoint(0,0,0);
177+
LambertPoint pt = new LambertPoint(0, 0, 0);
82178

83-
pt.setX((N+he)*cos(lat)*cos(lon));
84-
pt.setY((N+he)*cos(lat)*sin(lon));
85-
pt.setZ((N*(1-e*e)+he)*sin(lat));
179+
pt.setX((N + he) * cos(lat) * cos(lon));
180+
pt.setY((N + he) * cos(lat) * sin(lon));
181+
pt.setZ((N * (1 - e * e) + he) * sin(lat));
86182

87183
return pt;
88184

@@ -92,64 +188,98 @@ private static LambertPoint geographicToCartesian(double lon, double lat, double
92188
* ALGO0012 - Passage des coordonnées cartésiennes aux coordonnées géographiques
93189
*/
94190

95-
private static LambertPoint cartesianToGeographic(LambertPoint org, double meridien, double a, double e, double eps)
96-
{
191+
private static LambertPoint cartesianToGeographic(LambertPoint org, double meridien, double a, double e, double eps) {
97192
double x = org.getX(), y = org.getY(), z = org.getZ();
98193

99-
double lon = meridien + atan(y/x);
194+
double lon = meridien + atan(y / x);
100195

101-
double module = sqrt(x*x + y*y);
196+
double module = sqrt(x * x + y * y);
102197

103-
double phi0 = atan(z/(module*(1-(a*e*e)/sqrt(x*x+y*y+z*z))));
104-
double phiI = atan(z/module/(1-a*e*e*cos(phi0)/(module * sqrt(1-e*e*sin(phi0)*sin(phi0)))));
105-
double delta= abs(phiI - phi0);
106-
while(delta > eps)
107-
{
198+
double phi0 = atan(z / (module * (1 - (a * e * e) / sqrt(x * x + y * y + z * z))));
199+
double phiI = atan(z / module / (1 - a * e * e * cos(phi0) / (module * sqrt(1 - e * e * sin(phi0) * sin(phi0)))));
200+
double delta = abs(phiI - phi0);
201+
while (delta > eps) {
108202
phi0 = phiI;
109-
phiI = atan(z/module/(1-a*e*e*cos(phi0)/(module * sqrt(1-e*e*sin(phi0)*sin(phi0)))));
110-
delta= abs(phiI - phi0);
203+
phiI = atan(z / module / (1 - a * e * e * cos(phi0) / (module * sqrt(1 - e * e * sin(phi0) * sin(phi0)))));
204+
delta = abs(phiI - phi0);
111205

112206
}
113207

114-
double he = module/cos(phiI) - a/sqrt(1-e*e*sin(phiI)*sin(phiI));
115-
116-
LambertPoint pt = new LambertPoint(lon,phiI,he);
208+
double he = module / cos(phiI) - a / sqrt(1 - e * e * sin(phiI) * sin(phiI));
117209

118-
return pt;
210+
return new LambertPoint(lon, phiI, he);
119211
}
212+
120213
/*
121214
* Convert Lambert -> WGS84
122215
* http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/transfo.pdf
123216
*
124217
*/
125218

126-
public static LambertPoint convertToWGS84(LambertPoint org, LambertZone zone){
219+
public static LambertPoint convertToWGS84(LambertPoint org, LambertZone zone) {
127220

128-
if(zone == Lambert93)
129-
{
130-
return lambertToGeographic(org,Lambert93,LON_MERID_IERS,E_WGS84,DEFAULT_EPS);
131-
}
132-
else {
133-
LambertPoint pt1 = lambertToGeographic(org, zone, LON_MERID_PARIS, E_CLARK_IGN, DEFAULT_EPS);
221+
if (zone == Lambert93) {
222+
return lambertToGeographic(org, Lambert93, LON_MERID_IERS, E_WGS84, DEFAULT_EPS);
223+
} else {
224+
LambertPoint pt1 = lambertToGeographic(org, zone, LON_MERID_PARIS, E_CLARK_IGN, DEFAULT_EPS);
134225

135226
LambertPoint pt2 = geographicToCartesian(pt1.getX(), pt1.getY(), pt1.getZ(), A_CLARK_IGN, E_CLARK_IGN);
136227

137-
pt2.translate(-168,-60,320);
228+
pt2.translate(-168, -60, 320);
138229

139230
//WGS84 refers to greenwich
140231
return cartesianToGeographic(pt2, LON_MERID_GREENWICH, A_WGS84, E_WGS84, DEFAULT_EPS);
141232
}
142233
}
143234

144-
public static LambertPoint convertToWGS84(double x, double y, LambertZone zone){
235+
/*
236+
* Convert WGS84 -> Lambert
237+
* http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/transfo.pdf
238+
*
239+
*/
240+
241+
public static LambertPoint convertToLambert(double latitude, double longitude, LambertZone zone) throws NotImplementedException {
242+
243+
if (zone == Lambert93) {
244+
throw new NotImplementedException();
245+
} else {
246+
LambertPoint pt1 = geographicToCartesian(longitude - LON_MERID_GREENWICH, latitude, 0, A_WGS84, E_WGS84);
247+
248+
pt1.translate(168, 60, -320);
249+
250+
LambertPoint pt2 = cartesianToGeographic(pt1, LON_MERID_PARIS, A_WGS84, E_WGS84, DEFAULT_EPS);
251+
252+
return geographicToLambert(pt2.getY(), pt2.getX(), zone, LON_MERID_PARIS, E_WGS84);
253+
}
254+
}
255+
256+
/*
257+
Method not really usefull, just to have two ways of doing the same conversion.
258+
*/
259+
public static LambertPoint convertToLambertByAlg003(double latitude, double longitude, LambertZone zone) throws NotImplementedException {
260+
261+
if (zone == Lambert93) {
262+
throw new NotImplementedException();
263+
} else {
264+
LambertPoint pt1 = geographicToCartesian(longitude - LON_MERID_GREENWICH, latitude, 0, A_WGS84, E_WGS84);
265+
266+
pt1.translate(168, 60, -320);
267+
268+
LambertPoint pt2 = cartesianToGeographic(pt1, LON_MERID_PARIS, A_WGS84, E_WGS84, DEFAULT_EPS);
269+
270+
return geographicToLambertAlg003(pt2.getY(), pt2.getX(), zone, LON_MERID_PARIS, E_WGS84);
271+
}
272+
}
273+
274+
public static LambertPoint convertToWGS84(double x, double y, LambertZone zone) {
145275

146-
LambertPoint pt = new LambertPoint(x,y,0);
276+
LambertPoint pt = new LambertPoint(x, y, 0);
147277
return convertToWGS84(pt, zone);
148278
}
149279

150-
public static LambertPoint convertToWGS84Deg(double x, double y, LambertZone zone){
280+
public static LambertPoint convertToWGS84Deg(double x, double y, LambertZone zone) {
151281

152-
LambertPoint pt = new LambertPoint(x,y,0);
282+
LambertPoint pt = new LambertPoint(x, y, 0);
153283
return convertToWGS84(pt, zone).toDegree();
154284
}
155285

0 commit comments

Comments
 (0)