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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +34 -0
- data/Makefile +13 -0
- data/README.md +58 -0
- data/Rakefile +17 -0
- data/ext/geodesic_wgs84/extconf.rb +13 -0
- data/ext/geodesic_wgs84/geodesic.c +1770 -0
- data/ext/geodesic_wgs84/geodesic.h +745 -0
- data/ext/geodesic_wgs84/geodesic_wgs84.c +192 -0
- data/geodesic_wgs84.gemspec +26 -0
- data/lib/geodesic_wgs84/version.rb +3 -0
- data/lib/geodesic_wgs84.rb +9 -0
- data/spec/geodesic_wgs84_spec.rb +25 -0
- metadata +88 -0
|
@@ -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,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
|