geographiclib 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa8370a9028f271543b408485a76114b2d7f396f
4
- data.tar.gz: 21443c4c505ce041d24155701c38e4a5a3ffa420
3
+ metadata.gz: cb0f807373f145e2b92afb212b290d8ba06126a3
4
+ data.tar.gz: 3cfb57e02c66a827b79d22daf013feeaeea431b4
5
5
  SHA512:
6
- metadata.gz: 3c0efaf0dbadca39751487f1626cb3124b6554fb66e367455e9431316944bcbe5dfb19af4517009349730d306dd59e8c5e07a1bb5c693598cb7dcf3232c9a4ad
7
- data.tar.gz: 6b4e08090d147a0e4ebaf5adf219485b4f20c7b1b749facbffe63193706b3b5ec4eec4f74bf3049365e4e22f1ce5e45bdcd33a4a2d7ac520be9569b17ab4ad8a
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(NUM2DBL(a), NUM2DBL(f));
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 = NUM2DBL(vlat1);
10
- lon1 = NUM2DBL(vlon1);
11
- azi1 = NUM2DBL(vazi1);
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, rb_id2sym(rb_intern_const("lat1")), DBL2NUM(lat1));
16
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lon1")), DBL2NUM(lon1));
17
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lat2")), DBL2NUM(lat2));
18
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lon2")), DBL2NUM(lon2));
19
- rb_hash_aset(r, rb_id2sym(rb_intern_const("s12")), DBL2NUM(s12));
20
- rb_hash_aset(r, rb_id2sym(rb_intern_const("azi1")), DBL2NUM(azi1));
21
- rb_hash_aset(r, rb_id2sym(rb_intern_const("azi2")), DBL2NUM(azi2));
22
- rb_hash_aset(r, rb_id2sym(rb_intern_const("m12")), DBL2NUM(m12));
23
- rb_hash_aset(r, rb_id2sym(rb_intern_const("M12")), DBL2NUM(M12));
24
- rb_hash_aset(r, rb_id2sym(rb_intern_const("M21")), DBL2NUM(M21));
25
- rb_hash_aset(r, rb_id2sym(rb_intern_const("S12")), DBL2NUM(S12));
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(NUM2DBL(a), NUM2DBL(f));
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 = NUM2DBL(vlat1);
34
- lon1 = NUM2DBL(vlon1);
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, rb_id2sym(rb_intern_const("lat1")), DBL2NUM(lat1));
40
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lon1")), DBL2NUM(lon1));
41
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lat2")), DBL2NUM(lat2));
42
- rb_hash_aset(r, rb_id2sym(rb_intern_const("lon2")), DBL2NUM(lon2));
43
- rb_hash_aset(r, rb_id2sym(rb_intern_const("s12")), DBL2NUM(s12));
44
- rb_hash_aset(r, rb_id2sym(rb_intern_const("azi1")), DBL2NUM(azi1));
45
- rb_hash_aset(r, rb_id2sym(rb_intern_const("azi2")), DBL2NUM(azi2));
46
- rb_hash_aset(r, rb_id2sym(rb_intern_const("m12")), DBL2NUM(m12));
47
- rb_hash_aset(r, rb_id2sym(rb_intern_const("M12")), DBL2NUM(M12));
48
- rb_hash_aset(r, rb_id2sym(rb_intern_const("M21")), DBL2NUM(M21));
49
- rb_hash_aset(r, rb_id2sym(rb_intern_const("S12")), DBL2NUM(S12));
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", DBL2NUM(GeographicLib::Constants::WGS84_a()));
58
- rb_define_const(constants, "WGS84_f", DBL2NUM(GeographicLib::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", (VALUE (*)(...)) geographiclib_geodesic_direct, 7);
61
- rb_define_singleton_method(geodesic, "inverse", (VALUE (*)(...)) geographiclib_geodesic_inverse, 6);
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
  }
@@ -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
- WGS84 = Geodesic.new Constants::WGS84_a, Constants::WGS84_f
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.1
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-02-28 00:00:00.000000000 Z
22
+ date: 2016-05-27 00:00:00.000000000 Z
23
23
  dependencies: []
24
24
  description: A wrapper for GeograpicLib.
25
25
  email: "—"