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
data/test/crs_test.rb CHANGED
@@ -1,1072 +1,1112 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class CrsTest < AbstractTest
6
- def test_create_from_epsg
7
- crs = Proj::Crs.new('EPSG:4326')
8
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
9
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
10
-
11
- assert_nil(crs.id)
12
- assert_equal('WGS 84', crs.description)
13
- assert_empty(crs.definition)
14
- refute(crs.has_inverse?)
15
- assert_equal(-1.0, crs.accuracy)
16
- end
17
-
18
- def test_create_from_urn
19
- crs = Proj::Crs.new('urn:ogc:def:crs:EPSG::4326')
20
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
21
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
22
- end
23
-
24
- def test_create_from_wkt
25
- crs = Proj::Crs.new(<<~EOS)
26
- GEOGCRS["WGS 84",
27
- DATUM["World Geodetic System 1984",
28
- ELLIPSOID["WGS 84",6378137,298.257223563,
29
- LENGTHUNIT["metre",1]]],
30
- PRIMEM["Greenwich",0,
31
- ANGLEUNIT["degree",0.0174532925199433]],
32
- CS[ellipsoidal,2],
33
- AXIS["geodetic latitude (Lat)",north,
34
- ORDER[1],
35
- ANGLEUNIT["degree",0.0174532925199433]],
36
- AXIS["geodetic longitude (Lon)",east,
37
- ORDER[2],
38
- ANGLEUNIT["degree",0.0174532925199433]],
39
- USAGE[
40
- SCOPE["unknown"],
41
- AREA["World"],
42
- BBOX[-90,-180,90,180]],
43
- ID["EPSG",4326]]
44
- EOS
45
-
46
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
47
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
48
- end
49
-
50
- def test_create_from_wkt_2
51
- wkt = <<~EOS
52
- GEOGCRS["WGS 84",
53
- DATUM["World Geodetic System 1984",
54
- ELLIPSOID["WGS 84",6378137,298.257223563,
55
- LENGTHUNIT["metre",1]]],
56
- PRIMEM["Greenwich",0,
57
- ANGLEUNIT["degree",0.0174532925199433]],
58
- CS[ellipsoidal,2],
59
- AXIS["geodetic latitude (Lat)",north,
60
- ORDER[1],
61
- ANGLEUNIT["degree",0.0174532925199433]],
62
- AXIS["geodetic longitude (Lon)",east,
63
- ORDER[2],
64
- ANGLEUNIT["degree",0.0174532925199433]],
65
- USAGE[
66
- SCOPE["unknown"],
67
- AREA["World"],
68
- BBOX[-90,-180,90,180]],
69
- ID["EPSG",4326]]
70
- EOS
71
-
72
- crs = Proj::Crs.create_from_wkt(wkt)
73
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
74
- assert_equal(wkt.strip, crs.to_wkt)
75
- end
76
-
77
- def test_create_from_wkt_warning
78
- wkt = <<~EOS
79
- PROJCS["test",
80
- GEOGCS["WGS 84",
81
- DATUM["WGS_1984",
82
- SPHEROID["WGS 84",6378137,298.257223563]],
83
- PRIMEM["Greenwich",0],
84
- UNIT["degree",0.0174532925199433]],
85
- PROJECTION["Transverse_Mercator"],
86
- PARAMETER["latitude_of_origi",31],
87
- UNIT["metre",1]]"
88
- EOS
89
- wkt.strip!
90
-
91
- crs = nil
92
- _, err = capture_io do
93
- crs = Proj::Crs.create_from_wkt(wkt)
94
- end
95
-
96
- expected = "Cannot find expected parameter Latitude of natural origin. Cannot find expected parameter Longitude of natural origin. Cannot find expected parameter False easting. Cannot find expected parameter False northing. Parameter latitude_of_origi found but not expected for this method. The WKT string lacks a value for Scale factor at natural origin. Default it to 1."
97
- assert_equal(expected, err.strip)
98
-
99
- assert_equal(:PJ_TYPE_PROJECTED_CRS, crs.proj_type)
100
- end
101
-
102
- def test_create_from_wkt_error
103
- wkt = <<~EOS
104
- GEOGCS[test,
105
- DATUM[test,
106
- SPHEROID[test,0,298.257223563,unused]],
107
- PRIMEM[Greenwich,0],
108
- UNIT[degree,0.0174532925199433]]
109
- EOS
110
- wkt.strip!
111
-
112
- error = assert_raises(RuntimeError) do
113
- Proj::Crs.create_from_wkt(wkt)
114
- end
115
-
116
- expected = <<~EOS
117
- Parsing error : syntax error, unexpected identifier, expecting string. Error occurred around:
118
- GEOGCS[test,
119
- ^
120
- EOS
121
-
122
- assert_equal(expected.strip, error.to_s)
123
- end
124
-
125
- def test_create_from_proj4
126
- crs = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
127
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
128
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
129
- end
130
-
131
- def test_create_from_database
132
- crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
133
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
134
- assert_equal("4326", crs.id_code)
135
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
136
- end
137
-
138
- def test_compound
139
- crs = Proj::Crs.new('EPSG:2393+5717')
140
- assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
141
- assert_equal('+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +units=m +vunits=m +no_defs +type=crs', crs.to_proj_string)
142
-
143
- crs = Proj::Crs.new('urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717')
144
- assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
145
- assert_equal('+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +units=m +vunits=m +no_defs +type=crs', crs.to_proj_string)
146
- end
147
-
148
- def test_not_crs
149
- error = assert_raises(Proj::Error) do
150
- Proj::Crs.new('+proj=utm +zone=32 +datum=WGS84')
151
- end
152
- assert_equal('Invalid crs definition. Proj created an instance of: PJ_TYPE_OTHER_COORDINATE_OPERATION.', error.message)
153
- end
154
-
155
- def test_finalize
156
- 100.times do
157
- crs = Proj::Crs.new('EPSG:4326')
158
- assert(crs.to_ptr)
159
- GC.start
160
- end
161
- assert(true)
162
- end
163
-
164
- def test_geodetic_crs
165
- crs = Proj::Crs.new('EPSG:4326')
166
- geodetic = crs.geodetic_crs
167
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, geodetic.proj_type)
168
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', geodetic.to_proj_string)
169
- end
170
-
171
- def test_datum
172
- wkt = <<~EOS
173
- PROJCS["WGS 84 / UTM zone 31N",
174
- GEOGCS["WGS 84",
175
- DATUM["WGS_1984",
176
- SPHEROID["WGS 84",6378137,298.257223563,
177
- AUTHORITY["EPSG","7030"]],
178
- AUTHORITY["EPSG","6326"]],
179
- PRIMEM["Greenwich",0,
180
- AUTHORITY["EPSG","8901"]],
181
- UNIT["degree",0.0174532925199433,
182
- AUTHORITY["EPSG","9122"]],
183
- AUTHORITY["EPSG","4326"]],
184
- PROJECTION["Transverse_Mercator"],
185
- PARAMETER["latitude_of_origin",0],
186
- PARAMETER["central_meridian",3],
187
- PARAMETER["scale_factor",0.9996],
188
- PARAMETER["false_easting",500000],
189
- PARAMETER["false_northing",0],
190
- UNIT["metre",1,
191
- AUTHORITY["EPSG","9001"]],
192
- AXIS["Easting",EAST],
193
- AXIS["Northing",NORTH],
194
- AUTHORITY["EPSG","32631"]]
195
- EOS
196
-
197
- crs = Proj::Crs.create_from_wkt(wkt)
198
- datum = crs.datum
199
- assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, datum.proj_type)
200
- end
201
-
202
- def test_datum_forced
203
- wkt = <<~EOS
204
- GEOGCRS["ETRS89",
205
- ENSEMBLE["European Terrestrial Reference System 1989 ensemble",
206
- MEMBER["European Terrestrial Reference Frame 1989"],
207
- MEMBER["European Terrestrial Reference Frame 1990"],
208
- MEMBER["European Terrestrial Reference Frame 1991"],
209
- MEMBER["European Terrestrial Reference Frame 1992"],
210
- MEMBER["European Terrestrial Reference Frame 1993"],
211
- MEMBER["European Terrestrial Reference Frame 1994"],
212
- MEMBER["European Terrestrial Reference Frame 1996"],
213
- MEMBER["European Terrestrial Reference Frame 1997"],
214
- MEMBER["European Terrestrial Reference Frame 2000"],
215
- MEMBER["European Terrestrial Reference Frame 2005"],
216
- MEMBER["European Terrestrial Reference Frame 2014"],
217
- ELLIPSOID["GRS 1980",6378137,298.257222101,
218
- LENGTHUNIT["metre",1]],
219
- ENSEMBLEACCURACY[0.1]],
220
- PRIMEM["Greenwich",0,
221
- ANGLEUNIT["degree",0.0174532925199433]],
222
- CS[ellipsoidal,2],
223
- AXIS["geodetic latitude (Lat)",north,
224
- ORDER[1],
225
- ANGLEUNIT["degree",0.0174532925199433]],
226
- AXIS["geodetic longitude (Lon)",east,
227
- ORDER[2],
228
- ANGLEUNIT["degree",0.0174532925199433]]]
229
- EOS
230
-
231
- crs = Proj::Crs.create(wkt)
232
- datum = crs.datum_forced
233
- assert_equal("European Terrestrial Reference System 1989", datum.name)
234
- end
235
-
236
- def test_horizontal_datum
237
- crs = Proj::Crs.new('EPSG:4326')
238
- datum = crs.horizontal_datum
239
- assert_equal(:PJ_TYPE_DATUM_ENSEMBLE, datum.proj_type)
240
- assert_equal("World Geodetic System 1984 ensemble", datum.name)
241
- end
242
-
243
- def test_coordinate_system
244
- crs = Proj::Crs.new('EPSG:4326')
245
- assert(crs.coordinate_system)
246
- end
247
-
248
- def test_ellipsoid
249
- crs = Proj::Crs.new('EPSG:4326')
250
- ellipsoid = crs.ellipsoid
251
- assert_instance_of(Proj::Ellipsoid, ellipsoid)
252
- assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
253
- end
254
-
255
- def test_prime_meridian
256
- crs = Proj::Crs.new('EPSG:4326')
257
- prime_meridian = crs.prime_meridian
258
- assert_instance_of(Proj::PrimeMeridian, prime_meridian)
259
- assert_equal('Greenwich', prime_meridian.name)
260
- end
261
-
262
- def test_coordinate_operation
263
- crs = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
264
-
265
- conversion_1 = crs.coordinate_operation
266
- assert_equal("UTM zone 31N", conversion_1.name)
267
- end
268
-
269
- def test_area_of_use
270
- crs = Proj::Crs.new('EPSG:4326')
271
- assert_kind_of(Proj::Area, crs.area_of_use)
272
- assert_equal('World.', crs.area_of_use.name)
273
- assert_in_delta(-180.0, crs.area_of_use.west_lon_degree, 0.1)
274
- assert_in_delta(-90.0, crs.area_of_use.south_lat_degree, 0.1)
275
- assert_in_delta(180.0, crs.area_of_use.east_lon_degree, 0.1)
276
- assert_in_delta(90.0, crs.area_of_use.north_lat_degree, 0.1)
277
- end
278
-
279
- def test_derived
280
- crs = Proj::Crs.new('EPSG:4326')
281
- refute(crs.derived?)
282
- end
283
-
284
- def test_non_deprecated
285
- crs = Proj::Crs.new('EPSG:4226')
286
- objects = crs.non_deprecated
287
- assert_equal(2, objects.count)
288
-
289
- object = objects[0]
290
- assert_equal("#<Proj::Crs - Locodjo 1965, PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
291
-
292
- object = objects[1]
293
- assert_equal("#<Proj::Crs - Abidjan 1987, PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
294
- end
295
-
296
- def test_identify
297
- crs = Proj::Crs.new('OGC:CRS84')
298
- objects, confidences = crs.identify('OGC')
299
-
300
- assert_equal(1, objects.count)
301
- object = objects[0]
302
- assert_equal("#<Proj::Crs - WGS 84 (CRS84), PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
303
-
304
- assert_equal(1, confidences.count)
305
- confidence = confidences[0]
306
- assert_equal(100, confidence)
307
- end
308
-
309
- def test_lp_distance
310
- wkt = <<~EOS
311
- GEODCRS["WGS 84",
312
- DATUM["World Geodetic System 1984",
313
- ELLIPSOID["WGS 84",6378137,298.257223563,
314
- LENGTHUNIT["metre",1]]],
315
- PRIMEM["Greenwich",0,
316
- ANGLEUNIT["degree",0.0174532925199433]],
317
- CS[ellipsoidal,2],
318
- AXIS["latitude",north,
319
- ORDER[1],
320
- ANGLEUNIT["degree",0.0174532925199433]],
321
- AXIS["longitude",east,
322
- ORDER[2],
323
- ANGLEUNIT["degree",0.0174532925199433]],
324
- ID["EPSG",4326]]
325
- EOS
326
-
327
- crs = Proj::Crs.new(wkt)
328
- coord1 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
329
- y: Proj.degrees_to_radians(49),
330
- z: 0, t:0)
331
- coord2 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
332
- y: Proj.degrees_to_radians(50),
333
- z: 0, t:0)
334
-
335
- distance = crs.lp_distance(coord1, coord2)
336
- assert_in_delta(111219.409, distance, 1e-3)
337
- end
338
-
339
- def test_geod_distance
340
- wkt = <<~EOS
341
- GEODCRS["WGS 84",
342
- DATUM["World Geodetic System 1984",
343
- ELLIPSOID["WGS 84",6378137,298.257223563,
344
- LENGTHUNIT["metre",1]]],
345
- PRIMEM["Greenwich",0,
346
- ANGLEUNIT["degree",0.0174532925199433]],
347
- CS[ellipsoidal,2],
348
- AXIS["latitude",north,
349
- ORDER[1],
350
- ANGLEUNIT["degree",0.0174532925199433]],
351
- AXIS["longitude",east,
352
- ORDER[2],
353
- ANGLEUNIT["degree",0.0174532925199433]],
354
- ID["EPSG",4326]]
355
- EOS
356
-
357
- crs = Proj::Crs.new(wkt)
358
- coord1 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
359
- y: Proj.degrees_to_radians(49),
360
- z: 0, t:0)
361
- coord2 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
362
- y: Proj.degrees_to_radians(50),
363
- z: 0, t:0)
364
-
365
- coord3 = crs.geod_distance(coord1, coord2)
366
- assert_in_delta(111219.409, coord3.x, 1e-3)
367
- end
368
-
369
- def test_source_crs
370
- wkt = <<~EOS
371
- PROJCRS["WGS 84 / UTM zone 31N",
372
- BASEGEODCRS["WGS 84",
373
- DATUM["World Geodetic System 1984",
374
- ELLIPSOID["WGS 84",6378137,298.257223563,
375
- LENGTHUNIT["metre",1]]],
376
- PRIMEM["Greenwich",0,
377
- ANGLEUNIT["degree",0.0174532925199433]]],
378
- CONVERSION["UTM zone 31N",
379
- METHOD["Transverse Mercator",
380
- ID["EPSG",9807]],
381
- PARAMETER["Latitude of natural origin",0,
382
- ANGLEUNIT["degree",0.0174532925199433],
383
- ID["EPSG",8801]],
384
- PARAMETER["Longitude of natural origin",3,
385
- ANGLEUNIT["degree",0.0174532925199433],
386
- ID["EPSG",8802]],
387
- PARAMETER["Scale factor at natural origin",0.9996,
388
- SCALEUNIT["unity",1],
389
- ID["EPSG",8805]],
390
- PARAMETER["False easting",500000,
391
- LENGTHUNIT["metre",1],
392
- ID["EPSG",8806]],
393
- PARAMETER["False northing",0,
394
- LENGTHUNIT["metre",1],
395
- ID["EPSG",8807]]],
396
- CS[Cartesian,2],
397
- AXIS["(E)",east,
398
- ORDER[1],
399
- LENGTHUNIT["metre",1]],
400
- AXIS["(N)",north,
401
- ORDER[2],
402
- LENGTHUNIT["metre",1]],
403
- ID["EPSG",32631]]
404
- EOS
405
-
406
- crs = Proj::Crs.new(wkt)
407
- source_crs = crs.source_crs
408
- assert_equal("WGS 84", source_crs.name)
409
- end
410
-
411
- def test_target_crs
412
- wkt = <<~EOS
413
- BOUNDCRS[
414
- SOURCECRS[
415
- GEODCRS["NTF (Paris)",
416
- DATUM["Nouvelle Triangulation Francaise (Paris)",
417
- ELLIPSOID["Clarke 1880 (IGN)",6378249.2,293.466021293627,
418
- LENGTHUNIT["metre",1]]],
419
- PRIMEM["Paris",2.5969213,
420
- ANGLEUNIT["grad",0.015707963267949]],
421
- CS[ellipsoidal,2],
422
- AXIS["latitude",north,
423
- ORDER[1],
424
- ANGLEUNIT["grad",0.015707963267949]],
425
- AXIS["longitude",east,
426
- ORDER[2],
427
- ANGLEUNIT["grad",0.015707963267949]],
428
- ID["EPSG",4807]]],
429
- TARGETCRS[
430
- GEODCRS["WGS 84",
431
- DATUM["World Geodetic System 1984",
432
- ELLIPSOID["WGS 84",6378137,298.257223563,
433
- LENGTHUNIT["metre",1]]],
434
- PRIMEM["Greenwich",0,
435
- ANGLEUNIT["degree",0.0174532925199433]],
436
- CS[ellipsoidal,2],
437
- AXIS["latitude",north,
438
- ORDER[1],
439
- ANGLEUNIT["degree",0.0174532925199433]],
440
- AXIS["longitude",east,
441
- ORDER[2],
442
- ANGLEUNIT["degree",0.0174532925199433]],
443
- ID["EPSG",4326]]],
444
- ABRIDGEDTRANSFORMATION["",
445
- METHOD[""],
446
- PARAMETER["foo",1]]]
447
- EOS
448
-
449
- crs = Proj::Crs.new(wkt)
450
- target_crs = crs.target_crs
451
- assert_equal("WGS 84", target_crs.name)
452
- end
453
-
454
- def test_to_proj_string
455
- crs = Proj::Crs.new('EPSG:26915')
456
- assert_equal('+proj=utm +zone=15 +datum=NAD83 +units=m +no_defs +type=crs', crs.to_proj_string)
457
- end
458
-
459
- def test_to_wkt
460
- crs = Proj::Crs.new('EPSG:26915')
461
-
462
- expected = <<~EOS
463
- PROJCRS["NAD83 / UTM zone 15N",
464
- BASEGEOGCRS["NAD83",
465
- DATUM["North American Datum 1983",
466
- ELLIPSOID["GRS 1980",6378137,298.257222101,
467
- LENGTHUNIT["metre",1]]],
468
- PRIMEM["Greenwich",0,
469
- ANGLEUNIT["degree",0.0174532925199433]],
470
- ID["EPSG",4269]],
471
- CONVERSION["UTM zone 15N",
472
- METHOD["Transverse Mercator",
473
- ID["EPSG",9807]],
474
- PARAMETER["Latitude of natural origin",0,
475
- ANGLEUNIT["degree",0.0174532925199433],
476
- ID["EPSG",8801]],
477
- PARAMETER["Longitude of natural origin",-93,
478
- ANGLEUNIT["degree",0.0174532925199433],
479
- ID["EPSG",8802]],
480
- PARAMETER["Scale factor at natural origin",0.9996,
481
- SCALEUNIT["unity",1],
482
- ID["EPSG",8805]],
483
- PARAMETER["False easting",500000,
484
- LENGTHUNIT["metre",1],
485
- ID["EPSG",8806]],
486
- PARAMETER["False northing",0,
487
- LENGTHUNIT["metre",1],
488
- ID["EPSG",8807]]],
489
- CS[Cartesian,2],
490
- AXIS["(E)",east,
491
- ORDER[1],
492
- LENGTHUNIT["metre",1]],
493
- AXIS["(N)",north,
494
- ORDER[2],
495
- LENGTHUNIT["metre",1]],
496
- USAGE[
497
- SCOPE["Engineering survey, topographic mapping."],
498
- AREA["North America - between 96\xC2\xB0W and 90\xC2\xB0W - onshore and offshore. Canada - Manitoba; Nunavut; Ontario. United States (USA) - Arkansas; Illinois; Iowa; Kansas; Louisiana; Michigan; Minnesota; Mississippi; Missouri; Nebraska; Oklahoma; Tennessee; Texas; Wisconsin."],
499
- BBOX[25.61,-96,84,-90]],
500
- ID["EPSG",26915]]
501
- EOS
502
-
503
- assert_equal(expected.strip, crs.to_wkt)
504
- end
505
-
506
- def test_to_json
507
- crs = Proj::Crs.new('EPSG:26915')
508
- expected = <<~EOS
509
- {
510
- "$schema": "https://proj.org/schemas/#{proj9? ? 'v0.5' : 'v0.4'}/projjson.schema.json",
511
- "type": "ProjectedCRS",
512
- "name": "NAD83 / UTM zone 15N",
513
- "base_crs": {
514
- "name": "NAD83",
515
- "datum": {
516
- "type": "GeodeticReferenceFrame",
517
- "name": "North American Datum 1983",
518
- "ellipsoid": {
519
- "name": "GRS 1980",
520
- "semi_major_axis": 6378137,
521
- "inverse_flattening": 298.257222101
522
- }
523
- },
524
- "coordinate_system": {
525
- "subtype": "ellipsoidal",
526
- "axis": [
527
- {
528
- "name": "Geodetic latitude",
529
- "abbreviation": "Lat",
530
- "direction": "north",
531
- "unit": "degree"
532
- },
533
- {
534
- "name": "Geodetic longitude",
535
- "abbreviation": "Lon",
536
- "direction": "east",
537
- "unit": "degree"
538
- }
539
- ]
540
- },
541
- "id": {
542
- "authority": "EPSG",
543
- "code": 4269
544
- }
545
- },
546
- "conversion": {
547
- "name": "UTM zone 15N",
548
- "method": {
549
- "name": "Transverse Mercator",
550
- "id": {
551
- "authority": "EPSG",
552
- "code": 9807
553
- }
554
- },
555
- "parameters": [
556
- {
557
- "name": "Latitude of natural origin",
558
- "value": 0,
559
- "unit": "degree",
560
- "id": {
561
- "authority": "EPSG",
562
- "code": 8801
563
- }
564
- },
565
- {
566
- "name": "Longitude of natural origin",
567
- "value": -93,
568
- "unit": "degree",
569
- "id": {
570
- "authority": "EPSG",
571
- "code": 8802
572
- }
573
- },
574
- {
575
- "name": "Scale factor at natural origin",
576
- "value": 0.9996,
577
- "unit": "unity",
578
- "id": {
579
- "authority": "EPSG",
580
- "code": 8805
581
- }
582
- },
583
- {
584
- "name": "False easting",
585
- "value": 500000,
586
- "unit": "metre",
587
- "id": {
588
- "authority": "EPSG",
589
- "code": 8806
590
- }
591
- },
592
- {
593
- "name": "False northing",
594
- "value": 0,
595
- "unit": "metre",
596
- "id": {
597
- "authority": "EPSG",
598
- "code": 8807
599
- }
600
- }
601
- ]
602
- },
603
- "coordinate_system": {
604
- "subtype": "Cartesian",
605
- "axis": [
606
- {
607
- "name": "Easting",
608
- "abbreviation": "E",
609
- "direction": "east",
610
- "unit": "metre"
611
- },
612
- {
613
- "name": "Northing",
614
- "abbreviation": "N",
615
- "direction": "north",
616
- "unit": "metre"
617
- }
618
- ]
619
- },
620
- "scope": "Engineering survey, topographic mapping.",
621
- "area": "North America - between 96\xC2\xB0W and 90\xC2\xB0W - onshore and offshore. Canada - Manitoba; Nunavut; Ontario. United States (USA) - Arkansas; Illinois; Iowa; Kansas; Louisiana; Michigan; Minnesota; Mississippi; Missouri; Nebraska; Oklahoma; Tennessee; Texas; Wisconsin.",
622
- "bbox": {
623
- "south_latitude": 25.61,
624
- "west_longitude": -96,
625
- "north_latitude": 84,
626
- "east_longitude": -90
627
- },
628
- "id": {
629
- "authority": "EPSG",
630
- "code": 26915
631
- }
632
- }
633
- EOS
634
-
635
- assert_equal(expected.strip, crs.to_json)
636
- end
637
-
638
- def test_to_wgs84
639
- wkt = <<~EOS
640
- BOUNDCRS[
641
- SOURCECRS[
642
- GEOGCRS["NTF (Paris)",
643
- DATUM["Nouvelle Triangulation Francaise (Paris)",
644
- ELLIPSOID["Clarke 1880 (IGN)",6378249.2,293.466021293627,
645
- LENGTHUNIT["metre",1]]],
646
- PRIMEM["Paris",2.5969213,
647
- ANGLEUNIT["grad",0.0157079632679489]],
648
- CS[ellipsoidal,2],
649
- AXIS["geodetic latitude (Lat)",north,
650
- ORDER[1],
651
- ANGLEUNIT["grad",0.0157079632679489]],
652
- AXIS["geodetic longitude (Lon)",east,
653
- ORDER[2],
654
- ANGLEUNIT["grad",0.0157079632679489]],
655
- USAGE[
656
- SCOPE["Geodesy."],
657
- AREA["France - onshore - mainland and Corsica."],
658
- BBOX[41.31,-4.87,51.14,9.63]],
659
- ID["EPSG",4807]]],
660
- TARGETCRS[
661
- GEOGCRS["WGS 84",
662
- DATUM["World Geodetic System 1984",
663
- ELLIPSOID["WGS 84",6378137,298.257223563,
664
- LENGTHUNIT["metre",1]]],
665
- PRIMEM["Greenwich",0,
666
- ANGLEUNIT["degree",0.0174532925199433]],
667
- CS[ellipsoidal,2],
668
- AXIS["latitude",north,
669
- ORDER[1],
670
- ANGLEUNIT["degree",0.0174532925199433]],
671
- AXIS["longitude",east,
672
- ORDER[2],
673
- ANGLEUNIT["degree",0.0174532925199433]],
674
- ID["EPSG",4326]]],
675
- ABRIDGEDTRANSFORMATION["NTF to WGS 84 (1)",
676
- VERSION["IGN-Fra"],
677
- METHOD["Geocentric translations (geog2D domain)",
678
- ID["EPSG",9603]],
679
- PARAMETER["X-axis translation",-168,
680
- ID["EPSG",8605]],
681
- PARAMETER["Y-axis translation",-60,
682
- ID["EPSG",8606]],
683
- PARAMETER["Z-axis translation",320,
684
- ID["EPSG",8607]],
685
- USAGE[
686
- SCOPE["(null/copy) Approximation for medium and low accuracy applications assuming equality between plate-fixed static and earth-fixed dynamic CRSs, ignoring static/dynamic CRS differences."],
687
- AREA["France - onshore - mainland and Corsica."],
688
- BBOX[41.31,-4.87,51.14,9.63]],
689
- ID["EPSG",1193],
690
- REMARK["These same parameter values are used to transform to ETRS89. See NTF to ETRS89 (1) (code 1651)."]]]
691
- EOS
692
-
693
- crs = Proj::Crs.new(wkt)
694
- operation = crs.coordinate_operation
695
- values = operation.to_wgs84
696
-
697
- expected = [-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0]
698
- assert_equal(expected, values)
699
- end
700
-
701
- def test_geographic
702
- context = Proj::Context.new
703
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
704
-
705
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
706
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
707
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
708
- coordinate_system: coordinate_system)
709
-
710
- crs_2 = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
711
- assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
712
- end
713
-
714
- def test_geographic_datum
715
- context = Proj::Context.new
716
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
717
- datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
718
- crs = Proj::Crs.create_geographic_from_datum(context, name: "WGS 84", datum: datum, coordinate_system: coordinate_system)
719
- end
720
-
721
- def test_geocentric
722
- context = Proj::Context.new
723
- crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
724
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
725
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
726
- angular_units: "Degree", angular_units_conv: 0.0174532925199433,
727
- linear_units: "Metre", linear_units_conv: 1.0)
728
-
729
- crs_2 = Proj::Crs.create_from_database("EPSG", "4978", :PJ_CATEGORY_CRS)
730
- assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
731
- end
732
-
733
- def test_geocentric_datum
734
- context = Proj::Context.new
735
- crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
736
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
737
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
738
- angular_units: "Degree", angular_units_conv: 0.0174532925199433,
739
- linear_units: "Metre", linear_units_conv: 1.0)
740
- datum = crs.datum
741
-
742
- geocentric_crs = Proj::Crs.create_geocentric_from_datum(context, name: "WGS 84", datum: datum,
743
- linear_units: "Metre", linear_units_conv: 1.0)
744
-
745
- assert(crs.equivalent_to?(geocentric_crs, :PJ_COMP_STRICT))
746
- end
747
-
748
- def test_vertical_crs_ex
749
- context = Proj::Context.new
750
-
751
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS (ftUS)",
752
- datum_name: "myVertDatum",
753
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
754
- geoid_model_name: "PROJ @foo.gtx",
755
- accuracy: 123)
756
- assert(vertical_crs)
757
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
758
- end
759
-
760
- def test_vertical_crs_ex_with_geog_crs
761
- context = Proj::Context.new
762
- # NAD83(2011) / UTM zone 11N
763
- horizontal_crs = Proj::Crs.create_from_database("EPSG", "6340", :PJ_CATEGORY_CRS)
764
-
765
- # WGS84
766
- wgs84 = Proj::Crs.new("EPSG:4979", context)
767
-
768
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
769
- datum_name: "myVertDatum",
770
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
771
- geoid_model_name: "PROJ @foo.gtx",
772
- geoid_geog_crs: wgs84)
773
- assert(vertical_crs)
774
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
775
- end
776
-
777
- def test_bound_vertical
778
- context = Proj::Context.new
779
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
780
- datum_name: "myVertDatum")
781
-
782
- crs_4979 = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
783
- bound = Proj::Crs.create_bound_vertical(context, vertical_crs: vertical_crs,
784
- hub_crs: crs_4979, grid_name: "foo.gtx")
785
-
786
- assert_equal(:PJ_TYPE_BOUND_CRS, bound.proj_type)
787
- assert_equal("myVertCRS", bound.name)
788
- end
789
-
790
- def test_compound
791
- context = Proj::Context.new
792
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
793
-
794
- horizontal_crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
795
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
796
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
797
- coordinate_system: coordinate_system)
798
-
799
- vertical_crs = Proj::Crs.create_vertical(context, name: "myVertCRS",
800
- datum_name: "myVertDatum",
801
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219)
802
-
803
- assert(vertical_crs)
804
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
805
- assert_equal("myVertCRS", vertical_crs.name)
806
-
807
- compound_crs = Proj::Crs.create_compound(context, name: "myCompoundCRS",
808
- horizontal_crs: horizontal_crs, vertical_crs: vertical_crs);
809
- assert(compound_crs)
810
- assert_equal(:PJ_TYPE_COMPOUND_CRS, compound_crs.proj_type)
811
- assert_equal("myCompoundCRS", compound_crs.name)
812
-
813
- crs = compound_crs.sub_crs(0)
814
- assert(crs.equivalent_to?(horizontal_crs, :PJ_COMP_STRICT))
815
-
816
- crs = compound_crs.sub_crs(1)
817
- assert(crs.equivalent_to?(vertical_crs, :PJ_COMP_STRICT))
818
- end
819
-
820
- def test_derived_geographic
821
- context = Proj::Context.new
822
- crs = Proj::Crs.create("EPSG:4326", context)
823
-
824
- conversion = Proj::Projection.pole_rotation_grib_convention(context, south_pole_lat_in_unrotated_crs: 2, south_pole_long_in_unrotated_crs: 3,
825
- axis_rotation: 4, ang_unit_name: "Degree", ang_unit_conv_factor: 0.0174532925199433)
826
-
827
- coordinate_system = crs.coordinate_system
828
-
829
- # Wrong type of base_geographic_crs
830
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
831
- base_geographic_crs: conversion, conversion: conversion,
832
- coordinate_system: coordinate_system)
833
- refute(derived_crs)
834
-
835
- # Wrong type of conversion
836
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
837
- base_geographic_crs: crs, conversion: crs,
838
- coordinate_system: coordinate_system)
839
- refute(derived_crs)
840
-
841
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
842
- base_geographic_crs: crs, conversion: conversion,
843
- coordinate_system: coordinate_system)
844
- refute(crs.derived?)
845
- assert(derived_crs.derived?)
846
-
847
- expected = "+proj=ob_tran +o_proj=longlat +o_lon_p=-4 +o_lat_p=-2 +lon_0=3 +datum=WGS84 +no_defs +type=crs"
848
- assert_equal(expected, derived_crs.to_proj_string)
849
- end
850
-
851
- def test_projected
852
- context = Proj::Context.new
853
- param = Proj::Parameter.new(name: "param name", value: 0.99,
854
- unit_conv_factor: 1.0, unit_type: :PJ_UT_SCALE)
855
-
856
- conversion = Proj::Conversion.create_conversion(context, name: "conv",
857
- auth_name: "conv auth", code: "conv code",
858
- method_name: "method", method_auth_name: "method auth", method_code: "method code",
859
- params: [param])
860
-
861
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
862
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984",
863
- ellipsoid_name: "WGS 84", semi_major_meter: 6378137, inv_flattening: 298.257223563,
864
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
865
- pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
866
- coordinate_system: coordinate_system)
867
-
868
- cartesian = Proj::CoordinateSystem.create_cartesian_2d(context, :PJ_CART2D_EASTING_NORTHING)
869
-
870
- projected = Proj::Crs.create_projected(context, name: "My Projected CRS", geodetic_crs: crs,
871
- conversion: conversion, coordinate_system: cartesian)
872
- assert_equal(:PJ_TYPE_PROJECTED_CRS, projected.proj_type)
873
- assert_equal("My Projected CRS", projected.name)
874
- end
875
-
876
- def test_create_bound_crs_to_wgs84
877
- context = Proj::Context.new
878
- crs = Proj::Crs.create_from_database("EPSG", "4807", :PJ_CATEGORY_CRS)
879
-
880
- bounded = Proj::Crs.create_bound_to_wgs84(context, crs: crs)
881
- expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
882
- assert_equal(expected, bounded.to_proj_string)
883
-
884
- base_crs = bounded.source_crs
885
- assert(base_crs.equivalent_to?(crs, :PJ_COMP_EQUIVALENT))
886
-
887
- hub_crs = bounded.target_crs
888
- wgs84_crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
889
- assert(hub_crs.equivalent_to?(wgs84_crs, :PJ_COMP_EQUIVALENT))
890
-
891
- transform = bounded.coordinate_operation
892
- values = transform.to_wgs84(true)
893
- expected = [-168, -60, 320, 0, 0, 0, 0]
894
- assert_equal(expected, values)
895
-
896
- bounded_2 = Proj::Crs.create_bound(context, base_crs: base_crs, hub_crs: hub_crs, transformation: transform)
897
- assert_equal(:PJ_TYPE_BOUND_CRS, bounded_2.proj_type)
898
- expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
899
- assert_equal(expected, bounded_2.to_proj_string)
900
- end
901
-
902
- def test_create_engineering
903
- context = Proj::Context.new
904
- crs = Proj::Crs.create_engineering("EPSG", name: "4807")
905
- assert_equal("4807", crs.name)
906
- assert_equal(:PJ_TYPE_ENGINEERING_CRS, crs.proj_type)
907
-
908
- expected = <<~EOS
909
- LOCAL_CS["name",
910
- UNIT["metre",1,
911
- AUTHORITY["EPSG","9001"]],
912
- AXIS["Easting",EAST],
913
- AXIS["Northing",NORTH]]
914
- EOS
915
-
916
- # This crashes proj
917
- #assert_equal(expected, crs.to_wkt(:PJ_WKT1_GDAL))
918
- end
919
-
920
- def test_query_geodetic_from_datum
921
- context = Proj::Context.new
922
- crses = Proj::Crs.query_geodetic_from_datum(context, datum_auth_name: "EPSG", datum_code: "6326")
923
-
924
- expected = case
925
- when proj9?
926
- 12
927
- else
928
- 11
929
- end
930
-
931
- assert_equal(expected, crses.size)
932
-
933
- crses = Proj::Crs.query_geodetic_from_datum(context, auth_name: "EPSG",
934
- datum_auth_name: "EPSG", datum_code: "6326",
935
- crs_type: "geographic 2D")
936
- assert_equal(1, crses.size)
937
- end
938
-
939
- def test_alter_name
940
- context = Proj::Context.new
941
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
942
-
943
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
944
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
945
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
946
- coordinate_system: coordinate_system)
947
- assert_equal("WGS 84", crs.name)
948
-
949
- altered = crs.alter_name("new name")
950
- assert_equal("WGS 84", crs.name)
951
- assert_equal("new name", altered.name)
952
- end
953
-
954
- def test_alter_id
955
- context = Proj::Context.new
956
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
957
-
958
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
959
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
960
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
961
- coordinate_system: coordinate_system)
962
- refute(crs.auth)
963
-
964
- altered = crs.alter_id("auth", "code")
965
- refute(crs.auth)
966
- assert_equal("auth:code", altered.auth)
967
- end
968
-
969
- def test_alter_geodetic_crs
970
- context = Proj::Context.new
971
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
972
- geod_crs = projected.geodetic_crs
973
- new_geod_crs = Proj::Crs.new("+proj=longlat +type=crs", context)
974
-
975
- altered = geod_crs.alter_geodetic_crs(new_geod_crs)
976
- assert(altered.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
977
-
978
- altered = projected.alter_geodetic_crs(new_geod_crs)
979
- assert_equal(:PJ_TYPE_PROJECTED_CRS, altered.proj_type)
980
- assert(altered.geodetic_crs.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
981
- end
982
-
983
- def test_alter_cs_angular_unit
984
- context = Proj::Context.new
985
- crs = Proj::Crs.new('EPSG:4326')
986
- altered = crs.alter_cs_angular_unit(angular_units: "my unit", angular_units_conv: 2,
987
- unit_auth_name: "my auth", unit_code: "my code")
988
-
989
- cs = altered.coordinate_system
990
- assert_equal(2, cs.axis_count)
991
-
992
- axis = cs.axis_info(0)
993
- assert_equal("my unit", axis.unit_name)
994
- assert_equal(2, axis.unit_conv_factor)
995
- assert_equal("my auth", axis.unit_auth_name)
996
- assert_equal("my code", axis.unit_code)
997
- end
998
-
999
- def test_alter_alter_cs_linear_unit
1000
- context = Proj::Context.new
1001
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1002
- altered = projected.alter_cs_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1003
- unit_auth_name: "my auth", unit_code: "my code")
1004
-
1005
- cs = altered.coordinate_system
1006
- assert_equal(2, cs.axis_count)
1007
-
1008
- axis = cs.axis_info(0)
1009
- assert_equal("my unit", axis.unit_name)
1010
- assert_equal(2, axis.unit_conv_factor)
1011
- assert_equal("my auth", axis.unit_auth_name)
1012
- assert_equal("my code", axis.unit_code)
1013
- end
1014
-
1015
- def test_alter_parameters_linear_unit
1016
- context = Proj::Context.new
1017
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1018
- altered = projected.alter_parameters_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1019
- convert_to_new_unit: false)
1020
-
1021
- wkt = altered.to_wkt
1022
- assert_match(/500000/, wkt)
1023
- assert_match(/"my unit",2/, wkt)
1024
- end
1025
-
1026
- def test_promote_to_3d
1027
- context = Proj::Context.new
1028
- crs = Proj::Crs.new('EPSG:4326')
1029
-
1030
- crs_3d = crs.promote_to_3d
1031
- assert_equal("4979", crs_3d.id_code)
1032
-
1033
- cs = crs_3d.coordinate_system
1034
- assert_equal(3, cs.axis_count)
1035
- end
1036
-
1037
- def test_demote_to_3d
1038
- context = Proj::Context.new
1039
- crs = Proj::Crs.new('EPSG:4979')
1040
-
1041
- crs_2d = crs.demote_to_2d
1042
- assert_equal("4326", crs_2d.id_code)
1043
-
1044
- cs = crs_2d.coordinate_system
1045
- assert_equal(2, cs.axis_count)
1046
- end
1047
-
1048
- def test_projected_3d_with_base
1049
- context = Proj::Context.new
1050
- projected = Proj::Crs.new('EPSG:32631')
1051
- base_crs_3d = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
1052
-
1053
- crs_3d = projected.projected_3d(geog_3d_crs: base_crs_3d)
1054
- assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1055
- assert_equal(crs_3d.name, projected.name)
1056
-
1057
- cs = crs_3d.coordinate_system
1058
- assert_equal(3, cs.axis_count)
1059
- end
1060
-
1061
- def test_projected_3d_without_base
1062
- context = Proj::Context.new
1063
- projected = Proj::Crs.new('EPSG:32631')
1064
-
1065
- crs_3d = projected.projected_3d
1066
- assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1067
- assert_equal(crs_3d.name, projected.name)
1068
-
1069
- cs = crs_3d.coordinate_system
1070
- assert_equal(3, cs.axis_count)
1071
- end
1072
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class CrsTest < AbstractTest
6
+ def test_create_from_epsg
7
+ crs = Proj::Crs.new('EPSG:4326')
8
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
9
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
10
+
11
+ assert_nil(crs.id)
12
+ assert_equal('WGS 84', crs.description)
13
+ assert_empty(crs.definition)
14
+ refute(crs.has_inverse?)
15
+ assert_equal(-1.0, crs.accuracy)
16
+ end
17
+
18
+ def test_create_from_urn
19
+ crs = Proj::Crs.new('urn:ogc:def:crs:EPSG::4326')
20
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
21
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
22
+ end
23
+
24
+ def test_create_from_wkt
25
+ crs = Proj::Crs.new(<<~EOS)
26
+ GEOGCRS["WGS 84",
27
+ DATUM["World Geodetic System 1984",
28
+ ELLIPSOID["WGS 84",6378137,298.257223563,
29
+ LENGTHUNIT["metre",1]]],
30
+ PRIMEM["Greenwich",0,
31
+ ANGLEUNIT["degree",0.0174532925199433]],
32
+ CS[ellipsoidal,2],
33
+ AXIS["geodetic latitude (Lat)",north,
34
+ ORDER[1],
35
+ ANGLEUNIT["degree",0.0174532925199433]],
36
+ AXIS["geodetic longitude (Lon)",east,
37
+ ORDER[2],
38
+ ANGLEUNIT["degree",0.0174532925199433]],
39
+ USAGE[
40
+ SCOPE["unknown"],
41
+ AREA["World"],
42
+ BBOX[-90,-180,90,180]],
43
+ ID["EPSG",4326]]
44
+ EOS
45
+
46
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
47
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
48
+ end
49
+
50
+ def test_create_from_wkt_2
51
+ wkt = <<~EOS
52
+ GEOGCRS["WGS 84",
53
+ DATUM["World Geodetic System 1984",
54
+ ELLIPSOID["WGS 84",6378137,298.257223563,
55
+ LENGTHUNIT["metre",1]]],
56
+ PRIMEM["Greenwich",0,
57
+ ANGLEUNIT["degree",0.0174532925199433]],
58
+ CS[ellipsoidal,2],
59
+ AXIS["geodetic latitude (Lat)",north,
60
+ ORDER[1],
61
+ ANGLEUNIT["degree",0.0174532925199433]],
62
+ AXIS["geodetic longitude (Lon)",east,
63
+ ORDER[2],
64
+ ANGLEUNIT["degree",0.0174532925199433]],
65
+ USAGE[
66
+ SCOPE["unknown"],
67
+ AREA["World"],
68
+ BBOX[-90,-180,90,180]],
69
+ ID["EPSG",4326]]
70
+ EOS
71
+
72
+ crs = Proj::Crs.create_from_wkt(wkt)
73
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
74
+ assert_equal(wkt.strip, crs.to_wkt)
75
+ end
76
+
77
+ def test_create_from_wkt_warning
78
+ wkt = <<~EOS
79
+ PROJCS["test",
80
+ GEOGCS["WGS 84",
81
+ DATUM["WGS_1984",
82
+ SPHEROID["WGS 84",6378137,298.257223563]],
83
+ PRIMEM["Greenwich",0],
84
+ UNIT["degree",0.0174532925199433]],
85
+ PROJECTION["Transverse_Mercator"],
86
+ PARAMETER["latitude_of_origi",31],
87
+ UNIT["metre",1]]"
88
+ EOS
89
+ wkt = wkt.strip
90
+
91
+ crs = nil
92
+ _, err = capture_io do
93
+ crs = Proj::Crs.create_from_wkt(wkt)
94
+ end
95
+
96
+ if Proj::Api::PROJ_VERSION >= '9.6.0'
97
+ expected = "The WKT string lacks a value for Scale factor at natural origin. Default it to 1.. Cannot find expected parameter Latitude of natural origin. Cannot find expected parameter Longitude of natural origin. Cannot find expected parameter False easting. Cannot find expected parameter False northing. Parameter latitude_of_origi found but not expected for this method"
98
+ else
99
+ expected = "Cannot find expected parameter Latitude of natural origin. Cannot find expected parameter Longitude of natural origin. Cannot find expected parameter False easting. Cannot find expected parameter False northing. Parameter latitude_of_origi found but not expected for this method. The WKT string lacks a value for Scale factor at natural origin. Default it to 1."
100
+ end
101
+ assert_equal(expected, err.strip)
102
+
103
+ assert_equal(:PJ_TYPE_PROJECTED_CRS, crs.proj_type)
104
+ end
105
+
106
+ def test_create_from_wkt_error
107
+ wkt = <<~EOS
108
+ GEOGCS[test,
109
+ DATUM[test,
110
+ SPHEROID[test,0,298.257223563,unused]],
111
+ PRIMEM[Greenwich,0],
112
+ UNIT[degree,0.0174532925199433]]
113
+ EOS
114
+ wkt = wkt.strip
115
+
116
+ error = assert_raises(RuntimeError) do
117
+ Proj::Crs.create_from_wkt(wkt)
118
+ end
119
+
120
+ expected = <<~EOS
121
+ Parsing error : syntax error, unexpected identifier, expecting string. Error occurred around:
122
+ GEOGCS[test,
123
+ ^
124
+ EOS
125
+
126
+ assert_equal(expected.strip, error.to_s)
127
+ end
128
+
129
+ def test_create_from_proj4
130
+ crs = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
131
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
132
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
133
+ end
134
+
135
+ def test_create_from_database
136
+ crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
137
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
138
+ assert_equal("4326", crs.id_code)
139
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
140
+ end
141
+
142
+ def test_compound
143
+ crs = Proj::Crs.new('EPSG:2393+5717')
144
+ assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
145
+ assert_equal('+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +units=m +vunits=m +no_defs +type=crs', crs.to_proj_string)
146
+
147
+ crs = Proj::Crs.new('urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717')
148
+ assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
149
+ assert_equal('+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +units=m +vunits=m +no_defs +type=crs', crs.to_proj_string)
150
+ end
151
+
152
+ def test_not_crs
153
+ error = assert_raises(Proj::Error) do
154
+ Proj::Crs.new('+proj=utm +zone=32 +datum=WGS84')
155
+ end
156
+ assert_equal('Invalid crs definition. Proj created an instance of: PJ_TYPE_OTHER_COORDINATE_OPERATION.', error.message)
157
+ end
158
+
159
+ def test_finalize
160
+ 100.times do
161
+ crs = Proj::Crs.new('EPSG:4326')
162
+ assert(crs.to_ptr)
163
+ GC.start
164
+ end
165
+ assert(true)
166
+ end
167
+
168
+ def test_geodetic_crs
169
+ crs = Proj::Crs.new('EPSG:4326')
170
+ geodetic = crs.geodetic_crs
171
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, geodetic.proj_type)
172
+ assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', geodetic.to_proj_string)
173
+ end
174
+
175
+ def test_datum
176
+ wkt = <<~EOS
177
+ PROJCS["WGS 84 / UTM zone 31N",
178
+ GEOGCS["WGS 84",
179
+ DATUM["WGS_1984",
180
+ SPHEROID["WGS 84",6378137,298.257223563,
181
+ AUTHORITY["EPSG","7030"]],
182
+ AUTHORITY["EPSG","6326"]],
183
+ PRIMEM["Greenwich",0,
184
+ AUTHORITY["EPSG","8901"]],
185
+ UNIT["degree",0.0174532925199433,
186
+ AUTHORITY["EPSG","9122"]],
187
+ AUTHORITY["EPSG","4326"]],
188
+ PROJECTION["Transverse_Mercator"],
189
+ PARAMETER["latitude_of_origin",0],
190
+ PARAMETER["central_meridian",3],
191
+ PARAMETER["scale_factor",0.9996],
192
+ PARAMETER["false_easting",500000],
193
+ PARAMETER["false_northing",0],
194
+ UNIT["metre",1,
195
+ AUTHORITY["EPSG","9001"]],
196
+ AXIS["Easting",EAST],
197
+ AXIS["Northing",NORTH],
198
+ AUTHORITY["EPSG","32631"]]
199
+ EOS
200
+
201
+ crs = Proj::Crs.create_from_wkt(wkt)
202
+ datum = crs.datum
203
+ assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, datum.proj_type)
204
+ end
205
+
206
+ def test_datum_forced
207
+ wkt = <<~EOS
208
+ GEOGCRS["ETRS89",
209
+ ENSEMBLE["European Terrestrial Reference System 1989 ensemble",
210
+ MEMBER["European Terrestrial Reference Frame 1989"],
211
+ MEMBER["European Terrestrial Reference Frame 1990"],
212
+ MEMBER["European Terrestrial Reference Frame 1991"],
213
+ MEMBER["European Terrestrial Reference Frame 1992"],
214
+ MEMBER["European Terrestrial Reference Frame 1993"],
215
+ MEMBER["European Terrestrial Reference Frame 1994"],
216
+ MEMBER["European Terrestrial Reference Frame 1996"],
217
+ MEMBER["European Terrestrial Reference Frame 1997"],
218
+ MEMBER["European Terrestrial Reference Frame 2000"],
219
+ MEMBER["European Terrestrial Reference Frame 2005"],
220
+ MEMBER["European Terrestrial Reference Frame 2014"],
221
+ ELLIPSOID["GRS 1980",6378137,298.257222101,
222
+ LENGTHUNIT["metre",1]],
223
+ ENSEMBLEACCURACY[0.1]],
224
+ PRIMEM["Greenwich",0,
225
+ ANGLEUNIT["degree",0.0174532925199433]],
226
+ CS[ellipsoidal,2],
227
+ AXIS["geodetic latitude (Lat)",north,
228
+ ORDER[1],
229
+ ANGLEUNIT["degree",0.0174532925199433]],
230
+ AXIS["geodetic longitude (Lon)",east,
231
+ ORDER[2],
232
+ ANGLEUNIT["degree",0.0174532925199433]]]
233
+ EOS
234
+
235
+ crs = Proj::Crs.create(wkt)
236
+ datum = crs.datum_forced
237
+ assert_equal("European Terrestrial Reference System 1989", datum.name)
238
+ end
239
+
240
+ def test_horizontal_datum
241
+ crs = Proj::Crs.new('EPSG:4326')
242
+ datum = crs.horizontal_datum
243
+ # proj_crs_get_horizontal_datum may return either a datum ensemble or a
244
+ # geodetic reference frame depending on the PROJ/EPSG database version.
245
+ assert_includes([:PJ_TYPE_DATUM_ENSEMBLE, :PJ_TYPE_GEODETIC_REFERENCE_FRAME], datum.proj_type)
246
+ assert(datum.name.start_with?("World Geodetic System 1984"))
247
+ end
248
+
249
+ def test_coordinate_system
250
+ crs = Proj::Crs.new('EPSG:4326')
251
+ assert(crs.coordinate_system)
252
+ end
253
+
254
+ def test_ellipsoid
255
+ crs = Proj::Crs.new('EPSG:4326')
256
+ ellipsoid = crs.ellipsoid
257
+ assert_instance_of(Proj::Ellipsoid, ellipsoid)
258
+ assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
259
+ end
260
+
261
+ def test_prime_meridian
262
+ crs = Proj::Crs.new('EPSG:4326')
263
+ prime_meridian = crs.prime_meridian
264
+ assert_instance_of(Proj::PrimeMeridian, prime_meridian)
265
+ assert_equal('Greenwich', prime_meridian.name)
266
+ end
267
+
268
+ def test_coordinate_operation
269
+ crs = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
270
+
271
+ conversion_1 = crs.coordinate_operation
272
+ assert_equal("UTM zone 31N", conversion_1.name)
273
+ end
274
+
275
+ def test_area_of_use
276
+ crs = Proj::Crs.new('EPSG:4326')
277
+ assert_kind_of(Proj::Area, crs.area_of_use)
278
+ assert_equal('World.', crs.area_of_use.name)
279
+ assert_in_delta(-180.0, crs.area_of_use.west_lon_degree, 0.1)
280
+ assert_in_delta(-90.0, crs.area_of_use.south_lat_degree, 0.1)
281
+ assert_in_delta(180.0, crs.area_of_use.east_lon_degree, 0.1)
282
+ assert_in_delta(90.0, crs.area_of_use.north_lat_degree, 0.1)
283
+ end
284
+
285
+ def test_area_of_use_to_s
286
+ crs = Proj::Crs.new('EPSG:4326')
287
+ area = crs.area_of_use
288
+ expected = "Area west_lon_degree: -180.0, south_lat_degree: -90.0, east_lon_degree: 180.0, north_lat_degree: 90.0"
289
+ assert_equal(expected, area.to_s)
290
+ end
291
+
292
+ def test_area_of_use_stale_errno
293
+ # Leave stale errno on the context via a failed operation.
294
+ # proj_get_area_of_use returns :bool, so the check must use `unless result`
295
+ # not `result != 1` (since true != 1 is always true in Ruby).
296
+ context = Proj::Context.new
297
+ assert_raises(Proj::Error) do
298
+ Proj::Conversion.new("invalid_projection_string", context)
299
+ end
300
+
301
+ crs = Proj::Crs.new('EPSG:4326', context)
302
+ area = crs.area_of_use
303
+ assert_equal('World.', area.name)
304
+ end
305
+
306
+ def test_derived
307
+ crs = Proj::Crs.new('EPSG:4326')
308
+ refute(crs.derived?)
309
+ end
310
+
311
+ def test_non_deprecated
312
+ crs = Proj::Crs.new('EPSG:4226')
313
+ objects = crs.non_deprecated
314
+ assert_equal(2, objects.count)
315
+
316
+ object = objects[0]
317
+ assert_equal("#<Proj::Crs - Locodjo 1965, PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
318
+
319
+ object = objects[1]
320
+ assert_equal("#<Proj::Crs - Abidjan 1987, PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
321
+ end
322
+
323
+ def test_identify
324
+ crs = Proj::Crs.new('OGC:CRS84')
325
+ objects, confidences = crs.identify('OGC')
326
+
327
+ assert_equal(1, objects.count)
328
+ object = objects[0]
329
+ assert_equal("#<Proj::Crs - WGS 84 (CRS84), PJ_TYPE_GEOGRAPHIC_2D_CRS>", object.to_s)
330
+
331
+ assert_equal(1, confidences.count)
332
+ confidence = confidences[0]
333
+ assert_equal(100, confidence)
334
+ end
335
+
336
+ def test_lp_distance
337
+ wkt = <<~EOS
338
+ GEODCRS["WGS 84",
339
+ DATUM["World Geodetic System 1984",
340
+ ELLIPSOID["WGS 84",6378137,298.257223563,
341
+ LENGTHUNIT["metre",1]]],
342
+ PRIMEM["Greenwich",0,
343
+ ANGLEUNIT["degree",0.0174532925199433]],
344
+ CS[ellipsoidal,2],
345
+ AXIS["latitude",north,
346
+ ORDER[1],
347
+ ANGLEUNIT["degree",0.0174532925199433]],
348
+ AXIS["longitude",east,
349
+ ORDER[2],
350
+ ANGLEUNIT["degree",0.0174532925199433]],
351
+ ID["EPSG",4326]]
352
+ EOS
353
+
354
+ crs = Proj::Crs.new(wkt)
355
+ coord1 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
356
+ y: Proj.degrees_to_radians(49),
357
+ z: 0, t:0)
358
+ coord2 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
359
+ y: Proj.degrees_to_radians(50),
360
+ z: 0, t:0)
361
+
362
+ distance = crs.lp_distance(coord1, coord2)
363
+ assert_in_delta(111219.409, distance, 1e-3)
364
+ end
365
+
366
+ def test_geod_distance
367
+ wkt = <<~EOS
368
+ GEODCRS["WGS 84",
369
+ DATUM["World Geodetic System 1984",
370
+ ELLIPSOID["WGS 84",6378137,298.257223563,
371
+ LENGTHUNIT["metre",1]]],
372
+ PRIMEM["Greenwich",0,
373
+ ANGLEUNIT["degree",0.0174532925199433]],
374
+ CS[ellipsoidal,2],
375
+ AXIS["latitude",north,
376
+ ORDER[1],
377
+ ANGLEUNIT["degree",0.0174532925199433]],
378
+ AXIS["longitude",east,
379
+ ORDER[2],
380
+ ANGLEUNIT["degree",0.0174532925199433]],
381
+ ID["EPSG",4326]]
382
+ EOS
383
+
384
+ crs = Proj::Crs.new(wkt)
385
+ coord1 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
386
+ y: Proj.degrees_to_radians(49),
387
+ z: 0, t:0)
388
+ coord2 = Proj::Coordinate.new(x: Proj.degrees_to_radians(2),
389
+ y: Proj.degrees_to_radians(50),
390
+ z: 0, t:0)
391
+
392
+ coord3 = crs.geod_distance(coord1, coord2)
393
+ assert_in_delta(111219.409, coord3.x, 1e-3)
394
+ end
395
+
396
+ def test_source_crs
397
+ wkt = <<~EOS
398
+ PROJCRS["WGS 84 / UTM zone 31N",
399
+ BASEGEODCRS["WGS 84",
400
+ DATUM["World Geodetic System 1984",
401
+ ELLIPSOID["WGS 84",6378137,298.257223563,
402
+ LENGTHUNIT["metre",1]]],
403
+ PRIMEM["Greenwich",0,
404
+ ANGLEUNIT["degree",0.0174532925199433]]],
405
+ CONVERSION["UTM zone 31N",
406
+ METHOD["Transverse Mercator",
407
+ ID["EPSG",9807]],
408
+ PARAMETER["Latitude of natural origin",0,
409
+ ANGLEUNIT["degree",0.0174532925199433],
410
+ ID["EPSG",8801]],
411
+ PARAMETER["Longitude of natural origin",3,
412
+ ANGLEUNIT["degree",0.0174532925199433],
413
+ ID["EPSG",8802]],
414
+ PARAMETER["Scale factor at natural origin",0.9996,
415
+ SCALEUNIT["unity",1],
416
+ ID["EPSG",8805]],
417
+ PARAMETER["False easting",500000,
418
+ LENGTHUNIT["metre",1],
419
+ ID["EPSG",8806]],
420
+ PARAMETER["False northing",0,
421
+ LENGTHUNIT["metre",1],
422
+ ID["EPSG",8807]]],
423
+ CS[Cartesian,2],
424
+ AXIS["(E)",east,
425
+ ORDER[1],
426
+ LENGTHUNIT["metre",1]],
427
+ AXIS["(N)",north,
428
+ ORDER[2],
429
+ LENGTHUNIT["metre",1]],
430
+ ID["EPSG",32631]]
431
+ EOS
432
+
433
+ crs = Proj::Crs.new(wkt)
434
+ source_crs = crs.source_crs
435
+ assert_equal("WGS 84", source_crs.name)
436
+ end
437
+
438
+ def test_target_crs
439
+ wkt = <<~EOS
440
+ BOUNDCRS[
441
+ SOURCECRS[
442
+ GEODCRS["NTF (Paris)",
443
+ DATUM["Nouvelle Triangulation Francaise (Paris)",
444
+ ELLIPSOID["Clarke 1880 (IGN)",6378249.2,293.466021293627,
445
+ LENGTHUNIT["metre",1]]],
446
+ PRIMEM["Paris",2.5969213,
447
+ ANGLEUNIT["grad",0.015707963267949]],
448
+ CS[ellipsoidal,2],
449
+ AXIS["latitude",north,
450
+ ORDER[1],
451
+ ANGLEUNIT["grad",0.015707963267949]],
452
+ AXIS["longitude",east,
453
+ ORDER[2],
454
+ ANGLEUNIT["grad",0.015707963267949]],
455
+ ID["EPSG",4807]]],
456
+ TARGETCRS[
457
+ GEODCRS["WGS 84",
458
+ DATUM["World Geodetic System 1984",
459
+ ELLIPSOID["WGS 84",6378137,298.257223563,
460
+ LENGTHUNIT["metre",1]]],
461
+ PRIMEM["Greenwich",0,
462
+ ANGLEUNIT["degree",0.0174532925199433]],
463
+ CS[ellipsoidal,2],
464
+ AXIS["latitude",north,
465
+ ORDER[1],
466
+ ANGLEUNIT["degree",0.0174532925199433]],
467
+ AXIS["longitude",east,
468
+ ORDER[2],
469
+ ANGLEUNIT["degree",0.0174532925199433]],
470
+ ID["EPSG",4326]]],
471
+ ABRIDGEDTRANSFORMATION["",
472
+ METHOD[""],
473
+ PARAMETER["foo",1]]]
474
+ EOS
475
+
476
+ crs = Proj::Crs.new(wkt)
477
+ target_crs = crs.target_crs
478
+ assert_equal("WGS 84", target_crs.name)
479
+ end
480
+
481
+ def test_to_proj_string
482
+ crs = Proj::Crs.new('EPSG:26915')
483
+ assert_equal('+proj=utm +zone=15 +datum=NAD83 +units=m +no_defs +type=crs', crs.to_proj_string)
484
+ end
485
+
486
+ def test_to_wkt
487
+ crs = Proj::Crs.new('EPSG:26915')
488
+
489
+ expected = <<~EOS
490
+ PROJCRS["NAD83 / UTM zone 15N",
491
+ BASEGEOGCRS["NAD83",
492
+ DATUM["North American Datum 1983",
493
+ ELLIPSOID["GRS 1980",6378137,298.257222101,
494
+ LENGTHUNIT["metre",1]]],
495
+ PRIMEM["Greenwich",0,
496
+ ANGLEUNIT["degree",0.0174532925199433]],
497
+ ID["EPSG",4269]],
498
+ CONVERSION["UTM zone 15N",
499
+ METHOD["Transverse Mercator",
500
+ ID["EPSG",9807]],
501
+ PARAMETER["Latitude of natural origin",0,
502
+ ANGLEUNIT["degree",0.0174532925199433],
503
+ ID["EPSG",8801]],
504
+ PARAMETER["Longitude of natural origin",-93,
505
+ ANGLEUNIT["degree",0.0174532925199433],
506
+ ID["EPSG",8802]],
507
+ PARAMETER["Scale factor at natural origin",0.9996,
508
+ SCALEUNIT["unity",1],
509
+ ID["EPSG",8805]],
510
+ PARAMETER["False easting",500000,
511
+ LENGTHUNIT["metre",1],
512
+ ID["EPSG",8806]],
513
+ PARAMETER["False northing",0,
514
+ LENGTHUNIT["metre",1],
515
+ ID["EPSG",8807]]],
516
+ CS[Cartesian,2],
517
+ AXIS["(E)",east,
518
+ ORDER[1],
519
+ LENGTHUNIT["metre",1]],
520
+ AXIS["(N)",north,
521
+ ORDER[2],
522
+ LENGTHUNIT["metre",1]],
523
+ USAGE[
524
+ SCOPE["Engineering survey, topographic mapping."],
525
+ AREA["North America - between 96\xC2\xB0W and 90\xC2\xB0W - onshore and offshore. Canada - Manitoba; Nunavut; Ontario. United States (USA) - Arkansas; Illinois; Iowa; Kansas; Louisiana; Michigan; Minnesota; Mississippi; Missouri; Nebraska; Oklahoma; Tennessee; Texas; Wisconsin."],
526
+ BBOX[25.61,-96,84,-90]],
527
+ ID["EPSG",26915]]
528
+ EOS
529
+
530
+ assert_equal(expected.strip, crs.to_wkt)
531
+ end
532
+
533
+ def test_to_wkt_single_line
534
+ crs = Proj::Crs.new('EPSG:4326')
535
+ wkt = crs.to_wkt(multiline: false)
536
+ refute_includes(wkt, "\n")
537
+ end
538
+
539
+ def test_to_json
540
+ crs = Proj::Crs.new('EPSG:26915')
541
+
542
+ schema_version = case
543
+ when Proj::Api::PROJ_VERSION >= '9.0.0'
544
+ 'v0.7'
545
+ when Proj::Api::PROJ_VERSION >= '9.3.0'
546
+ 'v0.5'
547
+ else
548
+ 'v0.4'
549
+ end
550
+
551
+ expected = <<~EOS
552
+ {
553
+ "$schema": "https://proj.org/schemas/#{schema_version}/projjson.schema.json",
554
+ "type": "ProjectedCRS",
555
+ "name": "NAD83 / UTM zone 15N",
556
+ "base_crs": {#{Proj::Api::PROJ_VERSION >= '9.6.0' ? "\n \"type\": \"GeographicCRS\"," : ''}
557
+ "name": "NAD83",
558
+ "datum": {
559
+ "type": "GeodeticReferenceFrame",
560
+ "name": "North American Datum 1983",
561
+ "ellipsoid": {
562
+ "name": "GRS 1980",
563
+ "semi_major_axis": 6378137,
564
+ "inverse_flattening": 298.257222101
565
+ }
566
+ },
567
+ "coordinate_system": {
568
+ "subtype": "ellipsoidal",
569
+ "axis": [
570
+ {
571
+ "name": "Geodetic latitude",
572
+ "abbreviation": "Lat",
573
+ "direction": "north",
574
+ "unit": "degree"
575
+ },
576
+ {
577
+ "name": "Geodetic longitude",
578
+ "abbreviation": "Lon",
579
+ "direction": "east",
580
+ "unit": "degree"
581
+ }
582
+ ]
583
+ },
584
+ "id": {
585
+ "authority": "EPSG",
586
+ "code": 4269
587
+ }#{Proj::Api::PROJ_VERSION >= Gem::Version.new('9.8.0') ? ",\n \"remarks\": \"Longitude is POSITIVE EAST. The adjustment included connections to Greenland and Mexico but the system was not adopted there. For applications with an accuracy of better than 1m replaced by NAD83(HARN) in the US and PRVI and by NAD83(CSRS) in Canada.\"" : ''}
588
+ },
589
+ "conversion": {
590
+ "name": "UTM zone 15N",
591
+ "method": {
592
+ "name": "Transverse Mercator",
593
+ "id": {
594
+ "authority": "EPSG",
595
+ "code": 9807
596
+ }
597
+ },
598
+ "parameters": [
599
+ {
600
+ "name": "Latitude of natural origin",
601
+ "value": 0,
602
+ "unit": "degree",
603
+ "id": {
604
+ "authority": "EPSG",
605
+ "code": 8801
606
+ }
607
+ },
608
+ {
609
+ "name": "Longitude of natural origin",
610
+ "value": -93,
611
+ "unit": "degree",
612
+ "id": {
613
+ "authority": "EPSG",
614
+ "code": 8802
615
+ }
616
+ },
617
+ {
618
+ "name": "Scale factor at natural origin",
619
+ "value": 0.9996,
620
+ "unit": "unity",
621
+ "id": {
622
+ "authority": "EPSG",
623
+ "code": 8805
624
+ }
625
+ },
626
+ {
627
+ "name": "False easting",
628
+ "value": 500000,
629
+ "unit": "metre",
630
+ "id": {
631
+ "authority": "EPSG",
632
+ "code": 8806
633
+ }
634
+ },
635
+ {
636
+ "name": "False northing",
637
+ "value": 0,
638
+ "unit": "metre",
639
+ "id": {
640
+ "authority": "EPSG",
641
+ "code": 8807
642
+ }
643
+ }
644
+ ]
645
+ },
646
+ "coordinate_system": {
647
+ "subtype": "Cartesian",
648
+ "axis": [
649
+ {
650
+ "name": "Easting",
651
+ "abbreviation": "E",
652
+ "direction": "east",
653
+ "unit": "metre"
654
+ },
655
+ {
656
+ "name": "Northing",
657
+ "abbreviation": "N",
658
+ "direction": "north",
659
+ "unit": "metre"
660
+ }
661
+ ]
662
+ },
663
+ "scope": "Engineering survey, topographic mapping.",
664
+ "area": "North America - between 96\xC2\xB0W and 90\xC2\xB0W - onshore and offshore. Canada - Manitoba; Nunavut; Ontario. United States (USA) - Arkansas; Illinois; Iowa; Kansas; Louisiana; Michigan; Minnesota; Mississippi; Missouri; Nebraska; Oklahoma; Tennessee; Texas; Wisconsin.",
665
+ "bbox": {
666
+ "south_latitude": 25.61,
667
+ "west_longitude": -96,
668
+ "north_latitude": 84,
669
+ "east_longitude": -90
670
+ },
671
+ "id": {
672
+ "authority": "EPSG",
673
+ "code": 26915
674
+ }
675
+ }
676
+ EOS
677
+
678
+ assert_equal(expected.strip, crs.to_json)
679
+ end
680
+
681
+ def test_to_wgs84
682
+ wkt = <<~EOS
683
+ BOUNDCRS[
684
+ SOURCECRS[
685
+ GEOGCRS["NTF (Paris)",
686
+ DATUM["Nouvelle Triangulation Francaise (Paris)",
687
+ ELLIPSOID["Clarke 1880 (IGN)",6378249.2,293.466021293627,
688
+ LENGTHUNIT["metre",1]]],
689
+ PRIMEM["Paris",2.5969213,
690
+ ANGLEUNIT["grad",0.0157079632679489]],
691
+ CS[ellipsoidal,2],
692
+ AXIS["geodetic latitude (Lat)",north,
693
+ ORDER[1],
694
+ ANGLEUNIT["grad",0.0157079632679489]],
695
+ AXIS["geodetic longitude (Lon)",east,
696
+ ORDER[2],
697
+ ANGLEUNIT["grad",0.0157079632679489]],
698
+ USAGE[
699
+ SCOPE["Geodesy."],
700
+ AREA["France - onshore - mainland and Corsica."],
701
+ BBOX[41.31,-4.87,51.14,9.63]],
702
+ ID["EPSG",4807]]],
703
+ TARGETCRS[
704
+ GEOGCRS["WGS 84",
705
+ DATUM["World Geodetic System 1984",
706
+ ELLIPSOID["WGS 84",6378137,298.257223563,
707
+ LENGTHUNIT["metre",1]]],
708
+ PRIMEM["Greenwich",0,
709
+ ANGLEUNIT["degree",0.0174532925199433]],
710
+ CS[ellipsoidal,2],
711
+ AXIS["latitude",north,
712
+ ORDER[1],
713
+ ANGLEUNIT["degree",0.0174532925199433]],
714
+ AXIS["longitude",east,
715
+ ORDER[2],
716
+ ANGLEUNIT["degree",0.0174532925199433]],
717
+ ID["EPSG",4326]]],
718
+ ABRIDGEDTRANSFORMATION["NTF to WGS 84 (1)",
719
+ VERSION["IGN-Fra"],
720
+ METHOD["Geocentric translations (geog2D domain)",
721
+ ID["EPSG",9603]],
722
+ PARAMETER["X-axis translation",-168,
723
+ ID["EPSG",8605]],
724
+ PARAMETER["Y-axis translation",-60,
725
+ ID["EPSG",8606]],
726
+ PARAMETER["Z-axis translation",320,
727
+ ID["EPSG",8607]],
728
+ USAGE[
729
+ SCOPE["(null/copy) Approximation for medium and low accuracy applications assuming equality between plate-fixed static and earth-fixed dynamic CRSs, ignoring static/dynamic CRS differences."],
730
+ AREA["France - onshore - mainland and Corsica."],
731
+ BBOX[41.31,-4.87,51.14,9.63]],
732
+ ID["EPSG",1193],
733
+ REMARK["These same parameter values are used to transform to ETRS89. See NTF to ETRS89 (1) (code 1651)."]]]
734
+ EOS
735
+
736
+ crs = Proj::Crs.new(wkt)
737
+ operation = crs.coordinate_operation
738
+ values = operation.to_wgs84
739
+
740
+ expected = [-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0]
741
+ assert_equal(expected, values)
742
+ end
743
+
744
+ def test_geographic
745
+ context = Proj::Context.new
746
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
747
+
748
+ crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
749
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
750
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
751
+ coordinate_system: coordinate_system)
752
+
753
+ crs_2 = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
754
+ assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
755
+ end
756
+
757
+ def test_geographic_datum
758
+ context = Proj::Context.new
759
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
760
+ datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
761
+ crs = Proj::Crs.create_geographic_from_datum(context, name: "WGS 84", datum: datum, coordinate_system: coordinate_system)
762
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
763
+ end
764
+
765
+ def test_geocentric
766
+ context = Proj::Context.new
767
+ crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
768
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
769
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
770
+ angular_units: "Degree", angular_units_conv: 0.0174532925199433,
771
+ linear_units: "Metre", linear_units_conv: 1.0)
772
+
773
+ crs_2 = Proj::Crs.create_from_database("EPSG", "4978", :PJ_CATEGORY_CRS)
774
+ assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
775
+ end
776
+
777
+ def test_geocentric_datum
778
+ context = Proj::Context.new
779
+ crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
780
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
781
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
782
+ angular_units: "Degree", angular_units_conv: 0.0174532925199433,
783
+ linear_units: "Metre", linear_units_conv: 1.0)
784
+ datum = crs.datum
785
+
786
+ geocentric_crs = Proj::Crs.create_geocentric_from_datum(context, name: "WGS 84", datum: datum,
787
+ linear_units: "Metre", linear_units_conv: 1.0)
788
+
789
+ assert(crs.equivalent_to?(geocentric_crs, :PJ_COMP_STRICT))
790
+ end
791
+
792
+ def test_vertical_crs_ex
793
+ context = Proj::Context.new
794
+
795
+ vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS (ftUS)",
796
+ datum_name: "myVertDatum",
797
+ linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
798
+ geoid_model_name: "PROJ @foo.gtx",
799
+ accuracy: 123)
800
+ assert(vertical_crs)
801
+ assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
802
+ end
803
+
804
+ def test_vertical_crs_ex_with_geog_crs
805
+ context = Proj::Context.new
806
+ # WGS84
807
+ wgs84 = Proj::Crs.new("EPSG:4979", context)
808
+
809
+ vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
810
+ datum_name: "myVertDatum",
811
+ linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
812
+ geoid_model_name: "PROJ @foo.gtx",
813
+ geoid_geog_crs: wgs84)
814
+ assert(vertical_crs)
815
+ assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
816
+ end
817
+
818
+ def test_bound_vertical
819
+ context = Proj::Context.new
820
+ vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
821
+ datum_name: "myVertDatum")
822
+
823
+ crs_4979 = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
824
+ bound = Proj::Crs.create_bound_vertical(context, vertical_crs: vertical_crs,
825
+ hub_crs: crs_4979, grid_name: "foo.gtx")
826
+
827
+ assert_equal(:PJ_TYPE_BOUND_CRS, bound.proj_type)
828
+ assert_equal("myVertCRS", bound.name)
829
+ end
830
+
831
+ def test_create_compound
832
+ context = Proj::Context.new
833
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
834
+
835
+ horizontal_crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
836
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
837
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
838
+ coordinate_system: coordinate_system)
839
+
840
+ vertical_crs = Proj::Crs.create_vertical(context, name: "myVertCRS",
841
+ datum_name: "myVertDatum",
842
+ linear_units: "US survey foot", linear_units_conv: 0.304800609601219)
843
+
844
+ assert(vertical_crs)
845
+ assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
846
+ assert_equal("myVertCRS", vertical_crs.name)
847
+
848
+ compound_crs = Proj::Crs.create_compound(context, name: "myCompoundCRS",
849
+ horizontal_crs: horizontal_crs, vertical_crs: vertical_crs);
850
+ assert(compound_crs)
851
+ assert_equal(:PJ_TYPE_COMPOUND_CRS, compound_crs.proj_type)
852
+ assert_equal("myCompoundCRS", compound_crs.name)
853
+
854
+ crs = compound_crs.sub_crs(0)
855
+ assert(crs.equivalent_to?(horizontal_crs, :PJ_COMP_STRICT))
856
+
857
+ crs = compound_crs.sub_crs(1)
858
+ assert(crs.equivalent_to?(vertical_crs, :PJ_COMP_STRICT))
859
+ end
860
+
861
+ def test_derived_geographic
862
+ context = Proj::Context.new
863
+ crs = Proj::Crs.create("EPSG:4326", context)
864
+
865
+ conversion = Proj::Projection.pole_rotation_grib_convention(context, south_pole_lat_in_unrotated_crs: 2, south_pole_long_in_unrotated_crs: 3,
866
+ axis_rotation: 4, angular_unit_name: "Degree", angular_unit_conversion_factor: 0.0174532925199433)
867
+
868
+ coordinate_system = crs.coordinate_system
869
+
870
+ # Wrong type of base_geographic_crs
871
+ derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
872
+ base_geographic_crs: conversion, conversion: conversion,
873
+ coordinate_system: coordinate_system)
874
+ refute(derived_crs)
875
+
876
+ # Wrong type of conversion
877
+ derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
878
+ base_geographic_crs: crs, conversion: crs,
879
+ coordinate_system: coordinate_system)
880
+ refute(derived_crs)
881
+
882
+ derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
883
+ base_geographic_crs: crs, conversion: conversion,
884
+ coordinate_system: coordinate_system)
885
+ refute(crs.derived?)
886
+ assert(derived_crs.derived?)
887
+
888
+ expected = "+proj=ob_tran +o_proj=longlat +o_lon_p=-4 +o_lat_p=-2 +lon_0=3 +datum=WGS84 +no_defs +type=crs"
889
+ assert_equal(expected, derived_crs.to_proj_string)
890
+ end
891
+
892
+ def test_projected
893
+ context = Proj::Context.new
894
+ param = Proj::Parameter.new(name: "param name", value: 0.99,
895
+ unit_conv_factor: 1.0, unit_type: :PJ_UT_SCALE)
896
+
897
+ conversion = Proj::Conversion.create_conversion(context, name: "conv",
898
+ auth_name: "conv auth", code: "conv code",
899
+ method_name: "method", method_auth_name: "method auth", method_code: "method code",
900
+ params: [param])
901
+
902
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
903
+ crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984",
904
+ ellipsoid_name: "WGS 84", semi_major_meter: 6378137, inv_flattening: 298.257223563,
905
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
906
+ pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
907
+ coordinate_system: coordinate_system)
908
+
909
+ cartesian = Proj::CoordinateSystem.create_cartesian_2d(context, :PJ_CART2D_EASTING_NORTHING)
910
+
911
+ projected = Proj::Crs.create_projected(context, name: "My Projected CRS", geodetic_crs: crs,
912
+ conversion: conversion, coordinate_system: cartesian)
913
+ assert_equal(:PJ_TYPE_PROJECTED_CRS, projected.proj_type)
914
+ assert_equal("My Projected CRS", projected.name)
915
+ end
916
+
917
+ def test_create_bound_crs_to_wgs84
918
+ context = Proj::Context.new
919
+ crs = Proj::Crs.create_from_database("EPSG", "4807", :PJ_CATEGORY_CRS)
920
+
921
+ bounded = Proj::Crs.create_bound_to_wgs84(context, crs: crs)
922
+ expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
923
+ assert_equal(expected, bounded.to_proj_string)
924
+
925
+ base_crs = bounded.source_crs
926
+ assert(base_crs.equivalent_to?(crs, :PJ_COMP_EQUIVALENT))
927
+
928
+ hub_crs = bounded.target_crs
929
+ wgs84_crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
930
+ assert(hub_crs.equivalent_to?(wgs84_crs, :PJ_COMP_EQUIVALENT))
931
+
932
+ transform = bounded.coordinate_operation
933
+ values = transform.to_wgs84(true)
934
+ expected = [-168, -60, 320, 0, 0, 0, 0]
935
+ assert_equal(expected, values)
936
+
937
+ bounded_2 = Proj::Crs.create_bound(context, base_crs: base_crs, hub_crs: hub_crs, transformation: transform)
938
+ assert_equal(:PJ_TYPE_BOUND_CRS, bounded_2.proj_type)
939
+ expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
940
+ assert_equal(expected, bounded_2.to_proj_string)
941
+ end
942
+
943
+ def test_create_engineering
944
+ context = Proj::Context.new
945
+ crs = Proj::Crs.create_engineering(context, name: "4807")
946
+ assert_equal("4807", crs.name)
947
+ assert_equal(:PJ_TYPE_ENGINEERING_CRS, crs.proj_type)
948
+
949
+ expected = <<~EOS
950
+ LOCAL_CS["4807",
951
+ UNIT["metre",1,
952
+ AUTHORITY["EPSG","9001"]],
953
+ AXIS["Easting",EAST],
954
+ AXIS["Northing",NORTH]]
955
+ EOS
956
+ assert_equal(expected.strip, crs.to_wkt(:PJ_WKT1_GDAL))
957
+ end
958
+
959
+ def test_query_geodetic_from_datum
960
+ context = Proj::Context.new
961
+ crses = Proj::Crs.query_geodetic_from_datum(context, datum_auth_name: "EPSG", datum_code: "6326")
962
+
963
+ expected = case
964
+ when Proj::Api::PROJ_VERSION >= '9.0.0'
965
+ 12
966
+ else
967
+ 11
968
+ end
969
+
970
+ assert_equal(expected, crses.size)
971
+
972
+ crses = Proj::Crs.query_geodetic_from_datum(context, auth_name: "EPSG",
973
+ datum_auth_name: "EPSG", datum_code: "6326",
974
+ crs_type: "geographic 2D")
975
+ assert_equal(1, crses.size)
976
+ end
977
+
978
+ def test_alter_name
979
+ context = Proj::Context.new
980
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
981
+
982
+ crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
983
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
984
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
985
+ coordinate_system: coordinate_system)
986
+ assert_equal("WGS 84", crs.name)
987
+
988
+ altered = crs.alter_name("new name")
989
+ assert_equal("WGS 84", crs.name)
990
+ assert_equal("new name", altered.name)
991
+ end
992
+
993
+ def test_alter_id
994
+ context = Proj::Context.new
995
+ coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
996
+
997
+ crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
998
+ semi_major_meter: 6378137, inv_flattening: 298.257223563,
999
+ prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
1000
+ coordinate_system: coordinate_system)
1001
+ refute(crs.auth)
1002
+
1003
+ altered = crs.alter_id("auth", "code")
1004
+ refute(crs.auth)
1005
+ assert_equal("auth:code", altered.auth)
1006
+ end
1007
+
1008
+ def test_alter_geodetic_crs
1009
+ context = Proj::Context.new
1010
+ projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1011
+ geod_crs = projected.geodetic_crs
1012
+ new_geod_crs = Proj::Crs.new("+proj=longlat +type=crs", context)
1013
+
1014
+ altered = geod_crs.alter_geodetic_crs(new_geod_crs)
1015
+ assert(altered.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
1016
+
1017
+ altered = projected.alter_geodetic_crs(new_geod_crs)
1018
+ assert_equal(:PJ_TYPE_PROJECTED_CRS, altered.proj_type)
1019
+ assert(altered.geodetic_crs.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
1020
+ end
1021
+
1022
+ def test_alter_cs_angular_unit
1023
+ crs = Proj::Crs.new('EPSG:4326')
1024
+ altered = crs.alter_cs_angular_unit(angular_units: "my unit", angular_units_conv: 2,
1025
+ unit_auth_name: "my auth", unit_code: "my code")
1026
+
1027
+ cs = altered.coordinate_system
1028
+ assert_equal(2, cs.axis_count)
1029
+
1030
+ axis = cs.axis_info(0)
1031
+ assert_equal("my unit", axis.unit_name)
1032
+ assert_equal(2, axis.unit_conv_factor)
1033
+ assert_equal("my auth", axis.unit_auth_name)
1034
+ assert_equal("my code", axis.unit_code)
1035
+ end
1036
+
1037
+ def test_alter_alter_cs_linear_unit
1038
+ projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1039
+ altered = projected.alter_cs_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1040
+ unit_auth_name: "my auth", unit_code: "my code")
1041
+
1042
+ cs = altered.coordinate_system
1043
+ assert_equal(2, cs.axis_count)
1044
+
1045
+ axis = cs.axis_info(0)
1046
+ assert_equal("my unit", axis.unit_name)
1047
+ assert_equal(2, axis.unit_conv_factor)
1048
+ assert_equal("my auth", axis.unit_auth_name)
1049
+ assert_equal("my code", axis.unit_code)
1050
+ end
1051
+
1052
+ def test_alter_parameters_linear_unit
1053
+ projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1054
+ altered = projected.alter_parameters_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1055
+ convert_to_new_unit: false)
1056
+
1057
+ wkt = altered.to_wkt
1058
+ assert_match(/500000/, wkt)
1059
+ assert_match(/"my unit",2/, wkt)
1060
+ end
1061
+
1062
+ def test_promote_to_3d
1063
+ crs = Proj::Crs.new('EPSG:4326')
1064
+
1065
+ crs_3d = crs.promote_to_3d
1066
+ assert_equal("4979", crs_3d.id_code)
1067
+
1068
+ cs = crs_3d.coordinate_system
1069
+ assert_equal(3, cs.axis_count)
1070
+ end
1071
+
1072
+ def test_demote_to_3d
1073
+ crs = Proj::Crs.new('EPSG:4979')
1074
+
1075
+ crs_2d = crs.demote_to_2d
1076
+ assert_equal("4326", crs_2d.id_code)
1077
+
1078
+ cs = crs_2d.coordinate_system
1079
+ assert_equal(2, cs.axis_count)
1080
+ end
1081
+
1082
+ def test_projected_3d_with_base
1083
+ projected = Proj::Crs.new('EPSG:32631')
1084
+ base_crs_3d = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
1085
+
1086
+ crs_3d = projected.projected_3d(geog_3d_crs: base_crs_3d)
1087
+ assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1088
+ assert_equal(crs_3d.name, projected.name)
1089
+
1090
+ cs = crs_3d.coordinate_system
1091
+ assert_equal(3, cs.axis_count)
1092
+ end
1093
+
1094
+ def test_projected_3d_without_base
1095
+ projected = Proj::Crs.new('EPSG:32631')
1096
+
1097
+ crs_3d = projected.projected_3d
1098
+ assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1099
+ assert_equal(crs_3d.name, projected.name)
1100
+
1101
+ cs = crs_3d.coordinate_system
1102
+ assert_equal(3, cs.axis_count)
1103
+ end
1104
+
1105
+ if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.4.0')
1106
+ def test_point_motion_operation
1107
+ # Static CRS — no point motion
1108
+ crs = Proj::Crs.new('EPSG:4326')
1109
+ refute(crs.point_motion_operation?)
1110
+ end
1111
+ end
1112
+ end