ffi-proj4 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+
2
+ module Proj4
3
+ module Tools
4
+ def bool_result(r)
5
+ case r
6
+ when 1
7
+ true
8
+ when 0
9
+ false
10
+ else
11
+ raise RuntimeError.new("Unexpected boolean result: #{r}")
12
+ end
13
+ end
14
+
15
+ def rad_to_deg!(rad)
16
+ unless rad.nil?
17
+ case rad
18
+ when Proj4::Point, Proj4::ProjXY
19
+ rad.to_deg!
20
+ else
21
+ rad * Proj4::RAD_TO_DEG
22
+ end
23
+ end
24
+ end
25
+
26
+ def rad_to_deg(rad)
27
+ rad_to_deg!(
28
+ !rad.is_a?(Numeric) && rad.respond_to?(:dup) ?
29
+ rad.dup :
30
+ rad
31
+ )
32
+ end
33
+
34
+ def deg_to_rad!(deg)
35
+ unless deg.nil?
36
+ case deg
37
+ when Proj4::Point, Proj4::ProjXY
38
+ deg.to_rad!
39
+ else
40
+ deg * Proj4::DEG_TO_RAD
41
+ end
42
+ end
43
+ end
44
+
45
+ def deg_to_rad(deg)
46
+ deg_to_rad!(
47
+ !deg.is_a?(Numeric) && deg.respond_to?(:dup) ?
48
+ deg.dup :
49
+ deg
50
+ )
51
+ end
52
+
53
+ class << self
54
+ include Proj4::Tools
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,5 @@
1
+
2
+ module Proj4
3
+ VERSION = "0.1.0"
4
+ end
5
+
@@ -0,0 +1,69 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class PointTests < MiniTest::Unit::TestCase
6
+ include TestHelper
7
+
8
+ def rad_deg_tester(method, expected_x, expected_y, expected_z, x, y, z)
9
+ point = Proj4::Point.new(x, y, z)
10
+ point.send("#{method}!")
11
+
12
+ assert_in_delta(expected_x, point.x, TOLERANCE)
13
+ assert_in_delta(expected_y, point.y, TOLERANCE)
14
+ assert_in_delta(expected_z, point.z, TOLERANCE)
15
+
16
+ point = Proj4::Point.new(x, y, z)
17
+ point2 = point.send(method)
18
+
19
+ assert_in_delta(x, point.x, TOLERANCE)
20
+ assert_in_delta(y, point.y, TOLERANCE)
21
+ assert_in_delta(z, point.z, TOLERANCE)
22
+
23
+ assert_in_delta(expected_x, point2.x, TOLERANCE)
24
+ assert_in_delta(expected_y, point2.y, TOLERANCE)
25
+ assert_in_delta(expected_z, point2.z, TOLERANCE)
26
+ end
27
+
28
+ def test_to_rad
29
+ rad_deg_tester(:to_rad,
30
+ 1.0471975511965976,
31
+ 1.5707963267948966,
32
+ 0.7853981633974483,
33
+ 60,
34
+ 90,
35
+ 45
36
+ )
37
+ end
38
+
39
+ def test_to_deg
40
+ rad_deg_tester(:to_deg,
41
+ 60,
42
+ 90,
43
+ 45,
44
+ 1.0471975511965976,
45
+ 1.5707963267948966,
46
+ 0.7853981633974483
47
+ )
48
+ end
49
+
50
+ def test_aliases
51
+ point = Proj4::Point.new(10, 20, 30)
52
+ assert_equal(10, point.x)
53
+ assert_equal(20, point.y)
54
+ assert_equal(10, point.lon)
55
+ assert_equal(20, point.lat)
56
+
57
+ point.lon = 15
58
+ point.lat = 25
59
+
60
+ assert_equal(15, point.x)
61
+ assert_equal(25, point.y)
62
+
63
+ point.x = 80
64
+ point.y = 85
65
+
66
+ assert_equal(80, point.lon)
67
+ assert_equal(85, point.lat)
68
+ end
69
+ end
@@ -0,0 +1,197 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class ProjectionTests < MiniTest::Unit::TestCase
6
+ include TestHelper
7
+
8
+ def definition_sorter(definition)
9
+ definition.split(/\s+/).sort.join(' ')
10
+ end
11
+
12
+ def definition_tester(expected, proj)
13
+ assert_equal(
14
+ definition_sorter(expected),
15
+ definition_sorter(Proj4::Projection.new(proj).definition)
16
+ )
17
+ end
18
+
19
+ def hash_tester(expected, proj)
20
+ hash = proj.to_hash
21
+ assert_equal(expected.size, hash.size)
22
+
23
+ expected.each do |k, v|
24
+ assert_equal(v, hash[k], " Expected #{v} for #{k}, got #{hash[k]}")
25
+ end
26
+ end
27
+
28
+ def test_read_strings
29
+ definition_tester(
30
+ '+init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0',
31
+ 'init=epsg:4326'
32
+ )
33
+
34
+ definition_tester(
35
+ '+datum=potsdam +ellps=bessel +init=epsg:31467 +k=1 +lat_0=0 +lon_0=9 +no_defs +proj=tmerc +towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7 +units=m +x_0=3500000 +y_0=0',
36
+ 'init=epsg:31467'
37
+ )
38
+
39
+ definition_tester(
40
+ '+init=epsg:31528 +proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m +no_defs',
41
+ 'init=epsg:31528'
42
+ )
43
+
44
+ definition_tester(
45
+ '+proj=ortel +lon_0=90w +ellps=WGS84',
46
+ 'proj=ortel lon_0=90w'
47
+ )
48
+
49
+ assert_raises(Proj4::ProjectionParseError) do
50
+ definition_tester(
51
+ '',
52
+ 'gibberish'
53
+ )
54
+ end
55
+ end
56
+
57
+ def test_read_arrays
58
+ definition_tester(
59
+ '+init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0',
60
+ [ 'init=epsg:4326' ]
61
+ )
62
+
63
+ definition_tester(
64
+ '+datum=potsdam +ellps=bessel +init=epsg:31467 +k=1 +lat_0=0 +lon_0=9 +no_defs +proj=tmerc +towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7 +units=m +x_0=3500000 +y_0=0',
65
+ [ 'init=epsg:31467' ]
66
+ )
67
+
68
+ definition_tester(
69
+ '+init=epsg:31528 +proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m +no_defs',
70
+ [ 'init=epsg:31528' ]
71
+ )
72
+
73
+ definition_tester(
74
+ '+proj=ortel +lon_0=90w +ellps=WGS84',
75
+ [ 'proj=ortel', 'lon_0=90w' ]
76
+ )
77
+
78
+ assert_raises(Proj4::ProjectionParseError) do
79
+ definition_tester(
80
+ '',
81
+ [ 'gibberish' ]
82
+ )
83
+ end
84
+ end
85
+
86
+ def test_read_hashes
87
+ definition_tester(
88
+ '+init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0',
89
+ { :init => 'epsg:4326' }
90
+ )
91
+
92
+ definition_tester(
93
+ '+datum=potsdam +ellps=bessel +init=epsg:31467 +k=1 +lat_0=0 +lon_0=9 +no_defs +proj=tmerc +towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7 +units=m +x_0=3500000 +y_0=0',
94
+ { :init => 'epsg:31467' }
95
+ )
96
+
97
+ definition_tester(
98
+ '+init=epsg:31528 +proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m +no_defs',
99
+ { :init => 'epsg:31528' }
100
+ )
101
+
102
+ definition_tester(
103
+ '+lon_0=90w +proj=ortel +ellps=WGS84',
104
+ { :proj => 'ortel', :lon_0 => '90w' }
105
+ )
106
+
107
+ assert_raises(Proj4::ProjectionParseError) do
108
+ definition_tester(
109
+ '',
110
+ { :proj => 'gibberish' }
111
+ )
112
+ end
113
+ end
114
+
115
+ def test_has_inverse
116
+ # XXX - checking if a projection has an inverse isn't supported by the
117
+ # PROJ.4 public API.
118
+ # assert(PROJ_WGS84.hasInverse?)
119
+ # assert(PROJ_GK.hasInverse?)
120
+ # assert(PROJ_CONAKRY.hasInverse?)
121
+ # assert(!PROJ_ORTEL.hasInverse?)
122
+ end
123
+
124
+ def test_is_latlong
125
+ %w{ isLatLong? lat_long? }.each do |method|
126
+ assert(PROJ_WGS84.send(method))
127
+ assert(!PROJ_GK.send(method))
128
+ assert(!PROJ_CONAKRY.send(method))
129
+ assert(!PROJ_ORTEL.send(method))
130
+ end
131
+ end
132
+
133
+ def test_is_geocent
134
+ %w{ isGeocent? isGeocentric? geocentric? }.each do |method|
135
+ assert(!PROJ_WGS84.send(method))
136
+ assert(!PROJ_GK.send(method))
137
+ assert(!PROJ_CONAKRY.send(method))
138
+ assert(!PROJ_ORTEL.send(method))
139
+ end
140
+ end
141
+
142
+ def test_get_def
143
+ %w{ getDef definition }.each do |method|
144
+ assert_equal(
145
+ '+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0',
146
+ PROJ_WGS84.send(method).strip
147
+ )
148
+
149
+ assert_equal(
150
+ '+init=epsg:31467 +proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +datum=potsdam +units=m +no_defs +ellps=bessel +towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7',
151
+ PROJ_GK.send(method).strip
152
+ )
153
+
154
+ assert_equal(
155
+ '+init=epsg:31528 +proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m +no_defs',
156
+ PROJ_CONAKRY.send(method).strip
157
+ )
158
+
159
+ assert_equal(
160
+ '+proj=ortel +lon_0=90w +ellps=WGS84',
161
+ PROJ_ORTEL.send(method).strip
162
+ )
163
+ end
164
+ end
165
+
166
+ def test_inspect
167
+ assert_equal('#<Proj4::Projection +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0>', PROJ_WGS84.to_s)
168
+ assert_equal('#<Proj4::Projection +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0>', PROJ_WGS84.inspect)
169
+ end
170
+
171
+ def test_to_hash
172
+ hash_tester(PROJ_WGS84_HASH, PROJ_WGS84)
173
+ hash_tester(PROJ_GK_HASH, PROJ_GK)
174
+ hash_tester(PROJ_CONAKRY_HASH, PROJ_CONAKRY)
175
+ hash_tester(PROJ_ORTEL_HASH, PROJ_ORTEL)
176
+ end
177
+
178
+ def test_projection
179
+ assert_equal('longlat', PROJ_WGS84.projection)
180
+ assert_equal('tmerc', PROJ_GK.projection)
181
+ assert_equal('utm', PROJ_CONAKRY.projection)
182
+ assert_equal('ortel', PROJ_ORTEL.projection)
183
+ end
184
+
185
+ def test_datum
186
+ assert_equal('WGS84', PROJ_WGS84.datum)
187
+ assert_equal('potsdam', PROJ_GK.datum)
188
+ assert_nil(PROJ_CONAKRY.datum)
189
+ assert_nil(PROJ_ORTEL.datum)
190
+ end
191
+
192
+ def test_shortcut_create
193
+ proj = Proj4::Projection.new("epsg:4326")
194
+
195
+ hash_tester(PROJ_WGS84_HASH, proj)
196
+ end
197
+ end
@@ -0,0 +1,82 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class SimpleTransformationTests < MiniTest::Unit::TestCase
6
+ include TestHelper
7
+
8
+ LONG = 8.4302123334
9
+ LAT = 48.9906726079
10
+ RW = 3458305
11
+ HW = 5428192
12
+
13
+ def simple_transformation_tester(method, expected_x, expected_y, proj, x, y, tolerance = TOLERANCE)
14
+ point = Proj4::Point.new(x, y)
15
+ result = proj.send("#{method}!", point)
16
+
17
+ assert_equal(result.object_id, point.object_id)
18
+ assert_in_delta(expected_x, result.x, tolerance)
19
+ assert_in_delta(expected_y, result.y, tolerance)
20
+
21
+ point = Proj4::Point.new(x, y)
22
+ result = proj.send(method, point)
23
+
24
+ refute_equal(result.object_id, point.object_id)
25
+ assert_in_delta(x, point.x, tolerance)
26
+ assert_in_delta(y, point.y, tolerance)
27
+ assert_in_delta(expected_x, result.x, tolerance)
28
+ assert_in_delta(expected_y, result.y, tolerance)
29
+ end
30
+
31
+ def test_forward
32
+ simple_transformation_tester(
33
+ :forward,
34
+ RW,
35
+ HW,
36
+ PROJ_GK,
37
+ Proj4::Tools.deg_to_rad(LONG),
38
+ Proj4::Tools.deg_to_rad(LAT),
39
+ 0.1
40
+ )
41
+ end
42
+
43
+ def test_inverse
44
+ simple_transformation_tester(
45
+ :inverse,
46
+ Proj4::Tools.deg_to_rad(LONG),
47
+ Proj4::Tools.deg_to_rad(LAT),
48
+ PROJ_GK,
49
+ RW,
50
+ HW
51
+ )
52
+ end
53
+
54
+ def test_forward_deg
55
+ simple_transformation_tester(
56
+ :forward_deg,
57
+ RW,
58
+ HW,
59
+ PROJ_GK,
60
+ LONG,
61
+ LAT,
62
+ 0.1
63
+ )
64
+ end
65
+
66
+ def test_inverse_deg
67
+ simple_transformation_tester(
68
+ :inverse_deg,
69
+ LONG,
70
+ LAT,
71
+ PROJ_GK,
72
+ RW,
73
+ HW
74
+ )
75
+ end
76
+
77
+ def test_out_of_bounds
78
+ assert_raises Proj4::LatitudeOrLongitudeExceededLimitsError do
79
+ PROJ_GK.forward_deg(190, 92)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,87 @@
1
+
2
+ if RUBY_VERSION >= '1.9'
3
+ require 'simplecov'
4
+
5
+ SimpleCov.command_name('FFI Proj4 Unit Tests')
6
+ SimpleCov.start do
7
+ add_filter '/test/'
8
+ end
9
+ end
10
+
11
+ require 'rubygems'
12
+ require 'minitest/autorun'
13
+
14
+ if RUBY_VERSION >= '1.9'
15
+ require 'minitest/reporters'
16
+ end
17
+
18
+ if ENV['USE_BINARY_PROJ4']
19
+ require 'proj4_ruby'
20
+ else
21
+ require File.join(File.dirname(__FILE__), %w{ .. lib ffi-proj4 })
22
+ end
23
+
24
+ Proj4.proj_lib = File.join(File.dirname(__FILE__), %w{ .. data }) if Proj4.respond_to?(:proj_lib)
25
+
26
+ puts "Ruby version #{RUBY_VERSION} - #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}"
27
+ puts "ffi-proj4 version #{Proj4::VERSION}"
28
+ puts "PROJ version #{Proj4.version}"
29
+ if defined?(Proj4::FFIProj4)
30
+ puts "Using #{Array(Proj4::FFIProj4.proj4_library_path).join(', ')}"
31
+ end
32
+ puts "Using PROJ_LIB #{Proj4.proj_lib}"
33
+
34
+ module TestHelper
35
+ TOLERANCE = 0.000001
36
+
37
+ PROJ_WGS84 = Proj4::Projection.new('init=epsg:4326')
38
+ PROJ_GK = Proj4::Projection.new('init=epsg:31467')
39
+ PROJ_CONAKRY = Proj4::Projection.new('init=epsg:31528')
40
+ PROJ_ORTEL = Proj4::Projection.new([ 'proj=ortel', 'lon_0=90w' ])
41
+
42
+ PROJ_WGS84_HASH = {
43
+ :init => 'epsg:4326',
44
+ :proj => 'longlat',
45
+ :datum => 'WGS84',
46
+ :no_defs => true,
47
+ :ellps => 'WGS84',
48
+ :towgs84 => '0,0,0'
49
+ }
50
+
51
+ PROJ_GK_HASH = {
52
+ :init => 'epsg:31467',
53
+ :proj => 'tmerc',
54
+ :lat_0 => '0',
55
+ :lon_0 => '9',
56
+ :k => '1',
57
+ :x_0 => '3500000',
58
+ :y_0 => '0',
59
+ :datum => 'potsdam',
60
+ :units => 'm',
61
+ :no_defs => true,
62
+ :ellps => 'bessel',
63
+ :towgs84 => '598.1,73.7,418.2,0.202,0.045,-2.455,6.7'
64
+ }
65
+
66
+ PROJ_CONAKRY_HASH = {
67
+ :init => 'epsg:31528',
68
+ :proj => 'utm',
69
+ :zone => '28',
70
+ :a => '6378249.2',
71
+ :b => '6356515',
72
+ :towgs84 => '-23,259,-9,0,0,0,0',
73
+ :units => 'm',
74
+ :no_defs => true
75
+ }
76
+
77
+ PROJ_ORTEL_HASH = {
78
+ :proj => 'ortel',
79
+ :lon_0 => '90w',
80
+ :ellps => 'WGS84'
81
+ }
82
+ end
83
+
84
+ if RUBY_VERSION >= '1.9'
85
+ MiniTest::Reporters.use!(MiniTest::Reporters::SpecReporter.new)
86
+ end
87
+