proj4rb 4.1.0 → 5.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +98 -0
- data/Gemfile +4 -4
- data/README.md +53 -0
- data/lib/api/proj.rb +750 -0
- data/lib/api/proj_experimental.rb +7 -0
- data/lib/api/proj_ffi.rb +47 -0
- data/lib/api/proj_version.rb +26 -0
- data/lib/examples/axis_order_normalization.rb +13 -0
- data/lib/examples/batch_transformation.rb +25 -0
- data/lib/examples/context_logging.rb +26 -0
- data/lib/examples/crs_identification.rb +18 -0
- data/lib/examples/database_query.rb +27 -0
- data/lib/examples/geodetic_distance.rb +38 -0
- data/lib/examples/geodetic_to_projected.rb +18 -0
- data/lib/examples/operation_factory_context.rb +19 -0
- data/lib/examples/pipeline_operator.rb +21 -0
- data/lib/examples/promote_demote_3d.rb +23 -0
- data/lib/examples/serialization_formats.rb +17 -0
- data/lib/examples/transform_bounds.rb +18 -0
- data/lib/examples/transformation_with_area.rb +18 -0
- data/lib/proj/area.rb +74 -74
- data/lib/proj/axis_info.rb +44 -44
- data/lib/proj/bounds.rb +22 -0
- data/lib/proj/bounds3d.rb +45 -0
- data/lib/proj/context.rb +57 -23
- data/lib/proj/conversion.rb +94 -91
- data/lib/proj/coordinate.rb +304 -281
- data/lib/proj/coordinate_metadata.rb +38 -0
- data/lib/proj/coordinate_operation_mixin.rb +464 -381
- data/lib/proj/coordinate_system.rb +143 -137
- data/lib/proj/crs.rb +688 -672
- data/lib/proj/crs_info.rb +47 -47
- data/lib/proj/database.rb +310 -305
- data/lib/proj/datum.rb +32 -32
- data/lib/proj/datum_ensemble.rb +34 -34
- data/lib/proj/domain.rb +82 -0
- data/lib/proj/ellipsoid.rb +77 -77
- data/lib/proj/error.rb +7 -8
- data/lib/proj/file_api_callbacks.rb +165 -0
- data/lib/proj/grid.rb +121 -121
- data/lib/proj/grid_cache.rb +65 -64
- data/lib/proj/grid_info.rb +19 -19
- data/lib/proj/life_span.rb +21 -0
- data/lib/proj/network_api_callbacks.rb +86 -0
- data/lib/proj/operation.rb +66 -42
- data/lib/proj/operation_factory_context.rb +4 -2
- data/lib/proj/options.rb +41 -0
- data/lib/proj/parameter.rb +37 -37
- data/lib/proj/parameters.rb +106 -107
- data/lib/proj/pj_axis_description.rb +26 -0
- data/lib/proj/pj_object.rb +602 -670
- data/lib/proj/pj_objects.rb +45 -45
- data/lib/proj/pj_param_description.rb +28 -0
- data/lib/proj/prime_meridian.rb +65 -65
- data/lib/proj/projection.rb +1771 -698
- data/lib/proj/session.rb +2 -0
- data/lib/proj/transformation.rb +102 -102
- data/lib/proj/unit.rb +81 -108
- data/lib/proj.rb +10 -3
- data/lib/proj4.rb +5 -5
- data/proj4rb.gemspec +10 -5
- data/test/abstract_test.rb +7 -28
- data/test/context_test.rb +210 -172
- data/test/context_validation_test.rb +11 -0
- data/test/conversion_test.rb +376 -368
- data/test/coordinate_metadata_test.rb +34 -0
- data/test/coordinate_system_test.rb +162 -144
- data/test/coordinate_test.rb +289 -34
- data/test/crs_test.rb +1112 -1072
- data/test/database_test.rb +407 -359
- data/test/datum_ensemble_test.rb +64 -64
- data/test/datum_test.rb +61 -54
- data/test/domain_test.rb +72 -0
- data/test/ellipsoid_test.rb +80 -80
- data/test/examples_test.rb +149 -0
- data/test/file_api_example.rb +58 -0
- data/test/file_api_test.rb +74 -66
- data/test/grid_cache_test.rb +72 -72
- data/test/grid_test.rb +126 -141
- data/test/network_api_example.rb +48 -0
- data/test/network_api_test.rb +33 -45
- data/test/operation_factory_context_test.rb +225 -201
- data/test/operation_test.rb +40 -29
- data/test/options_test.rb +17 -0
- data/test/parameters_test.rb +86 -40
- data/test/pj_object_test.rb +221 -179
- data/test/prime_meridian_test.rb +75 -75
- data/test/proj_test.rb +58 -58
- data/test/projection_test.rb +680 -650
- data/test/session_test.rb +78 -77
- data/test/transformation_test.rb +238 -210
- data/test/unit_test.rb +114 -76
- metadata +45 -31
- data/ChangeLog +0 -89
- data/README.rdoc +0 -207
- data/lib/api/api.rb +0 -117
- data/lib/api/api_5_0.rb +0 -338
- data/lib/api/api_5_1.rb +0 -7
- data/lib/api/api_5_2.rb +0 -5
- data/lib/api/api_6_0.rb +0 -146
- data/lib/api/api_6_1.rb +0 -5
- data/lib/api/api_6_2.rb +0 -10
- data/lib/api/api_6_3.rb +0 -6
- data/lib/api/api_7_0.rb +0 -69
- data/lib/api/api_7_1.rb +0 -73
- data/lib/api/api_7_2.rb +0 -14
- data/lib/api/api_8_0.rb +0 -6
- data/lib/api/api_8_1.rb +0 -24
- data/lib/api/api_8_2.rb +0 -6
- data/lib/api/api_9_1.rb +0 -7
- data/lib/api/api_9_2.rb +0 -9
- data/lib/api/api_experimental.rb +0 -201
- data/lib/proj/file_api.rb +0 -166
- data/lib/proj/network_api.rb +0 -92
data/test/context_test.rb
CHANGED
|
@@ -1,172 +1,210 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative './abstract_test'
|
|
4
|
-
|
|
5
|
-
class ContextTest < AbstractTest
|
|
6
|
-
def test_create
|
|
7
|
-
context = Proj::Context.new
|
|
8
|
-
assert(context.to_ptr)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def test_finalize
|
|
12
|
-
100.times do
|
|
13
|
-
context = Proj::Context.new
|
|
14
|
-
assert(context.to_ptr)
|
|
15
|
-
GC.start
|
|
16
|
-
end
|
|
17
|
-
assert(true)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def test_clone
|
|
21
|
-
context = Proj::Context.new
|
|
22
|
-
refute(context.use_proj4_init_rules)
|
|
23
|
-
context.use_proj4_init_rules = true
|
|
24
|
-
assert(context.use_proj4_init_rules)
|
|
25
|
-
|
|
26
|
-
clone = context.clone
|
|
27
|
-
assert(clone.use_proj4_init_rules)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_dup
|
|
31
|
-
context = Proj::Context.new
|
|
32
|
-
refute(context.use_proj4_init_rules)
|
|
33
|
-
context.use_proj4_init_rules = true
|
|
34
|
-
assert(context.use_proj4_init_rules)
|
|
35
|
-
|
|
36
|
-
clone = context.clone
|
|
37
|
-
assert(clone.use_proj4_init_rules)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def test_one_per_thread
|
|
41
|
-
context_1 = Proj::Context.current
|
|
42
|
-
context_2 = Proj::Context.current
|
|
43
|
-
assert_same(context_1, context_2)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_search_paths
|
|
47
|
-
context = Proj::Context.new
|
|
48
|
-
path = File.join(Dir.tmpdir, "temp_proj_dic2")
|
|
49
|
-
|
|
50
|
-
begin
|
|
51
|
-
File.open(path, 'wb') do |file|
|
|
52
|
-
file << "<MY_PIPELINE> +proj=pipeline +step +proj=utm +zone=31 +ellps=GRS80"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Try to use the pipeline, an error will occur since it is not on the path
|
|
56
|
-
error = assert_raises(Proj::Error) do
|
|
57
|
-
Proj::Conversion.new("+init=temp_proj_dic2:MY_PIPELINE")
|
|
58
|
-
end
|
|
59
|
-
assert_equal("Invalid value for an argument", error.to_s)
|
|
60
|
-
|
|
61
|
-
# Set the path and try again
|
|
62
|
-
context.search_paths = [File.dirname(path)]
|
|
63
|
-
conversion = Proj::Conversion.new("+init=temp_proj_dic2:MY_PIPELINE", context)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
context
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
data.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
assert_equal(
|
|
107
|
-
assert_equal(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
context
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
context.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
context
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
context.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
context
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
assert_equal(
|
|
171
|
-
end
|
|
172
|
-
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require_relative './abstract_test'
|
|
4
|
+
|
|
5
|
+
class ContextTest < AbstractTest
|
|
6
|
+
def test_create
|
|
7
|
+
context = Proj::Context.new
|
|
8
|
+
assert(context.to_ptr)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_finalize
|
|
12
|
+
100.times do
|
|
13
|
+
context = Proj::Context.new
|
|
14
|
+
assert(context.to_ptr)
|
|
15
|
+
GC.start
|
|
16
|
+
end
|
|
17
|
+
assert(true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_clone
|
|
21
|
+
context = Proj::Context.new
|
|
22
|
+
refute(context.use_proj4_init_rules)
|
|
23
|
+
context.use_proj4_init_rules = true
|
|
24
|
+
assert(context.use_proj4_init_rules)
|
|
25
|
+
|
|
26
|
+
clone = context.clone
|
|
27
|
+
assert(clone.use_proj4_init_rules)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_dup
|
|
31
|
+
context = Proj::Context.new
|
|
32
|
+
refute(context.use_proj4_init_rules)
|
|
33
|
+
context.use_proj4_init_rules = true
|
|
34
|
+
assert(context.use_proj4_init_rules)
|
|
35
|
+
|
|
36
|
+
clone = context.clone
|
|
37
|
+
assert(clone.use_proj4_init_rules)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_one_per_thread
|
|
41
|
+
context_1 = Proj::Context.current
|
|
42
|
+
context_2 = Proj::Context.current
|
|
43
|
+
assert_same(context_1, context_2)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_search_paths
|
|
47
|
+
context = Proj::Context.new
|
|
48
|
+
path = File.join(Dir.tmpdir, "temp_proj_dic2")
|
|
49
|
+
|
|
50
|
+
begin
|
|
51
|
+
File.open(path, 'wb') do |file|
|
|
52
|
+
file << "<MY_PIPELINE> +proj=pipeline +step +proj=utm +zone=31 +ellps=GRS80"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Try to use the pipeline, an error will occur since it is not on the path
|
|
56
|
+
error = assert_raises(Proj::Error) do
|
|
57
|
+
Proj::Conversion.new("+init=temp_proj_dic2:MY_PIPELINE", context)
|
|
58
|
+
end
|
|
59
|
+
assert_equal("Invalid value for an argument", error.to_s)
|
|
60
|
+
|
|
61
|
+
# Set the path and try again
|
|
62
|
+
context.search_paths = [File.dirname(path)]
|
|
63
|
+
conversion = Proj::Conversion.new("+init=temp_proj_dic2:MY_PIPELINE", context)
|
|
64
|
+
assert(conversion)
|
|
65
|
+
ensure
|
|
66
|
+
File.delete(path)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_database_path
|
|
71
|
+
refute_nil(Proj::Context.current.database.path)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_log_level
|
|
75
|
+
assert_equal(:PJ_LOG_ERROR, Proj::Context.current.log_level)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_set_log_level
|
|
79
|
+
context = Proj::Context.new
|
|
80
|
+
context.log_level = :PJ_LOG_ERROR
|
|
81
|
+
assert_equal(:PJ_LOG_ERROR, context.log_level)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_invalid_database_path
|
|
85
|
+
context = Proj::Context.new
|
|
86
|
+
path = '/wrong'
|
|
87
|
+
error = assert_raises(Proj::Error) do
|
|
88
|
+
context.database.path = path
|
|
89
|
+
end
|
|
90
|
+
# TODO - if you run this test on its own you get a useful error message, if you run all tests
|
|
91
|
+
# at once you get a useless error message. Not sure what is causing the difference
|
|
92
|
+
#assert_match(/No such file or directory|generic error of unknown origin|File not found or invalid/, error.to_s)
|
|
93
|
+
assert_equal("Unknown error (code 4096)", error.to_s)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_set_log_function
|
|
97
|
+
context = Proj::Context.new
|
|
98
|
+
called = false
|
|
99
|
+
|
|
100
|
+
data = FFI::MemoryPointer.new(:int)
|
|
101
|
+
data.write_int(5)
|
|
102
|
+
|
|
103
|
+
context.set_log_function(data) do |pointer, int, message|
|
|
104
|
+
called = true
|
|
105
|
+
refute(pointer.null?)
|
|
106
|
+
assert_equal(5, pointer.read_int)
|
|
107
|
+
assert_equal(1, int)
|
|
108
|
+
assert_equal('proj_context_set_database_path: Open of /wrong failed', message)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
begin
|
|
112
|
+
context.database.path = '/wrong'
|
|
113
|
+
rescue
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
assert(called)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_set_log_function_retains_callback_and_data_pointer
|
|
120
|
+
context = Proj::Context.new
|
|
121
|
+
data = FFI::MemoryPointer.new(:int)
|
|
122
|
+
callback = proc { |_pointer, _int, _message| }
|
|
123
|
+
|
|
124
|
+
context.set_log_function(data, &callback)
|
|
125
|
+
|
|
126
|
+
assert_same(callback, context.instance_variable_get(:@log_function))
|
|
127
|
+
assert_same(data, context.instance_variable_get(:@log_data_pointer))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_use_proj4_init_rules
|
|
131
|
+
context = Proj::Context.new
|
|
132
|
+
refute(context.use_proj4_init_rules)
|
|
133
|
+
|
|
134
|
+
context.use_proj4_init_rules = true
|
|
135
|
+
assert(context.use_proj4_init_rules)
|
|
136
|
+
|
|
137
|
+
context.use_proj4_init_rules = false
|
|
138
|
+
refute(context.use_proj4_init_rules)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_network_enabled
|
|
142
|
+
context = Proj::Context.new
|
|
143
|
+
refute(context.network_enabled?)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_network_enabled_set
|
|
147
|
+
context = Proj::Context.new
|
|
148
|
+
refute(context.network_enabled?)
|
|
149
|
+
|
|
150
|
+
context.network_enabled = true
|
|
151
|
+
assert(context.network_enabled?)
|
|
152
|
+
|
|
153
|
+
context.network_enabled = false
|
|
154
|
+
refute(context.network_enabled?)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_url
|
|
158
|
+
context = Proj::Context.new
|
|
159
|
+
assert_equal("https://cdn.proj.org", context.url)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_url_set
|
|
163
|
+
context = Proj::Context.new
|
|
164
|
+
assert_equal("https://cdn.proj.org", context.url)
|
|
165
|
+
|
|
166
|
+
context.url = "https://cdn.proj.org/changed"
|
|
167
|
+
assert_equal("https://cdn.proj.org/changed", context.url)
|
|
168
|
+
|
|
169
|
+
context.url = "https://cdn.proj.org"
|
|
170
|
+
assert_equal("https://cdn.proj.org", context.url)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def test_ca_bundle_path
|
|
174
|
+
context = Proj::Context.new
|
|
175
|
+
context.ca_bundle_path = "/some/path/to/ca-bundle.crt"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def test_user_directory
|
|
179
|
+
context = Proj::Context.new
|
|
180
|
+
assert_match(/proj$/, context.user_directory)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.5.0')
|
|
184
|
+
def test_set_user_writable_directory
|
|
185
|
+
context = Proj::Context.new
|
|
186
|
+
dir = File.join(Dir.tmpdir, "proj4rb-test-#{$$}")
|
|
187
|
+
begin
|
|
188
|
+
context.set_user_writable_directory(dir, create: true)
|
|
189
|
+
assert(Dir.exist?(dir))
|
|
190
|
+
ensure
|
|
191
|
+
Dir.rmdir(dir) if Dir.exist?(dir)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_wkt_dialect
|
|
197
|
+
context = Proj::Context.new
|
|
198
|
+
|
|
199
|
+
wkt = 'LOCAL_CS["foo"]'
|
|
200
|
+
assert_includes([:PJ_GUESSED_WKT2_2015, :PJ_GUESSED_WKT1_GDAL], context.wkt_dialect(wkt))
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def test_destroy
|
|
204
|
+
context = Proj::Context.new
|
|
205
|
+
refute(context.to_ptr.null?)
|
|
206
|
+
|
|
207
|
+
context.destroy
|
|
208
|
+
assert(context.to_ptr.null?)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require_relative './abstract_test'
|
|
2
|
+
|
|
3
|
+
class ContextValidationTest < AbstractTest
|
|
4
|
+
def test_create_engineering_requires_proj_context
|
|
5
|
+
error = assert_raises(TypeError) do
|
|
6
|
+
Proj::Crs.create_engineering("EPSG", name: "4807")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
assert_equal("expected Proj::Context, got String", error.message)
|
|
10
|
+
end
|
|
11
|
+
end
|