proj4rb 4.1.1 → 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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/Gemfile +4 -4
  4. data/README.md +53 -0
  5. data/lib/api/proj.rb +750 -0
  6. data/lib/api/proj_experimental.rb +7 -0
  7. data/lib/api/proj_ffi.rb +47 -0
  8. data/lib/api/proj_version.rb +26 -0
  9. data/lib/examples/axis_order_normalization.rb +13 -0
  10. data/lib/examples/batch_transformation.rb +25 -0
  11. data/lib/examples/context_logging.rb +26 -0
  12. data/lib/examples/crs_identification.rb +18 -0
  13. data/lib/examples/database_query.rb +27 -0
  14. data/lib/examples/geodetic_distance.rb +38 -0
  15. data/lib/examples/geodetic_to_projected.rb +18 -0
  16. data/lib/examples/operation_factory_context.rb +19 -0
  17. data/lib/examples/pipeline_operator.rb +21 -0
  18. data/lib/examples/promote_demote_3d.rb +23 -0
  19. data/lib/examples/serialization_formats.rb +17 -0
  20. data/lib/examples/transform_bounds.rb +18 -0
  21. data/lib/examples/transformation_with_area.rb +18 -0
  22. data/lib/proj/area.rb +74 -74
  23. data/lib/proj/axis_info.rb +44 -44
  24. data/lib/proj/bounds.rb +22 -0
  25. data/lib/proj/bounds3d.rb +45 -0
  26. data/lib/proj/context.rb +57 -23
  27. data/lib/proj/conversion.rb +94 -91
  28. data/lib/proj/coordinate.rb +304 -281
  29. data/lib/proj/coordinate_metadata.rb +38 -38
  30. data/lib/proj/coordinate_operation_mixin.rb +464 -381
  31. data/lib/proj/coordinate_system.rb +143 -137
  32. data/lib/proj/crs.rb +688 -680
  33. data/lib/proj/crs_info.rb +47 -47
  34. data/lib/proj/database.rb +310 -305
  35. data/lib/proj/datum.rb +32 -32
  36. data/lib/proj/datum_ensemble.rb +34 -34
  37. data/lib/proj/domain.rb +82 -0
  38. data/lib/proj/ellipsoid.rb +77 -77
  39. data/lib/proj/error.rb +7 -8
  40. data/lib/proj/file_api_callbacks.rb +165 -0
  41. data/lib/proj/grid.rb +121 -121
  42. data/lib/proj/grid_cache.rb +65 -64
  43. data/lib/proj/grid_info.rb +19 -19
  44. data/lib/proj/life_span.rb +21 -0
  45. data/lib/proj/network_api_callbacks.rb +86 -0
  46. data/lib/proj/operation.rb +66 -42
  47. data/lib/proj/operation_factory_context.rb +4 -2
  48. data/lib/proj/options.rb +41 -0
  49. data/lib/proj/parameter.rb +37 -37
  50. data/lib/proj/parameters.rb +106 -107
  51. data/lib/proj/pj_axis_description.rb +26 -0
  52. data/lib/proj/pj_object.rb +602 -672
  53. data/lib/proj/pj_objects.rb +45 -45
  54. data/lib/proj/pj_param_description.rb +28 -0
  55. data/lib/proj/prime_meridian.rb +65 -65
  56. data/lib/proj/projection.rb +54 -25
  57. data/lib/proj/session.rb +2 -0
  58. data/lib/proj/transformation.rb +102 -102
  59. data/lib/proj/unit.rb +81 -108
  60. data/lib/proj.rb +10 -3
  61. data/lib/proj4.rb +5 -5
  62. data/proj4rb.gemspec +10 -5
  63. data/test/abstract_test.rb +7 -5
  64. data/test/context_test.rb +210 -172
  65. data/test/context_validation_test.rb +11 -0
  66. data/test/conversion_test.rb +376 -368
  67. data/test/coordinate_metadata_test.rb +34 -0
  68. data/test/coordinate_system_test.rb +162 -144
  69. data/test/coordinate_test.rb +289 -34
  70. data/test/crs_test.rb +1112 -1082
  71. data/test/database_test.rb +407 -391
  72. data/test/datum_ensemble_test.rb +64 -64
  73. data/test/datum_test.rb +61 -54
  74. data/test/domain_test.rb +72 -0
  75. data/test/ellipsoid_test.rb +80 -80
  76. data/test/examples_test.rb +149 -0
  77. data/test/file_api_example.rb +58 -0
  78. data/test/file_api_test.rb +74 -66
  79. data/test/grid_cache_test.rb +72 -72
  80. data/test/grid_test.rb +126 -141
  81. data/test/network_api_example.rb +48 -0
  82. data/test/network_api_test.rb +33 -45
  83. data/test/operation_factory_context_test.rb +225 -205
  84. data/test/operation_test.rb +40 -29
  85. data/test/options_test.rb +17 -0
  86. data/test/parameters_test.rb +86 -40
  87. data/test/pj_object_test.rb +221 -187
  88. data/test/prime_meridian_test.rb +75 -75
  89. data/test/proj_test.rb +58 -58
  90. data/test/projection_test.rb +680 -650
  91. data/test/session_test.rb +78 -77
  92. data/test/transformation_test.rb +238 -210
  93. data/test/unit_test.rb +114 -76
  94. metadata +44 -32
  95. data/ChangeLog +0 -94
  96. data/README.rdoc +0 -189
  97. data/lib/api/api.rb +0 -117
  98. data/lib/api/api_5_0.rb +0 -338
  99. data/lib/api/api_5_1.rb +0 -7
  100. data/lib/api/api_5_2.rb +0 -5
  101. data/lib/api/api_6_0.rb +0 -146
  102. data/lib/api/api_6_1.rb +0 -5
  103. data/lib/api/api_6_2.rb +0 -10
  104. data/lib/api/api_6_3.rb +0 -6
  105. data/lib/api/api_7_0.rb +0 -69
  106. data/lib/api/api_7_1.rb +0 -73
  107. data/lib/api/api_7_2.rb +0 -14
  108. data/lib/api/api_8_0.rb +0 -6
  109. data/lib/api/api_8_1.rb +0 -24
  110. data/lib/api/api_8_2.rb +0 -6
  111. data/lib/api/api_9_1.rb +0 -7
  112. data/lib/api/api_9_2.rb +0 -9
  113. data/lib/api/api_9_4.rb +0 -6
  114. data/lib/api/api_experimental.rb +0 -201
  115. data/lib/proj/file_api.rb +0 -166
  116. data/lib/proj/network_api.rb +0 -92
@@ -1,45 +1,33 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class NetworkApiTest < AbstractTest
6
- def setup
7
- super
8
- # Make sure downloader callbacks are not GCed
9
- #GC.stress = true
10
- end
11
-
12
- def teardown
13
- super
14
- GC.stress = false
15
- end
16
-
17
- def test_download
18
- skip "This test causes a segfault due to the way Proj cleans up on shutdown"
19
-
20
- context = Proj::Context.new
21
- context.network_enabled = true
22
-
23
- # Create a grid
24
- grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
25
- grid.delete
26
-
27
- context.cache.clear
28
-
29
- # Install custom network api
30
- context.set_network_api(Proj::NetworkApiImpl)
31
-
32
- conversion = Proj::Conversion.new(<<~EOS, context)
33
- +proj=pipeline
34
- +step +proj=unitconvert +xy_in=deg +xy_out=rad
35
- +step +proj=vgridshift +grids=dk_sdfe_dvr90.tif +multiplier=1
36
- +step +proj=unitconvert +xy_in=rad +xy_out=deg
37
- EOS
38
-
39
- coord = Proj::Coordinate.new(lon: 12, lat: 56, z: 0)
40
- new_coord = conversion.forward(coord)
41
- assert_in_delta(12, new_coord.lon)
42
- assert_in_delta(56, new_coord.lat)
43
- assert_in_delta(36.5909996032715, new_coord.z, 1e-10)
44
- end
45
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+ require_relative './network_api_example'
5
+
6
+ class NetworkApiTest < AbstractTest
7
+ def test_download
8
+ context = Proj::Context.new
9
+ context.network_enabled = true
10
+
11
+ # Create a grid
12
+ grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
13
+ grid.delete
14
+
15
+ context.cache.clear
16
+
17
+ # Install custom network api
18
+ context.set_network_api(Proj::NetworkApiExample)
19
+
20
+ conversion = Proj::Conversion.new(<<~EOS, context)
21
+ +proj=pipeline
22
+ +step +proj=unitconvert +xy_in=deg +xy_out=rad
23
+ +step +proj=vgridshift +grids=dk_sdfe_dvr90.tif +multiplier=1
24
+ +step +proj=unitconvert +xy_in=rad +xy_out=deg
25
+ EOS
26
+
27
+ coord = Proj::Coordinate.new(lon: 12, lat: 56, z: 0)
28
+ new_coord = conversion.forward(coord)
29
+ assert_in_delta(12, new_coord.lon)
30
+ assert_in_delta(56, new_coord.lat)
31
+ assert_in_delta(36.5909996032715, new_coord.z, 1e-10)
32
+ end
33
+ end
@@ -1,205 +1,225 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class OperationFactoryContextTest < AbstractTest
6
- def test_create
7
- context = Proj::Context.new
8
- factory_context = Proj::OperationFactoryContext.new(context)
9
- assert(context.to_ptr)
10
- end
11
-
12
- def test_finalize
13
- 100.times do
14
- context = Proj::Context.new
15
- factory_context = Proj::OperationFactoryContext.new(context)
16
- assert(context.to_ptr)
17
- GC.start
18
- end
19
- assert(true)
20
- end
21
-
22
- def test_create_operations
23
- context = Proj::Context.new
24
- source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
25
- target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
26
-
27
- factory_context = Proj::OperationFactoryContext.new(context)
28
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
29
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
30
-
31
- operations = factory_context.create_operations(source, target)
32
- assert_equal(10, operations.count)
33
-
34
- operation = operations[0]
35
- assert_equal("NAD27 to NAD83 (4)", operation.name)
36
- refute(operation.ballpark_transformation?)
37
- end
38
-
39
- def test_suggested_operation
40
- context = Proj::Context.new
41
- source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
42
- target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
43
-
44
- factory_context = Proj::OperationFactoryContext.new(context)
45
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
46
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
47
-
48
- operations = factory_context.create_operations(source, target)
49
-
50
- coord = Proj::Coordinate.new(x: 40, y: -100)
51
- index = operations.suggested_operation(:PJ_FWD, coord)
52
-
53
- expected = case
54
- when Proj::Api::PROJ_VERSION >= '9.3.0'
55
- 3
56
- when Proj::Api::PROJ_VERSION >= '9.0.0'
57
- 2
58
- else
59
- 7
60
- end
61
- assert_equal(expected, index)
62
-
63
- operation = operations[index]
64
-
65
- expected = case
66
- when Proj::Api::PROJ_VERSION >= '9.3.0'
67
- "NAD27 to NAD83 (7)"
68
- when Proj::Api::PROJ_VERSION >= '9.0.0'
69
- "NAD27 to NAD83 (1)"
70
- else
71
- "Ballpark geographic offset from NAD27 to NAD83"
72
- end
73
-
74
- assert_equal(expected, operation.name)
75
- end
76
-
77
- def test_ballpark_transformations
78
- context = Proj::Context.new
79
- source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
80
- target = Proj::Crs.create_from_database("EPSG", "4258", :PJ_CATEGORY_CRS)
81
-
82
- factory_context = Proj::OperationFactoryContext.new(context)
83
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
84
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
85
-
86
- # Allowed implicitly
87
- operations = factory_context.create_operations(source, target)
88
- assert_equal(1, operations.count)
89
-
90
- # Allow explicitly
91
- factory_context.ballpark_transformations = true
92
- operations = factory_context.create_operations(source, target)
93
- assert_equal(1, operations.count)
94
-
95
- # Disallow
96
- factory_context.ballpark_transformations = false
97
- operations = factory_context.create_operations(source, target)
98
- assert_equal(0, operations.count)
99
- end
100
-
101
- def test_desired_accuracy
102
- context = Proj::Context.new
103
- factory_context = Proj::OperationFactoryContext.new(context)
104
- factory_context.desired_accuracy = 5
105
- end
106
-
107
- def test_set_area_of_interest
108
- context = Proj::Context.new
109
- factory_context = Proj::OperationFactoryContext.new(context)
110
- factory_context.set_area_of_interest(10, 10, 10, 10)
111
- end
112
-
113
- def test_crs_extent_use
114
- context = Proj::Context.new
115
- factory_context = Proj::OperationFactoryContext.new(context)
116
- factory_context.crs_extent_use = :PJ_CRS_EXTENT_SMALLEST
117
- end
118
-
119
- def test_spatial_criterion
120
- context = Proj::Context.new
121
- factory_context = Proj::OperationFactoryContext.new(context)
122
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT
123
- end
124
-
125
- def test_grid_availability
126
- context = Proj::Context.new
127
- factory_context = Proj::OperationFactoryContext.new(context)
128
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_USE
129
- end
130
-
131
- def test_use_proj_alternative_grid_names
132
- context = Proj::Context.new
133
- factory_context = Proj::OperationFactoryContext.new(context)
134
- factory_context.use_proj_alternative_grid_names = true
135
- end
136
-
137
- def test_allow_use_intermediate_crs
138
- context = Proj::Context.new
139
- # There is no direct transformations between both
140
- source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
141
- target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
142
-
143
- # Default behavior: allow any pivot
144
- factory_context = Proj::OperationFactoryContext.new(context)
145
- operations = factory_context.create_operations(source, target)
146
- assert_equal(1, operations.count)
147
-
148
- operation = operations[0]
149
- assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
150
- refute(operation.ballpark_transformation?)
151
-
152
- # Disallow pivots
153
- factory_context.allow_use_intermediate_crs = :PROJ_INTERMEDIATE_CRS_USE_NEVER
154
- operations = factory_context.create_operations(source, target)
155
- assert_equal(1, operations.count)
156
-
157
- operation = operations[0]
158
- assert_equal("Ballpark geographic offset from ED50 to RGF93 v1", operation.name)
159
- assert(operation.ballpark_transformation?)
160
- end
161
-
162
- def test_allowed_intermediate_crs
163
- context = Proj::Context.new
164
-
165
- # There is no direct transformations between both
166
- source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
167
- target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
168
-
169
- # Restrict pivot to ETRS89
170
- factory_context = Proj::OperationFactoryContext.new(context, authority: "EPSG")
171
- factory_context.allowed_intermediate_crs = ["EPSG", "4258"]
172
-
173
- operations = factory_context.create_operations(source, target)
174
- assert_equal(1, operations.count)
175
-
176
- operation = operations[0]
177
- assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
178
- end
179
-
180
- def test_discard_superseded
181
- context = Proj::Context.new
182
- source = Proj::Crs.create_from_database("EPSG", "4203", :PJ_CATEGORY_CRS)
183
- target = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
184
-
185
- factory_context = Proj::OperationFactoryContext.new(context)
186
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
187
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
188
-
189
- factory_context.discard_superseded = true
190
- operations = factory_context.create_operations(source, target)
191
- assert_equal(4, operations.count)
192
-
193
- factory_context.discard_superseded = false
194
- operations = factory_context.create_operations(source, target)
195
- assert_equal(5, operations.count)
196
- end
197
-
198
- if Proj::Api::PROJ_VERSION >= '9.0.0'
199
- def test_set_area_of_interest_name
200
- context = Proj::Context.new
201
- factory_context = Proj::OperationFactoryContext.new(context)
202
- factory_context.area_of_interest_name = 'test'
203
- end
204
- end
205
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class OperationFactoryContextTest < AbstractTest
6
+ def test_create
7
+ context = Proj::Context.new
8
+ factory_context = Proj::OperationFactoryContext.new(context)
9
+ assert(factory_context)
10
+ end
11
+
12
+ def test_retains_passed_context
13
+ context = Proj::Context.new
14
+ factory_context = Proj::OperationFactoryContext.new(context)
15
+ assert_same(context, factory_context.context)
16
+ end
17
+
18
+ def test_finalize
19
+ 100.times do
20
+ context = Proj::Context.new
21
+ factory_context = Proj::OperationFactoryContext.new(context)
22
+ assert(factory_context)
23
+ GC.start
24
+ end
25
+ end
26
+
27
+ def test_create_operations
28
+ context = Proj::Context.new
29
+ source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
30
+ target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
31
+
32
+ factory_context = Proj::OperationFactoryContext.new(context)
33
+ factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
34
+ factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
35
+
36
+ operations = factory_context.create_operations(source, target)
37
+ assert_equal(10, operations.count)
38
+
39
+ operation = operations[0]
40
+ assert_equal("NAD27 to NAD83 (4)", operation.name)
41
+ refute(operation.ballpark_transformation?)
42
+ end
43
+
44
+ def test_suggested_operation
45
+ context = Proj::Context.new
46
+ source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
47
+ target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
48
+
49
+ factory_context = Proj::OperationFactoryContext.new(context)
50
+ factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
51
+ factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
52
+
53
+ operations = factory_context.create_operations(source, target)
54
+
55
+ coord = Proj::Coordinate.new(x: 40, y: -100)
56
+ index = operations.suggested_operation(:PJ_FWD, coord)
57
+
58
+ expected = case
59
+ when Proj::Api::PROJ_VERSION >= '9.3.0'
60
+ 3
61
+ when Proj::Api::PROJ_VERSION >= '9.0.0'
62
+ 2
63
+ else
64
+ 7
65
+ end
66
+ assert_equal(expected, index)
67
+
68
+ operation = operations[index]
69
+
70
+ expected = case
71
+ when Proj::Api::PROJ_VERSION >= '9.3.0'
72
+ "NAD27 to NAD83 (7)"
73
+ when Proj::Api::PROJ_VERSION >= '9.0.0'
74
+ "NAD27 to NAD83 (1)"
75
+ else
76
+ "Ballpark geographic offset from NAD27 to NAD83"
77
+ end
78
+
79
+ assert_equal(expected, operation.name)
80
+ end
81
+
82
+ def test_ballpark_transformations
83
+ context = Proj::Context.new
84
+ source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
85
+ target = Proj::Crs.create_from_database("EPSG", "4258", :PJ_CATEGORY_CRS)
86
+
87
+ factory_context = Proj::OperationFactoryContext.new(context)
88
+ factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
89
+ factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
90
+
91
+ # Allowed implicitly
92
+ operations = factory_context.create_operations(source, target)
93
+ assert_equal(1, operations.count)
94
+
95
+ # Allow explicitly
96
+ factory_context.ballpark_transformations = true
97
+ operations = factory_context.create_operations(source, target)
98
+ assert_equal(1, operations.count)
99
+
100
+ # Disallow
101
+ factory_context.ballpark_transformations = false
102
+ operations = factory_context.create_operations(source, target)
103
+ assert_equal(0, operations.count)
104
+ end
105
+
106
+ def test_desired_accuracy
107
+ context = Proj::Context.new
108
+ factory_context = Proj::OperationFactoryContext.new(context)
109
+ factory_context.desired_accuracy = 5
110
+ end
111
+
112
+ def test_set_area_of_interest
113
+ context = Proj::Context.new
114
+ factory_context = Proj::OperationFactoryContext.new(context)
115
+ factory_context.set_area_of_interest(10, 10, 10, 10)
116
+ end
117
+
118
+ def test_crs_extent_use
119
+ context = Proj::Context.new
120
+ factory_context = Proj::OperationFactoryContext.new(context)
121
+ factory_context.crs_extent_use = :PJ_CRS_EXTENT_SMALLEST
122
+ end
123
+
124
+ def test_spatial_criterion
125
+ context = Proj::Context.new
126
+ factory_context = Proj::OperationFactoryContext.new(context)
127
+ factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT
128
+ end
129
+
130
+ def test_grid_availability
131
+ context = Proj::Context.new
132
+ factory_context = Proj::OperationFactoryContext.new(context)
133
+ factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_USED_FOR_SORTING
134
+ end
135
+
136
+ def test_use_proj_alternative_grid_names
137
+ context = Proj::Context.new
138
+ factory_context = Proj::OperationFactoryContext.new(context)
139
+ factory_context.use_proj_alternative_grid_names = true
140
+ end
141
+
142
+ def test_allow_use_intermediate_crs
143
+ context = Proj::Context.new
144
+ # There is no direct transformations between both
145
+ source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
146
+ target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
147
+
148
+ # Default behavior: allow any pivot
149
+ factory_context = Proj::OperationFactoryContext.new(context)
150
+ operations = factory_context.create_operations(source, target)
151
+ assert_equal(1, operations.count)
152
+
153
+ operation = operations[0]
154
+ expected_name = if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.8.0')
155
+ "ED50 to ETRS89 (10) + ETRS89 to ETRS89-FRA [RGF93 v1]"
156
+ else
157
+ "ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)"
158
+ end
159
+ assert_equal(expected_name, operation.name)
160
+ refute(operation.ballpark_transformation?)
161
+
162
+ # Disallow pivots
163
+ factory_context.allow_use_intermediate_crs = :PROJ_INTERMEDIATE_CRS_USE_NEVER
164
+ operations = factory_context.create_operations(source, target)
165
+ assert_equal(1, operations.count)
166
+
167
+ operation = operations[0]
168
+ expected_name = if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.8.0')
169
+ "Ballpark geographic offset from ED50 to ETRS89-FRA [RGF93 v1]"
170
+ else
171
+ "Ballpark geographic offset from ED50 to RGF93 v1"
172
+ end
173
+ assert_equal(expected_name, operation.name)
174
+ assert(operation.ballpark_transformation?)
175
+ end
176
+
177
+ def test_allowed_intermediate_crs
178
+ context = Proj::Context.new
179
+
180
+ # There is no direct transformations between both
181
+ source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
182
+ target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
183
+
184
+ # Restrict pivot to ETRS89
185
+ factory_context = Proj::OperationFactoryContext.new(context, authority: "EPSG")
186
+ factory_context.allowed_intermediate_crs = ["EPSG", "4258"]
187
+
188
+ operations = factory_context.create_operations(source, target)
189
+ assert_equal(1, operations.count)
190
+
191
+ operation = operations[0]
192
+ expected_name = if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.8.0')
193
+ "Ballpark geographic offset from ED50 to ETRS89-FRA [RGF93 v1]"
194
+ else
195
+ "ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)"
196
+ end
197
+ assert_equal(expected_name, operation.name)
198
+ end
199
+
200
+ def test_discard_superseded
201
+ context = Proj::Context.new
202
+ source = Proj::Crs.create_from_database("EPSG", "4203", :PJ_CATEGORY_CRS)
203
+ target = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
204
+
205
+ factory_context = Proj::OperationFactoryContext.new(context)
206
+ factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
207
+ factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
208
+
209
+ factory_context.discard_superseded = true
210
+ operations = factory_context.create_operations(source, target)
211
+ assert_equal(4, operations.count)
212
+
213
+ factory_context.discard_superseded = false
214
+ operations = factory_context.create_operations(source, target)
215
+ assert_equal(5, operations.count)
216
+ end
217
+
218
+ if Proj::Api::PROJ_VERSION >= '9.0.0'
219
+ def test_set_area_of_interest_name
220
+ context = Proj::Context.new
221
+ factory_context = Proj::OperationFactoryContext.new(context)
222
+ factory_context.area_of_interest_name = 'test'
223
+ end
224
+ end
225
+ end
@@ -1,29 +1,40 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class OperationTest < AbstractTest
6
- def test_get_all
7
- operations = Proj::Operation.list.map {|operation| operation.id}
8
- assert(operations.include?('aea'))
9
- assert(operations.include?('wintri'))
10
- end
11
-
12
- def test_one
13
- operation = Proj::Operation.get('rouss')
14
- assert_kind_of(Proj::Operation, operation)
15
- assert_equal('rouss', operation.id)
16
- assert_equal("Roussilhe Stereographic\n\tAzi, Ell", operation.description)
17
- end
18
-
19
- def test_equal
20
- e1 = Proj::Operation.get('rouss')
21
- e2 = Proj::Operation.get('rouss')
22
- assert(e1 == e2)
23
- end
24
-
25
- def test_failed_get
26
- operation = Proj::Operation.get('foo')
27
- assert_nil(operation)
28
- end
29
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class OperationTest < AbstractTest
6
+ def test_get_all
7
+ operations = Proj::Operation.list.map {|operation| operation.id}
8
+ assert(operations.include?('aea'))
9
+ assert(operations.include?('wintri'))
10
+ end
11
+
12
+ def test_one
13
+ operation = Proj::Operation.get('rouss')
14
+ assert_kind_of(Proj::Operation, operation)
15
+ assert_equal('rouss', operation.id)
16
+ assert_equal("Roussilhe Stereographic\n\tAzi, Ell", operation.description)
17
+ end
18
+
19
+ def test_equal
20
+ e1 = Proj::Operation.get('rouss')
21
+ e2 = Proj::Operation.get('rouss')
22
+ assert(e1 == e2)
23
+ end
24
+
25
+ def test_failed_get
26
+ operation = Proj::Operation.get('foo')
27
+ assert_nil(operation)
28
+ end
29
+
30
+ def test_to_s
31
+ operation = Proj::Operation.get('aea')
32
+ assert_equal('aea', operation.to_s)
33
+ end
34
+
35
+ def test_inspect
36
+ operation = Proj::Operation.get('aea')
37
+ assert_match(/id="aea"/, operation.inspect)
38
+ assert_match(/description=/, operation.inspect)
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ require_relative './abstract_test'
2
+
3
+ class OptionsTest < AbstractTest
4
+ def test_builds_null_terminated_pointer_array
5
+ options = Proj::Options.new("MULTILINE": "YES", "INDENTATION_WIDTH": 4)
6
+ pointers = options.to_ptr.get_array_of_pointer(0, 3)
7
+
8
+ refute(pointers[0].null?)
9
+ refute(pointers[1].null?)
10
+ assert(pointers[2].null?)
11
+ end
12
+
13
+ def test_empty_options_returns_null_pointer
14
+ options = Proj::Options.new({})
15
+ assert(options.to_ptr.null?)
16
+ end
17
+ end