geodesic_wgs84 1.32.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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