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.
Files changed (115) 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 -0
  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 -672
  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 -670
  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 +1771 -698
  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 -28
  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 -1072
  71. data/test/database_test.rb +407 -359
  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 -201
  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 -179
  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 +45 -31
  95. data/ChangeLog +0 -89
  96. data/README.rdoc +0 -207
  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_experimental.rb +0 -201
  114. data/lib/proj/file_api.rb +0 -166
  115. 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,201 +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 proj9?
55
- 2
56
- else
57
- 7
58
- end
59
- assert_equal(expected, index)
60
-
61
- operation = operations[index]
62
-
63
- expected = case
64
- when proj9?
65
- "NAD27 to NAD83 (1)"
66
- else
67
- "Ballpark geographic offset from NAD27 to NAD83"
68
- end
69
-
70
- assert_equal(expected, operation.name)
71
- end
72
-
73
- def test_ballpark_transformations
74
- context = Proj::Context.new
75
- source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
76
- target = Proj::Crs.create_from_database("EPSG", "4258", :PJ_CATEGORY_CRS)
77
-
78
- factory_context = Proj::OperationFactoryContext.new(context)
79
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
80
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
81
-
82
- # Allowed implicitly
83
- operations = factory_context.create_operations(source, target)
84
- assert_equal(1, operations.count)
85
-
86
- # Allow explicitly
87
- factory_context.ballpark_transformations = true
88
- operations = factory_context.create_operations(source, target)
89
- assert_equal(1, operations.count)
90
-
91
- # Disallow
92
- factory_context.ballpark_transformations = false
93
- operations = factory_context.create_operations(source, target)
94
- assert_equal(0, operations.count)
95
- end
96
-
97
- def test_desired_accuracy
98
- context = Proj::Context.new
99
- factory_context = Proj::OperationFactoryContext.new(context)
100
- factory_context.desired_accuracy = 5
101
- end
102
-
103
- def test_set_area_of_interest
104
- context = Proj::Context.new
105
- factory_context = Proj::OperationFactoryContext.new(context)
106
- factory_context.set_area_of_interest(10, 10, 10, 10)
107
- end
108
-
109
- def test_crs_extent_use
110
- context = Proj::Context.new
111
- factory_context = Proj::OperationFactoryContext.new(context)
112
- factory_context.crs_extent_use = :PJ_CRS_EXTENT_SMALLEST
113
- end
114
-
115
- def test_spatial_criterion
116
- context = Proj::Context.new
117
- factory_context = Proj::OperationFactoryContext.new(context)
118
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT
119
- end
120
-
121
- def test_grid_availability
122
- context = Proj::Context.new
123
- factory_context = Proj::OperationFactoryContext.new(context)
124
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_USE
125
- end
126
-
127
- def test_use_proj_alternative_grid_names
128
- context = Proj::Context.new
129
- factory_context = Proj::OperationFactoryContext.new(context)
130
- factory_context.use_proj_alternative_grid_names = true
131
- end
132
-
133
- def test_allow_use_intermediate_crs
134
- context = Proj::Context.new
135
- # There is no direct transformations between both
136
- source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
137
- target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
138
-
139
- # Default behavior: allow any pivot
140
- factory_context = Proj::OperationFactoryContext.new(context)
141
- operations = factory_context.create_operations(source, target)
142
- assert_equal(1, operations.count)
143
-
144
- operation = operations[0]
145
- assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
146
- refute(operation.ballpark_transformation?)
147
-
148
- # Disallow pivots
149
- factory_context.allow_use_intermediate_crs = :PROJ_INTERMEDIATE_CRS_USE_NEVER
150
- operations = factory_context.create_operations(source, target)
151
- assert_equal(1, operations.count)
152
-
153
- operation = operations[0]
154
- assert_equal("Ballpark geographic offset from ED50 to RGF93 v1", operation.name)
155
- assert(operation.ballpark_transformation?)
156
- end
157
-
158
- def test_allowed_intermediate_crs
159
- context = Proj::Context.new
160
-
161
- # There is no direct transformations between both
162
- source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
163
- target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
164
-
165
- # Restrict pivot to ETRS89
166
- factory_context = Proj::OperationFactoryContext.new(context, authority: "EPSG")
167
- factory_context.allowed_intermediate_crs = ["EPSG", "4258"]
168
-
169
- operations = factory_context.create_operations(source, target)
170
- assert_equal(1, operations.count)
171
-
172
- operation = operations[0]
173
- assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
174
- end
175
-
176
- def test_discard_superseded
177
- context = Proj::Context.new
178
- source = Proj::Crs.create_from_database("EPSG", "4203", :PJ_CATEGORY_CRS)
179
- target = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
180
-
181
- factory_context = Proj::OperationFactoryContext.new(context)
182
- factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
183
- factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
184
-
185
- factory_context.discard_superseded = true
186
- operations = factory_context.create_operations(source, target)
187
- assert_equal(4, operations.count)
188
-
189
- factory_context.discard_superseded = false
190
- operations = factory_context.create_operations(source, target)
191
- assert_equal(5, operations.count)
192
- end
193
-
194
- if proj9?
195
- def test_set_area_of_interest_name
196
- context = Proj::Context.new
197
- factory_context = Proj::OperationFactoryContext.new(context)
198
- factory_context.area_of_interest_name = 'test'
199
- end
200
- end
201
- 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