11package net .yageek .lambert ;
22
33
4+ import sun .reflect .generics .reflectiveObjects .NotImplementedException ;
5+
46import static java .lang .Math .*;
57import 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