geographiclib 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/geographiclib/geographiclib.cpp +255 -36
- data/lib/geographiclib.rb +8 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb0f807373f145e2b92afb212b290d8ba06126a3
|
4
|
+
data.tar.gz: 3cfb57e02c66a827b79d22daf013feeaeea431b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9caa261f5a9d99f9b1e9163877ab8eb36c02fda93df024503c71026cad265908a3e1e0cf8b8b15f500667b72361f25b044d845845e1ffa634f5cb128f8c8bcf
|
7
|
+
data.tar.gz: 1a9696ef61ce6faae4a230ba3810c9f2b472a84ae4376e6fe55084f35b3597f99787eef0f471d0766b1049d905e2836ffa9f285ada09d001693349e579b54c0e
|
@@ -1,62 +1,281 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <GeographicLib/Constants.hpp>
|
3
3
|
#include <GeographicLib/Geodesic.hpp>
|
4
|
+
#include <GeographicLib/DMS.hpp>
|
5
|
+
#include <GeographicLib/Geocentric.hpp>
|
6
|
+
#include <GeographicLib/LocalCartesian.hpp>
|
7
|
+
|
8
|
+
#define rb_symbol(s) rb_id2sym(rb_intern_const(s))
|
9
|
+
|
10
|
+
static void decode_lat_lon(VALUE vlat, VALUE vlon, GeographicLib::Math::real &lat, GeographicLib::Math::real &lon)
|
11
|
+
{
|
12
|
+
std::string slat, slon;
|
13
|
+
if (rb_type(vlat) == T_STRING && rb_type(vlon) == T_STRING) {
|
14
|
+
slat = rb_string_value_cstr(&vlat);
|
15
|
+
slon = rb_string_value_cstr(&vlon);
|
16
|
+
try {
|
17
|
+
GeographicLib::DMS::DecodeLatLon(slat, slon, lat, lon);
|
18
|
+
} catch (GeographicLib::GeographicErr e) {
|
19
|
+
rb_raise(rb_eRuntimeError, "This is not a valid position.");
|
20
|
+
}
|
21
|
+
} else {
|
22
|
+
lat = rb_num2dbl(vlat);
|
23
|
+
lon = rb_num2dbl(vlon);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
static void decode_azi(VALUE vazi, GeographicLib::Math::real &azi)
|
28
|
+
{
|
29
|
+
std::string sazi;
|
30
|
+
if (rb_type(vazi) == T_STRING) {
|
31
|
+
sazi = rb_string_value_cstr(&vazi);
|
32
|
+
try {
|
33
|
+
azi = GeographicLib::DMS::DecodeAzimuth(sazi);
|
34
|
+
} catch (GeographicLib::GeographicErr e) {
|
35
|
+
rb_raise(rb_eRuntimeError, "This is not a valid azimuth.");
|
36
|
+
}
|
37
|
+
} else {
|
38
|
+
azi = rb_num2dbl(vazi);
|
39
|
+
}
|
40
|
+
}
|
4
41
|
|
5
42
|
static VALUE geographiclib_geodesic_direct(VALUE self, VALUE a, VALUE f, VALUE vlat1, VALUE vlon1, VALUE vazi1, VALUE arcmode, VALUE vs12_a12)
|
6
43
|
{
|
7
|
-
GeographicLib::Geodesic g(
|
44
|
+
GeographicLib::Geodesic g(rb_num2dbl(a), rb_num2dbl(f));
|
8
45
|
GeographicLib::Math::real lat1, lon1, s12_a12, lat2, lon2, s12, azi1, azi2, m12, M12, M21, S12;
|
9
|
-
lat1
|
10
|
-
|
11
|
-
|
12
|
-
s12_a12 = NUM2DBL(vs12_a12);
|
46
|
+
decode_lat_lon(vlat1, vlon1, lat1, lon1);
|
47
|
+
decode_azi(vazi1, azi1);
|
48
|
+
s12_a12 = rb_num2dbl(vs12_a12);
|
13
49
|
g.GenDirect(lat1, lon1, azi1, arcmode, s12_a12, GeographicLib::Geodesic::ALL, lat2, lon2, azi2, s12, m12, M12, M21, S12);
|
14
50
|
VALUE r = rb_hash_new();
|
15
|
-
rb_hash_aset(r,
|
16
|
-
rb_hash_aset(r,
|
17
|
-
rb_hash_aset(r,
|
18
|
-
rb_hash_aset(r,
|
19
|
-
rb_hash_aset(r,
|
20
|
-
rb_hash_aset(r,
|
21
|
-
rb_hash_aset(r,
|
22
|
-
rb_hash_aset(r,
|
23
|
-
rb_hash_aset(r,
|
24
|
-
rb_hash_aset(r,
|
25
|
-
rb_hash_aset(r,
|
51
|
+
rb_hash_aset(r, rb_symbol("lat1"), rb_float_new(lat1));
|
52
|
+
rb_hash_aset(r, rb_symbol("lon1"), rb_float_new(lon1));
|
53
|
+
rb_hash_aset(r, rb_symbol("lat2"), rb_float_new(lat2));
|
54
|
+
rb_hash_aset(r, rb_symbol("lon2"), rb_float_new(lon2));
|
55
|
+
rb_hash_aset(r, rb_symbol("s12"), rb_float_new(s12));
|
56
|
+
rb_hash_aset(r, rb_symbol("azi1"), rb_float_new(azi1));
|
57
|
+
rb_hash_aset(r, rb_symbol("azi2"), rb_float_new(azi2));
|
58
|
+
rb_hash_aset(r, rb_symbol("m12"), rb_float_new(m12));
|
59
|
+
rb_hash_aset(r, rb_symbol("M12"), rb_float_new(M12));
|
60
|
+
rb_hash_aset(r, rb_symbol("M21"), rb_float_new(M21));
|
61
|
+
rb_hash_aset(r, rb_symbol("S12"), rb_float_new(S12));
|
26
62
|
return r;
|
27
63
|
}
|
28
64
|
|
29
65
|
static VALUE geographiclib_geodesic_inverse(VALUE self, VALUE a, VALUE f, VALUE vlat1, VALUE vlon1, VALUE vlat2, VALUE vlon2)
|
30
66
|
{
|
31
|
-
GeographicLib::Geodesic g(
|
67
|
+
GeographicLib::Geodesic g(rb_num2dbl(a), rb_num2dbl(f));
|
32
68
|
GeographicLib::Math::real lat1, lon1, lat2, lon2, s12, azi1, azi2, m12, M12, M21, S12;
|
33
|
-
lat1
|
34
|
-
|
35
|
-
lat2 = NUM2DBL(vlat2);
|
36
|
-
lon2 = NUM2DBL(vlon2);
|
69
|
+
decode_lat_lon(vlat1, vlon1, lat1, lon1);
|
70
|
+
decode_lat_lon(vlat2, vlon2, lat2, lon2);
|
37
71
|
g.GenInverse(lat1, lon1, lat2, lon2, GeographicLib::Geodesic::ALL, s12, azi1, azi2, m12, M12, M21, S12);
|
38
72
|
VALUE r = rb_hash_new();
|
39
|
-
rb_hash_aset(r,
|
40
|
-
rb_hash_aset(r,
|
41
|
-
rb_hash_aset(r,
|
42
|
-
rb_hash_aset(r,
|
43
|
-
rb_hash_aset(r,
|
44
|
-
rb_hash_aset(r,
|
45
|
-
rb_hash_aset(r,
|
46
|
-
rb_hash_aset(r,
|
47
|
-
rb_hash_aset(r,
|
48
|
-
rb_hash_aset(r,
|
49
|
-
rb_hash_aset(r,
|
73
|
+
rb_hash_aset(r, rb_symbol("lat1"), rb_float_new(lat1));
|
74
|
+
rb_hash_aset(r, rb_symbol("lon1"), rb_float_new(lon1));
|
75
|
+
rb_hash_aset(r, rb_symbol("lat2"), rb_float_new(lat2));
|
76
|
+
rb_hash_aset(r, rb_symbol("lon2"), rb_float_new(lon2));
|
77
|
+
rb_hash_aset(r, rb_symbol("s12"), rb_float_new(s12));
|
78
|
+
rb_hash_aset(r, rb_symbol("azi1"), rb_float_new(azi1));
|
79
|
+
rb_hash_aset(r, rb_symbol("azi2"), rb_float_new(azi2));
|
80
|
+
rb_hash_aset(r, rb_symbol("m12"), rb_float_new(m12));
|
81
|
+
rb_hash_aset(r, rb_symbol("M12"), rb_float_new(M12));
|
82
|
+
rb_hash_aset(r, rb_symbol("M21"), rb_float_new(M21));
|
83
|
+
rb_hash_aset(r, rb_symbol("S12"), rb_float_new(S12));
|
84
|
+
return r;
|
85
|
+
}
|
86
|
+
|
87
|
+
static VALUE geographiclib_dms_decode(VALUE self, VALUE str)
|
88
|
+
{
|
89
|
+
std::string s = rb_string_value_cstr(&str);
|
90
|
+
try {
|
91
|
+
GeographicLib::DMS::flag f;
|
92
|
+
GeographicLib::Math::real angle = GeographicLib::DMS::Decode(s, f);
|
93
|
+
VALUE r = rb_ary_new();
|
94
|
+
rb_ary_push(r, rb_float_new(angle));
|
95
|
+
switch (f) {
|
96
|
+
case GeographicLib::DMS::LATITUDE: rb_ary_push(r, rb_symbol("lat")); break;
|
97
|
+
case GeographicLib::DMS::LONGITUDE: rb_ary_push(r, rb_symbol("lon")); break;
|
98
|
+
case GeographicLib::DMS::AZIMUTH: rb_ary_push(r, rb_symbol("azi")); break;
|
99
|
+
case GeographicLib::DMS::NUMBER: rb_ary_push(r, rb_symbol("number")); break;
|
100
|
+
default: rb_ary_push(r, rb_symbol("none")); break;
|
101
|
+
}
|
102
|
+
return r;
|
103
|
+
} catch (GeographicLib::GeographicErr e) {
|
104
|
+
rb_raise(rb_eRuntimeError, "String is malformed.");
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
static VALUE geographiclib_dms_decode_lat_lon(VALUE self, VALUE vlat, VALUE vlon)
|
109
|
+
{
|
110
|
+
GeographicLib::Math::real lat, lon;
|
111
|
+
decode_lat_lon(vlat, vlon, lat, lon);
|
112
|
+
VALUE r = rb_ary_new();
|
113
|
+
rb_ary_push(r, rb_float_new(lat));
|
114
|
+
rb_ary_push(r, rb_float_new(lon));
|
115
|
+
return r;
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE geographiclib_dms_decode_azi(VALUE self, VALUE vazi)
|
119
|
+
{
|
120
|
+
GeographicLib::Math::real azi;
|
121
|
+
decode_azi(vazi, azi);
|
122
|
+
return rb_float_new(azi);
|
123
|
+
}
|
124
|
+
|
125
|
+
static void geographiclib_local_cartesian_free(void *x)
|
126
|
+
{
|
127
|
+
if (x) {
|
128
|
+
delete (GeographicLib::LocalCartesian *) x;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
static size_t geographiclib_local_cartesian_size(const void *x)
|
133
|
+
{
|
134
|
+
if (x) {
|
135
|
+
return sizeof(GeographicLib::LocalCartesian);
|
136
|
+
} else {
|
137
|
+
return 0;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
static const rb_data_type_t geographiclib_local_cartesian_type = {
|
142
|
+
"geographiclib_local_cartesian",
|
143
|
+
{
|
144
|
+
0,
|
145
|
+
geographiclib_local_cartesian_free,
|
146
|
+
geographiclib_local_cartesian_size
|
147
|
+
},
|
148
|
+
0,
|
149
|
+
0,
|
150
|
+
RUBY_TYPED_FREE_IMMEDIATELY
|
151
|
+
};
|
152
|
+
|
153
|
+
static VALUE geographiclib_local_cartesian_alloc(VALUE klass)
|
154
|
+
{
|
155
|
+
return TypedData_Wrap_Struct(klass, &geographiclib_local_cartesian_type, 0);
|
156
|
+
}
|
157
|
+
|
158
|
+
static GeographicLib::LocalCartesian *geographiclib_local_cartesian_get(VALUE v)
|
159
|
+
{
|
160
|
+
GeographicLib::LocalCartesian *x;
|
161
|
+
TypedData_Get_Struct(v, GeographicLib::LocalCartesian, &geographiclib_local_cartesian_type, x);
|
162
|
+
if (x) {
|
163
|
+
return x;
|
164
|
+
} else {
|
165
|
+
rb_raise(rb_eRuntimeError, "Object not initialized.");
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
static VALUE geographiclib_local_cartesian_initialize(int argc, VALUE *argv, VALUE self)
|
170
|
+
{
|
171
|
+
GeographicLib::Math::real lat = 0.0, lon = 0.0, h = 0.0;
|
172
|
+
switch (argc) {
|
173
|
+
default:
|
174
|
+
rb_raise(rb_eArgError, "Wrong number of arguments. Expecting 0, 1, 2 or 3.");
|
175
|
+
case 3:
|
176
|
+
h = rb_num2dbl(argv[2]);
|
177
|
+
case 2:
|
178
|
+
decode_lat_lon(argv[0], argv[1], lat, lon);
|
179
|
+
case 0:
|
180
|
+
break;
|
181
|
+
case 1:
|
182
|
+
rb_check_type(argv[0], T_HASH);
|
183
|
+
decode_lat_lon(rb_hash_lookup(argv[0], rb_symbol("lat")), rb_hash_lookup(argv[0], rb_symbol("lon")), lat, lon);
|
184
|
+
VALUE vh = rb_hash_lookup(argv[0], rb_symbol("h"));
|
185
|
+
if (vh != Qnil) {
|
186
|
+
h = rb_num2dbl(vh);
|
187
|
+
}
|
188
|
+
break;
|
189
|
+
}
|
190
|
+
geographiclib_local_cartesian_free(DATA_PTR(self));
|
191
|
+
DATA_PTR(self) = new GeographicLib::LocalCartesian(lat, lon, h);
|
192
|
+
return self;
|
193
|
+
}
|
194
|
+
|
195
|
+
static VALUE geographiclib_local_cartesian_forward(int argc, VALUE *argv, VALUE self)
|
196
|
+
{
|
197
|
+
GeographicLib::Math::real lat = 0.0, lon = 0.0, h = 0.0, x, y, z;
|
198
|
+
switch (argc) {
|
199
|
+
default:
|
200
|
+
rb_raise(rb_eArgError, "Wrong number of arguments. Expecting 1, 2 or 3.");
|
201
|
+
case 3:
|
202
|
+
h = rb_num2dbl(argv[2]);
|
203
|
+
case 2:
|
204
|
+
decode_lat_lon(argv[0], argv[1], lat, lon);
|
205
|
+
break;
|
206
|
+
case 1:
|
207
|
+
rb_check_type(argv[0], T_HASH);
|
208
|
+
decode_lat_lon(rb_hash_lookup(argv[0], rb_symbol("lat")), rb_hash_lookup(argv[0], rb_symbol("lon")), lat, lon);
|
209
|
+
VALUE vh = rb_hash_lookup(argv[0], rb_symbol("h"));
|
210
|
+
if (vh != Qnil) {
|
211
|
+
h = rb_num2dbl(vh);
|
212
|
+
}
|
213
|
+
break;
|
214
|
+
}
|
215
|
+
GeographicLib::LocalCartesian *lc = geographiclib_local_cartesian_get(self);
|
216
|
+
lc->Forward(lat, lon, h, x, y, z);
|
217
|
+
VALUE r = rb_hash_new();
|
218
|
+
rb_hash_aset(r, rb_symbol("x"), rb_float_new(x));
|
219
|
+
rb_hash_aset(r, rb_symbol("y"), rb_float_new(y));
|
220
|
+
rb_hash_aset(r, rb_symbol("z"), rb_float_new(z));
|
221
|
+
return r;
|
222
|
+
}
|
223
|
+
|
224
|
+
static VALUE geographiclib_local_cartesian_reverse(int argc, VALUE *argv, VALUE self)
|
225
|
+
{
|
226
|
+
GeographicLib::Math::real lat, lon, h, x, y, z = 0.0;
|
227
|
+
switch (argc) {
|
228
|
+
default:
|
229
|
+
rb_raise(rb_eArgError, "Wrong number of arguments. Expecting 1 or 3.");
|
230
|
+
case 3:
|
231
|
+
x = rb_num2dbl(argv[0]);
|
232
|
+
y = rb_num2dbl(argv[1]);
|
233
|
+
z = rb_num2dbl(argv[2]);
|
234
|
+
break;
|
235
|
+
case 1:
|
236
|
+
rb_check_type(argv[0], T_HASH);
|
237
|
+
x = rb_num2dbl(rb_hash_lookup(argv[0], rb_symbol("x")));
|
238
|
+
y = rb_num2dbl(rb_hash_lookup(argv[0], rb_symbol("y")));
|
239
|
+
z = rb_num2dbl(rb_hash_lookup(argv[0], rb_symbol("z")));
|
240
|
+
break;
|
241
|
+
}
|
242
|
+
GeographicLib::LocalCartesian *lc = geographiclib_local_cartesian_get(self);
|
243
|
+
lc->Reverse(x, y, z, lat, lon, h);
|
244
|
+
VALUE r = rb_hash_new();
|
245
|
+
rb_hash_aset(r, rb_symbol("lat"), rb_float_new(lat));
|
246
|
+
rb_hash_aset(r, rb_symbol("lon"), rb_float_new(lon));
|
247
|
+
rb_hash_aset(r, rb_symbol("h"), rb_float_new(h));
|
50
248
|
return r;
|
51
249
|
}
|
52
250
|
|
53
251
|
extern "C" void Init_geographiclib(void)
|
54
252
|
{
|
55
253
|
VALUE geographiclib = rb_define_module("GeographicLib");
|
254
|
+
|
56
255
|
VALUE constants = rb_define_module_under(geographiclib, "Constants");
|
57
|
-
rb_define_const(constants, "WGS84_a",
|
58
|
-
rb_define_const(constants, "WGS84_f",
|
256
|
+
rb_define_const(constants, "WGS84_a", rb_float_new(GeographicLib::Constants::WGS84_a()));
|
257
|
+
rb_define_const(constants, "WGS84_f", rb_float_new(GeographicLib::Constants::WGS84_f()));
|
258
|
+
|
59
259
|
VALUE geodesic = rb_define_class_under(geographiclib, "Geodesic", rb_cObject);
|
60
|
-
rb_define_singleton_method(geodesic, "direct",
|
61
|
-
|
260
|
+
rb_define_singleton_method(geodesic, "direct",
|
261
|
+
(VALUE (*)(...)) geographiclib_geodesic_direct, 7);
|
262
|
+
rb_define_singleton_method(geodesic, "inverse",
|
263
|
+
(VALUE (*)(...)) geographiclib_geodesic_inverse, 6);
|
264
|
+
|
265
|
+
VALUE dms = rb_define_module_under(geographiclib, "DMS");
|
266
|
+
rb_define_module_function(dms, "decode",
|
267
|
+
(VALUE (*)(...)) geographiclib_dms_decode, 1);
|
268
|
+
rb_define_module_function(dms, "decode_lat_lon",
|
269
|
+
(VALUE (*)(...)) geographiclib_dms_decode_lat_lon, 2);
|
270
|
+
rb_define_module_function(dms, "decode_azi",
|
271
|
+
(VALUE (*)(...)) geographiclib_dms_decode_azi, 1);
|
272
|
+
|
273
|
+
VALUE local_cartesian = rb_define_class_under(geographiclib, "LocalCartesian", rb_cObject);
|
274
|
+
rb_define_alloc_func(local_cartesian, geographiclib_local_cartesian_alloc);
|
275
|
+
rb_define_method(local_cartesian, "initialize",
|
276
|
+
(VALUE (*)(...)) geographiclib_local_cartesian_initialize, -1);
|
277
|
+
rb_define_method(local_cartesian, "forward",
|
278
|
+
(VALUE (*)(...)) geographiclib_local_cartesian_forward, -1);
|
279
|
+
rb_define_method(local_cartesian, "reverse",
|
280
|
+
(VALUE (*)(...)) geographiclib_local_cartesian_reverse, -1);
|
62
281
|
}
|
data/lib/geographiclib.rb
CHANGED
@@ -2,19 +2,26 @@ require 'geographiclib/geographiclib'
|
|
2
2
|
|
3
3
|
module GeographicLib
|
4
4
|
class Geodesic
|
5
|
+
attr_accessor :a, :f
|
6
|
+
|
7
|
+
# Creates an ellipsoid with semi-major-axis a and flattening f.
|
5
8
|
def initialize a, f
|
6
9
|
@a = a
|
7
10
|
@f = f
|
8
11
|
end
|
9
12
|
|
13
|
+
# Calculates the direct geodesic problem given a point, an azimuth and a distance.
|
14
|
+
# If arcmode is false, the distance is in meters, otherwise it is an angle.
|
10
15
|
def direct lat1, lon1, azi1, arcmode, s12_a12
|
11
16
|
Geodesic.direct @a, @f, lat1, lon1, azi1, !!arcmode, s12_a12
|
12
17
|
end
|
13
18
|
|
19
|
+
# Calculates the inverse geodesic problem given two points.
|
14
20
|
def inverse lat1, lon1, lat2, lon2
|
15
21
|
Geodesic.inverse @a, @f, lat1, lon1, lat2, lon2
|
16
22
|
end
|
17
23
|
|
18
|
-
|
24
|
+
# An instance of Geodesic initialized with the parameters for the WGS84 ellipsoid.
|
25
|
+
WGS84 = Geodesic.new(Constants::WGS84_a, Constants::WGS84_f).freeze
|
19
26
|
end
|
20
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geographiclib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Karney <charles@karney.com>
|
@@ -19,7 +19,7 @@ authors:
|
|
19
19
|
autorequire:
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
|
-
date: 2016-
|
22
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
23
23
|
dependencies: []
|
24
24
|
description: A wrapper for GeograpicLib.
|
25
25
|
email: "—"
|