ffi-proj4 0.1.0

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,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
+