lambert_ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/ext/lambert_ruby/extconf.rb +3 -0
- data/ext/lambert_ruby/lambert.c +171 -0
- data/ext/lambert_ruby/lambert.h +71 -0
- data/ext/lambert_ruby/lambert/src/lambert.c +171 -0
- data/ext/lambert_ruby/lambert/src/lambert.h +71 -0
- data/ext/lambert_ruby/lambert/tests/test_lambert_cunit.c +195 -0
- data/ext/lambert_ruby/lambert_ruby.c +69 -0
- data/lib/lambert_ruby.rb +1 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NzM5YmI2MWY2OWFhZTVlZmE4ODQ1NGU5YWYzZmU3NGYwNjljYzY3ZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWM1NWNiNTBlOWIyMGMzZDFjNGYyZmIyZGVjZTEwMjZmYmE1NDk3MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YmI2ZmIwNDkxMjk2YjMwYTQzY2I3OTY0MTE0MmI1NWNjNjVhMjg3M2QyYmVh
|
10
|
+
MmY5ODVkNjQ0M2IwMzE0ZmQzYjcxZDJhNjU2ZDQzNGI3NTA5YTNiODE1MTc4
|
11
|
+
YzA5YzQ3MGY5YTI0ZGViZWEzNjBiZTg1YmNkNDU3OGVhYWQxOWE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTUzODYwZmQyYzQ2YTMwY2I4MDE2ZjRjOThlOTVhN2YxYzQwYWQyMDUwZjIw
|
14
|
+
YmU5MzRkN2EzNWU1N2VkNzBhMjU3ZGY0ZTE4MmY4M2IxM2IyOGFhY2ZjMDJi
|
15
|
+
ODVjMTg4NjM4Zjk3YWUyOWYwOTgxOTJlOTgwZWNhNzYzMzM0MWE=
|
@@ -0,0 +1,171 @@
|
|
1
|
+
/*
|
2
|
+
* Source des algorithmes : http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/notice/NTG_71.pdf
|
3
|
+
*
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "lambert.h"
|
7
|
+
#include <math.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
|
10
|
+
#define RAD_TO_DEG(x) x*180/M_PI
|
11
|
+
|
12
|
+
#define DISPLAY_YGLambertPoint(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint.x,YGLambertPoint.y,YGLambertPoint.z);
|
13
|
+
#define DISPLAY_YGLambertPoint_REF(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint->x,YGLambertPoint->y,YGLambertPoint->z);
|
14
|
+
|
15
|
+
static double lambert_n[6] = {0.7604059656, 0.7289686274, 0.6959127966, 0.6712679322, 0.7289686274, 0.7256077650};
|
16
|
+
static double lambert_c[6] = {11603796.98, 11745793.39, 11947992.52, 12136281.99, 11745793.39, 11754255.426};
|
17
|
+
static double lambert_xs[6]= {600000.0, 600000.0, 600000.0, 234.358, 600000.0, 700000.0};
|
18
|
+
static double lambert_ys[6]= {5657616.674, 6199695.768, 6791905.085, 7239161.542, 8199695.768, 12655612.050};
|
19
|
+
|
20
|
+
|
21
|
+
/*
|
22
|
+
* ALGO0002
|
23
|
+
*/
|
24
|
+
|
25
|
+
double lat_from_lat_iso(double lat_iso, double e,double eps)
|
26
|
+
{
|
27
|
+
|
28
|
+
double phi_0 = 2*atan(exp(lat_iso)) - M_PI_2;
|
29
|
+
double phi_i = 2*atan(pow((1+e*sin(phi_0))/(1-e*sin(phi_0)),e/2.0)*exp(lat_iso)) - M_PI_2;
|
30
|
+
double delta ;
|
31
|
+
while(delta = fabs(phi_i - phi_0),delta > eps)
|
32
|
+
{
|
33
|
+
phi_0 = phi_i;
|
34
|
+
phi_i = 2*atan(pow((1+e*sin(phi_0))/(1-e*sin(phi_0)),e/2.0)*exp(lat_iso)) - M_PI_2;
|
35
|
+
}
|
36
|
+
|
37
|
+
return phi_i;
|
38
|
+
|
39
|
+
}
|
40
|
+
/*
|
41
|
+
* ALGO0004 - Lambert vers geographiques
|
42
|
+
*/
|
43
|
+
|
44
|
+
void lambert_to_geographic(const YGLambertPoint * org,YGLambertPoint *dest, LambertZone zone, double lon_merid, double e, double eps)
|
45
|
+
{
|
46
|
+
double n = lambert_n[zone];
|
47
|
+
double C = lambert_c[zone];
|
48
|
+
double x_s = lambert_xs[zone];
|
49
|
+
double y_s = lambert_ys[zone];
|
50
|
+
|
51
|
+
double x = org->x;
|
52
|
+
double y = org->y;
|
53
|
+
|
54
|
+
double lon, gamma, R, lat_iso;
|
55
|
+
|
56
|
+
R = sqrt((x-x_s)*(x-x_s)+(y-y_s)*(y-y_s));
|
57
|
+
|
58
|
+
gamma = atan((x-x_s)/(y_s-y));
|
59
|
+
|
60
|
+
lon = lon_merid + gamma/n;
|
61
|
+
|
62
|
+
lat_iso = -1/n*log(fabs(R/C));
|
63
|
+
|
64
|
+
double lat = lat_from_lat_iso(lat_iso,e,eps);
|
65
|
+
|
66
|
+
dest->x = lon;
|
67
|
+
dest->y = lat;
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
/*
|
72
|
+
* ALGO0021 - Calcul de la grande Normale
|
73
|
+
*
|
74
|
+
*/
|
75
|
+
|
76
|
+
double lambert_normal(double lat, double a, double e)
|
77
|
+
{
|
78
|
+
|
79
|
+
return a/sqrt(1-e*e*sin(lat)*sin(lat));
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* ALGO0009 - Transformations geographiques -> cartésiennes
|
84
|
+
*
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
|
88
|
+
YGLambertPoint geographic_to_cartesian(double lon, double lat, double he, double a, double e)
|
89
|
+
{
|
90
|
+
double N = lambert_normal(lat,a,e);
|
91
|
+
|
92
|
+
YGLambertPoint pt = {0,0,0};
|
93
|
+
pt.x = (N+he)*cos(lat)*cos(lon);
|
94
|
+
|
95
|
+
pt.y = (N+he)*cos(lat)*sin(lon);
|
96
|
+
|
97
|
+
pt.z = (N*(1-e*e)+he)*sin(lat);
|
98
|
+
|
99
|
+
return pt;
|
100
|
+
|
101
|
+
}
|
102
|
+
|
103
|
+
/*
|
104
|
+
* ALGO0012 - Passage des coordonnées cartésiennes aux coordonnées géographiques
|
105
|
+
*/
|
106
|
+
|
107
|
+
YGLambertPoint cartesian_to_geographic(YGLambertPoint org, double meridien, double a, double e , double eps)
|
108
|
+
{
|
109
|
+
double x = org.x, y = org.y, z = org.z;
|
110
|
+
|
111
|
+
double lon = meridien + atan(y/x);
|
112
|
+
|
113
|
+
double module = sqrt(x*x + y*y);
|
114
|
+
|
115
|
+
double phi_0 = atan(z/(module*(1-(a*e*e)/sqrt(x*x+y*y+z*z))));
|
116
|
+
double phi_i = atan(z/module/(1-a*e*e*cos(phi_0)/(module * sqrt(1-e*e*sin(phi_0)*sin(phi_0)))));
|
117
|
+
double delta;
|
118
|
+
while(delta = fabs(phi_i - phi_0),delta > eps)
|
119
|
+
{
|
120
|
+
phi_0 = phi_i;
|
121
|
+
phi_i = atan(z/module/(1-a*e*e*cos(phi_0)/(module * sqrt(1-e*e*sin(phi_0)*sin(phi_0)))));
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
double he = module/cos(phi_i) - a/sqrt(1-e*e*sin(phi_i)*sin(phi_i));
|
126
|
+
|
127
|
+
YGLambertPoint pt;
|
128
|
+
pt.x = lon;
|
129
|
+
pt.y = phi_i;
|
130
|
+
pt.z = he;
|
131
|
+
|
132
|
+
return pt;
|
133
|
+
}
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
/*
|
138
|
+
* Convert Lambert -> WGS84
|
139
|
+
* http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/transfo.pdf
|
140
|
+
*
|
141
|
+
*/
|
142
|
+
|
143
|
+
void lambert_to_wgs84(const YGLambertPoint * org, YGLambertPoint *dest,LambertZone zone){
|
144
|
+
|
145
|
+
lambert_to_geographic(org,dest,zone,LON_MERID_PARIS,E_CLARK_IGN,DEFAULT_EPS);
|
146
|
+
|
147
|
+
YGLambertPoint temp = geographic_to_cartesian(dest->x,dest->y,dest->z,A_CLARK_IGN,E_CLARK_IGN);
|
148
|
+
|
149
|
+
temp.x= temp.x - 168;
|
150
|
+
temp.y= temp.y - 60;
|
151
|
+
temp.z= temp.z + 320;
|
152
|
+
|
153
|
+
//WGS84 refers to greenwich
|
154
|
+
temp = cartesian_to_geographic(temp, LON_MERID_GREENWICH, A_WGS84,E_WGS84,DEFAULT_EPS);
|
155
|
+
|
156
|
+
dest->x = temp.x;
|
157
|
+
dest->y = temp.y;
|
158
|
+
|
159
|
+
}
|
160
|
+
|
161
|
+
|
162
|
+
void lambert_to_wgs84_deg(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone)
|
163
|
+
{
|
164
|
+
YGLambertPoint temp = {0,0,0};
|
165
|
+
|
166
|
+
lambert_to_wgs84(org,&temp,zone);
|
167
|
+
|
168
|
+
dest->x = temp.x * 180/M_PI;
|
169
|
+
dest->y = temp.y * 180/M_PI;
|
170
|
+
dest->z = temp.z * 180/M_PI;
|
171
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#define DEFAULT_EPS 1e-10
|
2
|
+
#define E_CLARK_IGN 0.08248325676
|
3
|
+
#define E_WGS84 0.08181919106
|
4
|
+
|
5
|
+
#define A_CLARK_IGN 6378249.2
|
6
|
+
#define A_WGS84 6378137.0
|
7
|
+
|
8
|
+
#define LON_MERID_PARIS 0
|
9
|
+
#define LON_MERID_GREENWICH 0.04079234433
|
10
|
+
|
11
|
+
#define DISPLAY_YGLambertPoint(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint.x,YGLambertPoint.y,YGLambertPoint.z);
|
12
|
+
#define DISPLAY_YGLambertPoint_REF(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint->x,YGLambertPoint->y,YGLambertPoint->z);
|
13
|
+
|
14
|
+
typedef enum {
|
15
|
+
LAMBERT_I=0,
|
16
|
+
LAMBERT_II=1,
|
17
|
+
LAMBERT_III=2,
|
18
|
+
LAMBERT_IV=3,
|
19
|
+
LAMBERT_II_E=4,
|
20
|
+
LAMBERT_93= 5
|
21
|
+
} LambertZone;
|
22
|
+
|
23
|
+
typedef struct {
|
24
|
+
double x;
|
25
|
+
double y;
|
26
|
+
double z;
|
27
|
+
} YGLambertPoint;
|
28
|
+
|
29
|
+
|
30
|
+
/*
|
31
|
+
* ALGO0021 - Calcul de la grande Normale
|
32
|
+
*
|
33
|
+
*/
|
34
|
+
double lambert_normal(double lat, double a, double e);
|
35
|
+
|
36
|
+
/*
|
37
|
+
* Convert a YGLambertPoint struct from one lambert zone to WGS84 (Rad)
|
38
|
+
*
|
39
|
+
*/
|
40
|
+
void lambert_to_wgs84(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone);
|
41
|
+
|
42
|
+
/*
|
43
|
+
* Convert a YGLambertPoint struct from one lambert zone to WGS84 (Deg)
|
44
|
+
*
|
45
|
+
*/
|
46
|
+
void lambert_to_wgs84_deg(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone);
|
47
|
+
|
48
|
+
/*
|
49
|
+
* ALGO0002
|
50
|
+
*/
|
51
|
+
|
52
|
+
double lat_from_lat_iso(double lat_iso, double e, double eps);
|
53
|
+
|
54
|
+
/*
|
55
|
+
* ALGO0012
|
56
|
+
*/
|
57
|
+
|
58
|
+
YGLambertPoint cartesian_to_geographic(YGLambertPoint org, double meridien, double a, double e , double eps);
|
59
|
+
|
60
|
+
/*
|
61
|
+
* ALGO004
|
62
|
+
*/
|
63
|
+
void lambert_to_geographic(const YGLambertPoint * org,YGLambertPoint *dest, LambertZone zone, double lon_merid, double e, double eps);
|
64
|
+
|
65
|
+
/**
|
66
|
+
* ALGO0009 - Transformations geographiques -> cartésiennes
|
67
|
+
*
|
68
|
+
*
|
69
|
+
*/
|
70
|
+
|
71
|
+
YGLambertPoint geographic_to_cartesian(double lon, double lat, double he, double a, double e);
|
@@ -0,0 +1,171 @@
|
|
1
|
+
/*
|
2
|
+
* Source des algorithmes : http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/notice/NTG_71.pdf
|
3
|
+
*
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "lambert.h"
|
7
|
+
#include <math.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
|
10
|
+
#define RAD_TO_DEG(x) x*180/M_PI
|
11
|
+
|
12
|
+
#define DISPLAY_YGLambertPoint(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint.x,YGLambertPoint.y,YGLambertPoint.z);
|
13
|
+
#define DISPLAY_YGLambertPoint_REF(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint->x,YGLambertPoint->y,YGLambertPoint->z);
|
14
|
+
|
15
|
+
static double lambert_n[6] = {0.7604059656, 0.7289686274, 0.6959127966, 0.6712679322, 0.7289686274, 0.7256077650};
|
16
|
+
static double lambert_c[6] = {11603796.98, 11745793.39, 11947992.52, 12136281.99, 11745793.39, 11754255.426};
|
17
|
+
static double lambert_xs[6]= {600000.0, 600000.0, 600000.0, 234.358, 600000.0, 700000.0};
|
18
|
+
static double lambert_ys[6]= {5657616.674, 6199695.768, 6791905.085, 7239161.542, 8199695.768, 12655612.050};
|
19
|
+
|
20
|
+
|
21
|
+
/*
|
22
|
+
* ALGO0002
|
23
|
+
*/
|
24
|
+
|
25
|
+
double lat_from_lat_iso(double lat_iso, double e,double eps)
|
26
|
+
{
|
27
|
+
|
28
|
+
double phi_0 = 2*atan(exp(lat_iso)) - M_PI_2;
|
29
|
+
double phi_i = 2*atan(pow((1+e*sin(phi_0))/(1-e*sin(phi_0)),e/2.0)*exp(lat_iso)) - M_PI_2;
|
30
|
+
double delta ;
|
31
|
+
while(delta = fabs(phi_i - phi_0),delta > eps)
|
32
|
+
{
|
33
|
+
phi_0 = phi_i;
|
34
|
+
phi_i = 2*atan(pow((1+e*sin(phi_0))/(1-e*sin(phi_0)),e/2.0)*exp(lat_iso)) - M_PI_2;
|
35
|
+
}
|
36
|
+
|
37
|
+
return phi_i;
|
38
|
+
|
39
|
+
}
|
40
|
+
/*
|
41
|
+
* ALGO0004 - Lambert vers geographiques
|
42
|
+
*/
|
43
|
+
|
44
|
+
void lambert_to_geographic(const YGLambertPoint * org,YGLambertPoint *dest, LambertZone zone, double lon_merid, double e, double eps)
|
45
|
+
{
|
46
|
+
double n = lambert_n[zone];
|
47
|
+
double C = lambert_c[zone];
|
48
|
+
double x_s = lambert_xs[zone];
|
49
|
+
double y_s = lambert_ys[zone];
|
50
|
+
|
51
|
+
double x = org->x;
|
52
|
+
double y = org->y;
|
53
|
+
|
54
|
+
double lon, gamma, R, lat_iso;
|
55
|
+
|
56
|
+
R = sqrt((x-x_s)*(x-x_s)+(y-y_s)*(y-y_s));
|
57
|
+
|
58
|
+
gamma = atan((x-x_s)/(y_s-y));
|
59
|
+
|
60
|
+
lon = lon_merid + gamma/n;
|
61
|
+
|
62
|
+
lat_iso = -1/n*log(fabs(R/C));
|
63
|
+
|
64
|
+
double lat = lat_from_lat_iso(lat_iso,e,eps);
|
65
|
+
|
66
|
+
dest->x = lon;
|
67
|
+
dest->y = lat;
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
/*
|
72
|
+
* ALGO0021 - Calcul de la grande Normale
|
73
|
+
*
|
74
|
+
*/
|
75
|
+
|
76
|
+
double lambert_normal(double lat, double a, double e)
|
77
|
+
{
|
78
|
+
|
79
|
+
return a/sqrt(1-e*e*sin(lat)*sin(lat));
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* ALGO0009 - Transformations geographiques -> cartésiennes
|
84
|
+
*
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
|
88
|
+
YGLambertPoint geographic_to_cartesian(double lon, double lat, double he, double a, double e)
|
89
|
+
{
|
90
|
+
double N = lambert_normal(lat,a,e);
|
91
|
+
|
92
|
+
YGLambertPoint pt = {0,0,0};
|
93
|
+
pt.x = (N+he)*cos(lat)*cos(lon);
|
94
|
+
|
95
|
+
pt.y = (N+he)*cos(lat)*sin(lon);
|
96
|
+
|
97
|
+
pt.z = (N*(1-e*e)+he)*sin(lat);
|
98
|
+
|
99
|
+
return pt;
|
100
|
+
|
101
|
+
}
|
102
|
+
|
103
|
+
/*
|
104
|
+
* ALGO0012 - Passage des coordonnées cartésiennes aux coordonnées géographiques
|
105
|
+
*/
|
106
|
+
|
107
|
+
YGLambertPoint cartesian_to_geographic(YGLambertPoint org, double meridien, double a, double e , double eps)
|
108
|
+
{
|
109
|
+
double x = org.x, y = org.y, z = org.z;
|
110
|
+
|
111
|
+
double lon = meridien + atan(y/x);
|
112
|
+
|
113
|
+
double module = sqrt(x*x + y*y);
|
114
|
+
|
115
|
+
double phi_0 = atan(z/(module*(1-(a*e*e)/sqrt(x*x+y*y+z*z))));
|
116
|
+
double phi_i = atan(z/module/(1-a*e*e*cos(phi_0)/(module * sqrt(1-e*e*sin(phi_0)*sin(phi_0)))));
|
117
|
+
double delta;
|
118
|
+
while(delta = fabs(phi_i - phi_0),delta > eps)
|
119
|
+
{
|
120
|
+
phi_0 = phi_i;
|
121
|
+
phi_i = atan(z/module/(1-a*e*e*cos(phi_0)/(module * sqrt(1-e*e*sin(phi_0)*sin(phi_0)))));
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
double he = module/cos(phi_i) - a/sqrt(1-e*e*sin(phi_i)*sin(phi_i));
|
126
|
+
|
127
|
+
YGLambertPoint pt;
|
128
|
+
pt.x = lon;
|
129
|
+
pt.y = phi_i;
|
130
|
+
pt.z = he;
|
131
|
+
|
132
|
+
return pt;
|
133
|
+
}
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
/*
|
138
|
+
* Convert Lambert -> WGS84
|
139
|
+
* http://geodesie.ign.fr/contenu/fichiers/documentation/pedagogiques/transfo.pdf
|
140
|
+
*
|
141
|
+
*/
|
142
|
+
|
143
|
+
void lambert_to_wgs84(const YGLambertPoint * org, YGLambertPoint *dest,LambertZone zone){
|
144
|
+
|
145
|
+
lambert_to_geographic(org,dest,zone,LON_MERID_PARIS,E_CLARK_IGN,DEFAULT_EPS);
|
146
|
+
|
147
|
+
YGLambertPoint temp = geographic_to_cartesian(dest->x,dest->y,dest->z,A_CLARK_IGN,E_CLARK_IGN);
|
148
|
+
|
149
|
+
temp.x= temp.x - 168;
|
150
|
+
temp.y= temp.y - 60;
|
151
|
+
temp.z= temp.z + 320;
|
152
|
+
|
153
|
+
//WGS84 refers to greenwich
|
154
|
+
temp = cartesian_to_geographic(temp, LON_MERID_GREENWICH, A_WGS84,E_WGS84,DEFAULT_EPS);
|
155
|
+
|
156
|
+
dest->x = temp.x;
|
157
|
+
dest->y = temp.y;
|
158
|
+
|
159
|
+
}
|
160
|
+
|
161
|
+
|
162
|
+
void lambert_to_wgs84_deg(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone)
|
163
|
+
{
|
164
|
+
YGLambertPoint temp = {0,0,0};
|
165
|
+
|
166
|
+
lambert_to_wgs84(org,&temp,zone);
|
167
|
+
|
168
|
+
dest->x = temp.x * 180/M_PI;
|
169
|
+
dest->y = temp.y * 180/M_PI;
|
170
|
+
dest->z = temp.z * 180/M_PI;
|
171
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#define DEFAULT_EPS 1e-10
|
2
|
+
#define E_CLARK_IGN 0.08248325676
|
3
|
+
#define E_WGS84 0.08181919106
|
4
|
+
|
5
|
+
#define A_CLARK_IGN 6378249.2
|
6
|
+
#define A_WGS84 6378137.0
|
7
|
+
|
8
|
+
#define LON_MERID_PARIS 0
|
9
|
+
#define LON_MERID_GREENWICH 0.04079234433
|
10
|
+
|
11
|
+
#define DISPLAY_YGLambertPoint(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint.x,YGLambertPoint.y,YGLambertPoint.z);
|
12
|
+
#define DISPLAY_YGLambertPoint_REF(YGLambertPoint) printf(#YGLambertPoint" X:%f | Y:%f | Z:%f\n",YGLambertPoint->x,YGLambertPoint->y,YGLambertPoint->z);
|
13
|
+
|
14
|
+
typedef enum {
|
15
|
+
LAMBERT_I=0,
|
16
|
+
LAMBERT_II=1,
|
17
|
+
LAMBERT_III=2,
|
18
|
+
LAMBERT_IV=3,
|
19
|
+
LAMBERT_II_E=4,
|
20
|
+
LAMBERT_93= 5
|
21
|
+
} LambertZone;
|
22
|
+
|
23
|
+
typedef struct {
|
24
|
+
double x;
|
25
|
+
double y;
|
26
|
+
double z;
|
27
|
+
} YGLambertPoint;
|
28
|
+
|
29
|
+
|
30
|
+
/*
|
31
|
+
* ALGO0021 - Calcul de la grande Normale
|
32
|
+
*
|
33
|
+
*/
|
34
|
+
double lambert_normal(double lat, double a, double e);
|
35
|
+
|
36
|
+
/*
|
37
|
+
* Convert a YGLambertPoint struct from one lambert zone to WGS84 (Rad)
|
38
|
+
*
|
39
|
+
*/
|
40
|
+
void lambert_to_wgs84(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone);
|
41
|
+
|
42
|
+
/*
|
43
|
+
* Convert a YGLambertPoint struct from one lambert zone to WGS84 (Deg)
|
44
|
+
*
|
45
|
+
*/
|
46
|
+
void lambert_to_wgs84_deg(const YGLambertPoint * org, YGLambertPoint *dest, LambertZone zone);
|
47
|
+
|
48
|
+
/*
|
49
|
+
* ALGO0002
|
50
|
+
*/
|
51
|
+
|
52
|
+
double lat_from_lat_iso(double lat_iso, double e, double eps);
|
53
|
+
|
54
|
+
/*
|
55
|
+
* ALGO0012
|
56
|
+
*/
|
57
|
+
|
58
|
+
YGLambertPoint cartesian_to_geographic(YGLambertPoint org, double meridien, double a, double e , double eps);
|
59
|
+
|
60
|
+
/*
|
61
|
+
* ALGO004
|
62
|
+
*/
|
63
|
+
void lambert_to_geographic(const YGLambertPoint * org,YGLambertPoint *dest, LambertZone zone, double lon_merid, double e, double eps);
|
64
|
+
|
65
|
+
/**
|
66
|
+
* ALGO0009 - Transformations geographiques -> cartésiennes
|
67
|
+
*
|
68
|
+
*
|
69
|
+
*/
|
70
|
+
|
71
|
+
YGLambertPoint geographic_to_cartesian(double lon, double lat, double he, double a, double e);
|
@@ -0,0 +1,195 @@
|
|
1
|
+
#include <CUnit/Basic.h>
|
2
|
+
#include <CUnit/Console.h>
|
3
|
+
#include <CUnit/Automated.h>
|
4
|
+
#include <math.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include "../src/lambert.h"
|
7
|
+
|
8
|
+
#define DISPLAY_POINT(point) printf(#point" X:%f | Y:%f | Z:%f\n",point.x,point.y,point.z);
|
9
|
+
|
10
|
+
int init_suite_success(void) { return 0; }
|
11
|
+
int init_suite_failure(void) { return -1; }
|
12
|
+
int clean_suite_success(void) { return 0; }
|
13
|
+
int clean_suite_failure(void) { return -1; }
|
14
|
+
|
15
|
+
char buffer[20];
|
16
|
+
char format[20];
|
17
|
+
|
18
|
+
double truncate(double val, int n)
|
19
|
+
{
|
20
|
+
sprintf(format,"%%.%df",n);
|
21
|
+
sprintf(buffer,format,val);
|
22
|
+
return atof(buffer);
|
23
|
+
|
24
|
+
}
|
25
|
+
|
26
|
+
double rounded_down(double val,int n){
|
27
|
+
double p = pow(10,n);
|
28
|
+
return floorf(val*p)/p;
|
29
|
+
}
|
30
|
+
|
31
|
+
void test_lambert_deg(void)
|
32
|
+
{
|
33
|
+
YGLambertPoint org = {999534.581,112186.569,0};
|
34
|
+
YGLambertPoint dest = {0,0,0};
|
35
|
+
LambertZone zone = LAMBERT_I;
|
36
|
+
|
37
|
+
lambert_to_wgs84_deg(&org, &dest, zone);
|
38
|
+
printf("(Deg)Lon:%.11f - Lat:%.11f - H:%.11f\n",dest.x,dest.y,dest.z);
|
39
|
+
}
|
40
|
+
|
41
|
+
void test_lambert(void)
|
42
|
+
{
|
43
|
+
|
44
|
+
YGLambertPoint org = {999534.581,112186.569,0};
|
45
|
+
YGLambertPoint dest = {0,0,0};
|
46
|
+
LambertZone zone = LAMBERT_I;
|
47
|
+
|
48
|
+
lambert_to_wgs84(&org, &dest, zone);
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
void test_algo009(void)
|
53
|
+
{
|
54
|
+
double lon[3] = {0.01745329248 ,0.00290888212 ,0.00581776423};
|
55
|
+
double lat[3] = {0.02036217457,0.00000000000 ,-0.03199770300};
|
56
|
+
double he[3] = {100.0000,10.0000 ,2000.0000};
|
57
|
+
double a[3] = {6378249.2000 ,6378249.2000 ,6378249.2000};
|
58
|
+
double e[3] = {0.08248325679 ,0.08248325679 ,0.08248325679};
|
59
|
+
|
60
|
+
|
61
|
+
unsigned int i;
|
62
|
+
for (i =0; i < 3;++i)
|
63
|
+
{
|
64
|
+
YGLambertPoint pt = geographic_to_cartesian(lon[i],lat[i],he[i],a[i],e[i]);
|
65
|
+
DISPLAY_POINT(pt);
|
66
|
+
}
|
67
|
+
|
68
|
+
}
|
69
|
+
|
70
|
+
void test_algo0021 (void)
|
71
|
+
|
72
|
+
{
|
73
|
+
double n = 6393174.9755;
|
74
|
+
double lat = 0.97738438100;
|
75
|
+
double a = 6378388.0000;
|
76
|
+
double e = 0.081991890;
|
77
|
+
|
78
|
+
double calc = lambert_normal(lat,a,e);
|
79
|
+
printf("Expected:%.4f | Computed:%.4f\n",n,calc);
|
80
|
+
CU_ASSERT(n == truncate(calc,4));
|
81
|
+
|
82
|
+
}
|
83
|
+
void test_algo0002(void)
|
84
|
+
{
|
85
|
+
|
86
|
+
/*
|
87
|
+
* See IGN "Jeux d'essai"
|
88
|
+
*/
|
89
|
+
|
90
|
+
double lat_iso[3] = {1.00552653648,-0.30261690060 ,0.2000000000};
|
91
|
+
double e[3] = {0.08199188998,0.08199188998,0.08199188998};
|
92
|
+
double eps[3] = {1.0e-11,1.0e-11,1.0e-11};
|
93
|
+
|
94
|
+
double phi[3] = {0.87266462600, -0.29999999997 ,0.19998903369};
|
95
|
+
|
96
|
+
unsigned int index;
|
97
|
+
|
98
|
+
for(index = 0;index < 3;index++)
|
99
|
+
{
|
100
|
+
double result = lat_from_lat_iso(lat_iso[index], e[index], eps[index]);
|
101
|
+
result = truncate(result,11);
|
102
|
+
CU_ASSERT(result == phi[index]);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
void test_algo0012(void)
|
108
|
+
{
|
109
|
+
|
110
|
+
double a[3] = {6378249.2000, 6378249.2000 ,6378249.2000};
|
111
|
+
double e[3] = {0.08248325679, 0.08248325679, 0.08248325679};
|
112
|
+
double x[3] = {6376064.6950, 6378232.2150, 6376897.5370};
|
113
|
+
double y[3] = {111294.6230, 18553.5780, 37099.7050};
|
114
|
+
double z[3] = {128984.7250, 0.0000, -202730.9070};
|
115
|
+
double eps[3] = {1e-11,1e-11,1e-11};
|
116
|
+
|
117
|
+
double lon[3] = {0.01745329248, 0.00290888212, 0.00581776423};
|
118
|
+
double lat[3] = {0.02036217457, 0.00000000000, -0.03199770301};
|
119
|
+
double he[3] = {99.9995, 10.0001, 2000.0001};
|
120
|
+
|
121
|
+
unsigned int i;
|
122
|
+
double ign_eps = 1e-11;
|
123
|
+
for(i=0; i < 3;++i)
|
124
|
+
{
|
125
|
+
YGLambertPoint sample = {x[i],y[i],z[i]};
|
126
|
+
YGLambertPoint val ;
|
127
|
+
val = cartesian_to_geographic(sample,LON_MERID_PARIS,a[i],e[i],eps[i]);
|
128
|
+
|
129
|
+
// printf("X Computed:%.11f - Expected:%.11f\n",val.x,lon[i]);
|
130
|
+
CU_ASSERT(fabs(val.x - lon[i]) <= ign_eps);
|
131
|
+
// printf("Y Computed:%.11f - Expected:%.11f\n",val.y,lat[i]);
|
132
|
+
CU_ASSERT(fabs(val.y - lat[i]) <= ign_eps);
|
133
|
+
// printf("Z Computed:%.11f - Expected:%.11f\n",val.z,he[i]);
|
134
|
+
CU_ASSERT(truncate(val.z,4) == he[i] ) ;
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
}
|
139
|
+
void test_algo004(void)
|
140
|
+
{
|
141
|
+
|
142
|
+
YGLambertPoint org = {1029705.083,272723.849,0};
|
143
|
+
YGLambertPoint dest = {0,0,0};
|
144
|
+
YGLambertPoint expected = {0.145512099,0.872664626};
|
145
|
+
|
146
|
+
|
147
|
+
lambert_to_geographic(&org,&dest, LAMBERT_I, LON_MERID_GREENWICH,E_CLARK_IGN,1e-9);
|
148
|
+
printf("Lat:%.9f - Lon:%.9f - Expected:Lat:%.9f - Lon:%.9f\n",dest.x,dest.y,expected.x,expected.y);
|
149
|
+
CU_ASSERT(fabs(dest.x - expected.x) <= 1e-9);
|
150
|
+
CU_ASSERT(fabs(dest.y - expected.y) <= 1e-9);
|
151
|
+
}
|
152
|
+
|
153
|
+
int main(int argc, char **argv){
|
154
|
+
|
155
|
+
CU_pSuite pSuite = NULL;
|
156
|
+
|
157
|
+
/* initialize the CUnit test registry */
|
158
|
+
if (CUE_SUCCESS != CU_initialize_registry())
|
159
|
+
return CU_get_error();
|
160
|
+
|
161
|
+
/* add a suite to the registry */
|
162
|
+
pSuite = CU_add_suite("Suite_success", init_suite_success, clean_suite_success);
|
163
|
+
if (NULL == pSuite) {
|
164
|
+
CU_cleanup_registry();
|
165
|
+
return CU_get_error();
|
166
|
+
}
|
167
|
+
|
168
|
+
/* add the tests to the suite */
|
169
|
+
if ( NULL == CU_add_test(pSuite, "Test Algo0002", test_algo0002) ||
|
170
|
+
NULL == CU_add_test(pSuite, "Test Algo0012", test_algo0012) ||
|
171
|
+
NULL == CU_add_test(pSuite,"Test Algo004",test_algo004) ||
|
172
|
+
NULL == CU_add_test(pSuite,"Test algo0021",test_algo0021) ||
|
173
|
+
NULL == CU_add_test(pSuite,"test_algo009",test_algo009) ||
|
174
|
+
NULL == CU_add_test(pSuite,"test_algo009",test_lambert_deg) ||
|
175
|
+
NULL == CU_add_test(pSuite, "Test lambert", test_lambert)
|
176
|
+
)
|
177
|
+
{
|
178
|
+
CU_cleanup_registry();
|
179
|
+
return CU_get_error();
|
180
|
+
}
|
181
|
+
|
182
|
+
CU_basic_set_mode(CU_BRM_VERBOSE);
|
183
|
+
CU_basic_run_tests();
|
184
|
+
// CU_automated_run_tests();
|
185
|
+
|
186
|
+
CU_list_tests_to_file();
|
187
|
+
|
188
|
+
|
189
|
+
/* Clean up registry and return */
|
190
|
+
CU_cleanup_registry();
|
191
|
+
return CU_get_error();
|
192
|
+
|
193
|
+
return 0;
|
194
|
+
|
195
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "lambert.h"
|
3
|
+
|
4
|
+
static VALUE rb_mLambert;
|
5
|
+
static VALUE rb_cPoint;
|
6
|
+
|
7
|
+
static VALUE p_init(int argc, VALUE* argv, VALUE self)
|
8
|
+
{
|
9
|
+
|
10
|
+
VALUE x, y, z;
|
11
|
+
|
12
|
+
rb_scan_args(argc,argv, "21",&x, &y, &z);
|
13
|
+
|
14
|
+
if(NIL_P(z))
|
15
|
+
{
|
16
|
+
z = rb_float_new(0.0);
|
17
|
+
}
|
18
|
+
|
19
|
+
Check_Type(x,T_FLOAT);
|
20
|
+
Check_Type(y,T_FLOAT);
|
21
|
+
Check_Type(z,T_FLOAT);
|
22
|
+
|
23
|
+
rb_iv_set(self, "@x", x);
|
24
|
+
rb_iv_set(self, "@y", y);
|
25
|
+
rb_iv_set(self, "@z", z);
|
26
|
+
|
27
|
+
return self;
|
28
|
+
}
|
29
|
+
|
30
|
+
static VALUE p_convert(VALUE self,VALUE zone){
|
31
|
+
|
32
|
+
double x, y, z;
|
33
|
+
LambertZone cZone = NUM2INT(zone);
|
34
|
+
|
35
|
+
x = NUM2DBL(rb_iv_get(self,"@x"));
|
36
|
+
y = NUM2DBL(rb_iv_get(self,"@y"));
|
37
|
+
z = NUM2DBL(rb_iv_get(self,"@z"));
|
38
|
+
|
39
|
+
YGLambertPoint org = {x,y,z};
|
40
|
+
YGLambertPoint dest = {0,0,0};
|
41
|
+
|
42
|
+
lambert_to_wgs84_deg(&org,&dest,cZone);
|
43
|
+
|
44
|
+
rb_iv_set(self, "@x", rb_float_new(dest.x));
|
45
|
+
rb_iv_set(self, "@y", rb_float_new(dest.y));
|
46
|
+
rb_iv_set(self, "@z", rb_float_new(dest.z));
|
47
|
+
|
48
|
+
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
|
52
|
+
void Init_lambert_ruby(void) {
|
53
|
+
|
54
|
+
rb_mLambert = rb_define_module("Lambert");
|
55
|
+
rb_cPoint = rb_define_class_under(rb_mLambert,"LambertPoint",rb_cObject);
|
56
|
+
rb_define_attr(rb_cPoint,"x",1,1);
|
57
|
+
rb_define_attr(rb_cPoint,"y",1,1);
|
58
|
+
rb_define_attr(rb_cPoint,"z",1,1);
|
59
|
+
|
60
|
+
rb_define_method(rb_cPoint,"initialize",p_init,-1);
|
61
|
+
rb_define_method(rb_cPoint,"wgs84",p_convert,1);
|
62
|
+
|
63
|
+
rb_define_const(rb_mLambert,"LambertI",INT2NUM(LAMBERT_I));
|
64
|
+
rb_define_const(rb_mLambert,"LambertII",INT2NUM(LAMBERT_II));
|
65
|
+
rb_define_const(rb_mLambert,"LambertIII",INT2NUM(LAMBERT_III));
|
66
|
+
rb_define_const(rb_mLambert,"LambertIV",INT2NUM(LAMBERT_IV));
|
67
|
+
rb_define_const(rb_mLambert,"LambertIIExtended",INT2NUM(LAMBERT_II_E));
|
68
|
+
rb_define_const(rb_mLambert,"Lambert93",INT2NUM(LAMBERT_93));
|
69
|
+
}
|
data/lib/lambert_ruby.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'lambert_ruby/lambert_ruby'
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lambert_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yannick Heinrich
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Ruby wrapper for the lambert library that converts Lambert coordinates
|
14
|
+
to WGS84. It wraps the original C files with a basic Ruby interface.
|
15
|
+
email: yannick.heinrich@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions:
|
18
|
+
- ext/lambert_ruby/extconf.rb
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/lambert_ruby.rb
|
22
|
+
- ext/lambert_ruby/lambert/src/lambert.c
|
23
|
+
- ext/lambert_ruby/lambert/tests/test_lambert_cunit.c
|
24
|
+
- ext/lambert_ruby/lambert.c
|
25
|
+
- ext/lambert_ruby/lambert_ruby.c
|
26
|
+
- ext/lambert_ruby/lambert/src/lambert.h
|
27
|
+
- ext/lambert_ruby/lambert.h
|
28
|
+
- ext/lambert_ruby/extconf.rb
|
29
|
+
homepage: https://github.com/YaGeek/lambert-ruby
|
30
|
+
licenses:
|
31
|
+
- GPL-2
|
32
|
+
metadata: {}
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 2.0.3
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Ruby wrapper for the lambert library that converts Lambert coordinates to
|
53
|
+
WGS84
|
54
|
+
test_files: []
|