geodesic_wgs84 1.32.1

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.
@@ -0,0 +1,192 @@
1
+ /*
2
+ * Ruby wrapper code for geodesic functions
3
+ *
4
+ * Copyright (c) 2014 Volker Wiegand <volker.wiegand@cvw.de>
5
+ */
6
+
7
+ #include <ruby.h>
8
+ #include "geodesic.h"
9
+
10
+
11
+ static VALUE cWGS84;
12
+ static struct geod_geodesic g;
13
+
14
+
15
+ static VALUE
16
+ wgs84_init(VALUE klass)
17
+ {
18
+ double a = 6378137, f = 1/298.257223563; /* WGS84 */
19
+
20
+ geod_init(&g, a, f);
21
+
22
+ return klass;
23
+ }
24
+
25
+
26
+ static double
27
+ wgs84_get_value(VALUE arg)
28
+ {
29
+ char buf[64];
30
+ int dd, mm, ss, ff;
31
+ double dbl;
32
+
33
+ if (TYPE(arg) == T_FLOAT)
34
+ return NUM2DBL(arg);
35
+
36
+ if (TYPE(arg) == T_FIXNUM)
37
+ return (double) NUM2INT(arg);
38
+
39
+ if (TYPE(arg) == T_STRING && RSTRING_LEN(arg) < 60) {
40
+ memset(buf, 0, sizeof(buf));
41
+ memcpy(buf, RSTRING_PTR(arg), RSTRING_LEN(arg));
42
+
43
+ if (sscanf(buf, "%d.%d.%d,%d", &dd, &mm, &ss, &ff) == 4) {
44
+ // Round number to 6 digits
45
+ dbl = ((double) dd + ((((double) mm * 600.0) + ((double) ss * 10.0) + (double) ff) / 36000.0)) * 1000000.0;
46
+ return round(dbl) / 1000000.0;
47
+ }
48
+
49
+ if (sscanf(buf, "%d.%d", &dd, &ff) == 2) {
50
+ sscanf(buf, "%lf", &dbl);
51
+ return dbl;
52
+ }
53
+
54
+ if (sscanf(buf, "%d,%d", &dd, &ff) == 2) {
55
+ *strchr(buf, ',') = '.';
56
+ sscanf(buf, "%lf", &dbl);
57
+ return dbl;
58
+ }
59
+ }
60
+
61
+ rb_raise(rb_eArgError, "invalid (lat/lon) argument");
62
+ }
63
+
64
+
65
+ static VALUE
66
+ wgs84_lat_lon(int argc, VALUE *argv, VALUE klass)
67
+ {
68
+ double lat, lon;
69
+ VALUE tmp;
70
+
71
+ if (argc == 2) {
72
+ lat = wgs84_get_value(argv[0]);
73
+ lon = wgs84_get_value(argv[1]);
74
+ return rb_ary_new3(2L, rb_float_new(lat), rb_float_new(lon));
75
+ }
76
+
77
+ if (argc == 1 && TYPE(*argv) == T_ARRAY && RARRAY_LEN(*argv) == 2) {
78
+ lat = wgs84_get_value(rb_ary_entry(*argv, 0));
79
+ lon = wgs84_get_value(rb_ary_entry(*argv, 1));
80
+ return rb_ary_new3(2L, rb_float_new(lat), rb_float_new(lon));
81
+ }
82
+
83
+ if (argc == 1 && !NIL_P(tmp = rb_check_array_type(*argv))) {
84
+ lat = wgs84_get_value(rb_ary_entry(tmp, 0));
85
+ lon = wgs84_get_value(rb_ary_entry(tmp, 1));
86
+ return rb_ary_new3(2L, rb_float_new(lat), rb_float_new(lon));
87
+ }
88
+
89
+ rb_raise(rb_eArgError, "wrong number of arguments");
90
+ return Qnil;
91
+ }
92
+
93
+
94
+ static VALUE
95
+ wgs84_distance(int argc, VALUE *argv, VALUE klass)
96
+ {
97
+ int i;
98
+ double dbl[4], azi1, azi2, s12;
99
+ VALUE tmp1, tmp2;
100
+
101
+ if (argc == 4) {
102
+ for (i = 0; i < 4; i++)
103
+ dbl[i] = wgs84_get_value(argv[i]);
104
+ geod_inverse(&g, dbl[0], dbl[1], dbl[2], dbl[3], &s12, &azi1, &azi2);
105
+ return rb_ary_new3(2L, INT2NUM((int) round(s12)), INT2NUM((int) azi1));
106
+ }
107
+
108
+ if (argc == 1 && TYPE(*argv) == T_ARRAY && RARRAY_LEN(*argv) == 4) {
109
+ for (i = 0; i < 4; i++)
110
+ dbl[i] = wgs84_get_value(rb_ary_entry(*argv, i));
111
+ geod_inverse(&g, dbl[0], dbl[1], dbl[2], dbl[3], &s12, &azi1, &azi2);
112
+ return rb_ary_new3(2L, INT2NUM((int) round(s12)), INT2NUM((int) azi1));
113
+ }
114
+
115
+ if (argc == 2) {
116
+ tmp1 = rb_check_array_type(argv[0]);
117
+ tmp2 = rb_check_array_type(argv[1]);
118
+ if (!NIL_P(tmp1) && !NIL_P(tmp2)) {
119
+ dbl[0] = wgs84_get_value(rb_ary_entry(tmp1, 0));
120
+ dbl[1] = wgs84_get_value(rb_ary_entry(tmp1, 1));
121
+ dbl[2] = wgs84_get_value(rb_ary_entry(tmp2, 0));
122
+ dbl[3] = wgs84_get_value(rb_ary_entry(tmp2, 1));
123
+ geod_inverse(&g, dbl[0], dbl[1], dbl[2], dbl[3], &s12, &azi1, &azi2);
124
+ return rb_ary_new3(2L, INT2NUM((int) round(s12)), INT2NUM((int) azi1));
125
+ }
126
+ }
127
+
128
+ if (argc == 1 && TYPE(*argv) == T_ARRAY && RARRAY_LEN(*argv) == 2) {
129
+ tmp1 = rb_check_array_type(rb_ary_entry(*argv, 0));
130
+ tmp2 = rb_check_array_type(rb_ary_entry(*argv, 1));
131
+ if (!NIL_P(tmp1) && !NIL_P(tmp2)) {
132
+ dbl[0] = wgs84_get_value(rb_ary_entry(tmp1, 0));
133
+ dbl[1] = wgs84_get_value(rb_ary_entry(tmp1, 1));
134
+ dbl[2] = wgs84_get_value(rb_ary_entry(tmp2, 0));
135
+ dbl[3] = wgs84_get_value(rb_ary_entry(tmp2, 1));
136
+ geod_inverse(&g, dbl[0], dbl[1], dbl[2], dbl[3], &s12, &azi1, &azi2);
137
+ return rb_ary_new3(2L, INT2NUM((int) round(s12)), INT2NUM((int) azi1));
138
+ }
139
+ }
140
+
141
+ rb_raise(rb_eArgError, "wrong number of arguments");
142
+ return Qnil;
143
+ }
144
+
145
+
146
+ static VALUE
147
+ wgs84_average(VALUE klass, VALUE array, VALUE target)
148
+ {
149
+ VALUE tmp, arr_val;
150
+ double dst_lat, dst_lon, arr_lat, arr_lon, azi1, azi2, s12;
151
+ double arr_min = 0.0, arr_max = 0.0, arr_sum = 0.0;
152
+ int cnt, arr_azi = 0;
153
+
154
+ tmp = rb_check_array_type(target);
155
+ if (NIL_P(tmp))
156
+ rb_raise(rb_eArgError, "invalid (target) argument");
157
+ dst_lat = wgs84_get_value(rb_ary_entry(tmp, 0));
158
+ dst_lon = wgs84_get_value(rb_ary_entry(tmp, 1));
159
+
160
+ arr_val = rb_check_convert_type(array, T_ARRAY, "Array", "to_a");
161
+ for (cnt = 0; cnt < RARRAY_LEN(arr_val); cnt++) {
162
+ tmp = rb_check_array_type(rb_ary_entry(arr_val, cnt));
163
+ if (NIL_P(tmp))
164
+ rb_raise(rb_eArgError, "invalid (array) argument");
165
+ arr_lat = wgs84_get_value(rb_ary_entry(tmp, 0));
166
+ arr_lon = wgs84_get_value(rb_ary_entry(tmp, 1));
167
+ geod_inverse(&g, arr_lat, arr_lon, dst_lat, dst_lon, &s12, &azi1, &azi2);
168
+ s12 = round(s12);
169
+ if (arr_min == 0.0 || s12 < arr_min)
170
+ arr_min = s12;
171
+ if (arr_max == 0.0 || s12 > arr_max)
172
+ arr_max = s12;
173
+ arr_sum += s12;
174
+ arr_azi += (int) azi1;
175
+ }
176
+ s12 = round(round(arr_sum / (double) cnt) / 1000.0);
177
+ azi1 = round(round((arr_min + arr_max) / 2.0) / 1000.0);
178
+
179
+ return rb_ary_new3(3L, INT2NUM((int) s12), INT2NUM((int) azi1), INT2NUM(arr_azi / cnt));
180
+ }
181
+
182
+
183
+ void
184
+ Init_geodesic_wgs84(void)
185
+ {
186
+ cWGS84 = rb_define_class("Wgs84", rb_cObject);
187
+ rb_define_method(cWGS84, "initialize", wgs84_init, 0);
188
+ rb_define_method(cWGS84, "lat_lon", wgs84_lat_lon, -1);
189
+ rb_define_method(cWGS84, "distance", wgs84_distance, -1);
190
+ rb_define_method(cWGS84, "average", wgs84_average, 2);
191
+ }
192
+
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geodesic_wgs84/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geodesic_wgs84"
8
+ spec.version = GeodesicWgs84::VERSION
9
+ spec.date = "2014-03-06"
10
+ spec.authors = ["Volker Wiegand"]
11
+ spec.email = ["volker.wiegand@cvw.de"]
12
+ spec.summary = "Calculate distances on Earth using WGS84"
13
+ spec.description = "Geodesic functions based on http://geographiclib.sourceforge.net/"
14
+ spec.homepage = "http://github.com/volkerwiegand/geodesic_wgs84"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake", "~> 10.1"
24
+
25
+ spec.extensions = %w[ext/geodesic_wgs84/extconf.rb]
26
+ end
@@ -0,0 +1,3 @@
1
+ module GeodesicWgs84
2
+ VERSION = "1.32.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require "geodesic_wgs84/version"
2
+
3
+ module GeodesicWgs84
4
+ def self.hi
5
+ puts "Hello from geodesic_wgs84"
6
+ end
7
+ end
8
+
9
+ require "geodesic_wgs84/geodesic_wgs84"
@@ -0,0 +1,25 @@
1
+ require 'minitest/autorun'
2
+ require 'geodesic_wgs84'
3
+
4
+ class TestGeodesicWgs84 < MiniTest::Test
5
+ def setup
6
+ @wgs84 = Wgs84.new
7
+ end
8
+
9
+ def test_lat_lon_two_doubles
10
+ assert_equal [1.0, 2.0], @wgs84.lat_lon(1.0, 2.0)
11
+ end
12
+
13
+ def test_lat_lon_array_of_doubles
14
+ assert_equal [3.5, 4.123], @wgs84.lat_lon([3.5, 4.123])
15
+ end
16
+
17
+ def test_lat_lon_array_of_strings
18
+ assert_equal [3.5, 4.123], @wgs84.lat_lon(["3.5", "4.123"])
19
+ end
20
+
21
+ def test_lat_lon_doubles_with_comma
22
+ assert_equal [1.0, 2.0], @wgs84.lat_lon("1,0", "2,0")
23
+ end
24
+ end
25
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geodesic_wgs84
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.32.1
5
+ platform: ruby
6
+ authors:
7
+ - Volker Wiegand
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.1'
41
+ description: Geodesic functions based on http://geographiclib.sourceforge.net/
42
+ email:
43
+ - volker.wiegand@cvw.de
44
+ executables: []
45
+ extensions:
46
+ - ext/geodesic_wgs84/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - Makefile
53
+ - README.md
54
+ - Rakefile
55
+ - ext/geodesic_wgs84/extconf.rb
56
+ - ext/geodesic_wgs84/geodesic.c
57
+ - ext/geodesic_wgs84/geodesic.h
58
+ - ext/geodesic_wgs84/geodesic_wgs84.c
59
+ - geodesic_wgs84.gemspec
60
+ - lib/geodesic_wgs84.rb
61
+ - lib/geodesic_wgs84/version.rb
62
+ - spec/geodesic_wgs84_spec.rb
63
+ homepage: http://github.com/volkerwiegand/geodesic_wgs84
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.2.2
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Calculate distances on Earth using WGS84
87
+ test_files:
88
+ - spec/geodesic_wgs84_spec.rb