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 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: "—"