proj4rb 4.1.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/Gemfile +4 -4
  4. data/README.md +53 -0
  5. data/lib/api/proj.rb +750 -0
  6. data/lib/api/proj_experimental.rb +7 -0
  7. data/lib/api/proj_ffi.rb +47 -0
  8. data/lib/api/proj_version.rb +26 -0
  9. data/lib/examples/axis_order_normalization.rb +13 -0
  10. data/lib/examples/batch_transformation.rb +25 -0
  11. data/lib/examples/context_logging.rb +26 -0
  12. data/lib/examples/crs_identification.rb +18 -0
  13. data/lib/examples/database_query.rb +27 -0
  14. data/lib/examples/geodetic_distance.rb +38 -0
  15. data/lib/examples/geodetic_to_projected.rb +18 -0
  16. data/lib/examples/operation_factory_context.rb +19 -0
  17. data/lib/examples/pipeline_operator.rb +21 -0
  18. data/lib/examples/promote_demote_3d.rb +23 -0
  19. data/lib/examples/serialization_formats.rb +17 -0
  20. data/lib/examples/transform_bounds.rb +18 -0
  21. data/lib/examples/transformation_with_area.rb +18 -0
  22. data/lib/proj/area.rb +74 -74
  23. data/lib/proj/axis_info.rb +44 -44
  24. data/lib/proj/bounds.rb +22 -0
  25. data/lib/proj/bounds3d.rb +45 -0
  26. data/lib/proj/context.rb +57 -23
  27. data/lib/proj/conversion.rb +94 -91
  28. data/lib/proj/coordinate.rb +304 -281
  29. data/lib/proj/coordinate_metadata.rb +38 -38
  30. data/lib/proj/coordinate_operation_mixin.rb +464 -381
  31. data/lib/proj/coordinate_system.rb +143 -137
  32. data/lib/proj/crs.rb +688 -680
  33. data/lib/proj/crs_info.rb +47 -47
  34. data/lib/proj/database.rb +310 -305
  35. data/lib/proj/datum.rb +32 -32
  36. data/lib/proj/datum_ensemble.rb +34 -34
  37. data/lib/proj/domain.rb +82 -0
  38. data/lib/proj/ellipsoid.rb +77 -77
  39. data/lib/proj/error.rb +7 -8
  40. data/lib/proj/file_api_callbacks.rb +165 -0
  41. data/lib/proj/grid.rb +121 -121
  42. data/lib/proj/grid_cache.rb +65 -64
  43. data/lib/proj/grid_info.rb +19 -19
  44. data/lib/proj/life_span.rb +21 -0
  45. data/lib/proj/network_api_callbacks.rb +86 -0
  46. data/lib/proj/operation.rb +66 -42
  47. data/lib/proj/operation_factory_context.rb +4 -2
  48. data/lib/proj/options.rb +41 -0
  49. data/lib/proj/parameter.rb +37 -37
  50. data/lib/proj/parameters.rb +106 -107
  51. data/lib/proj/pj_axis_description.rb +26 -0
  52. data/lib/proj/pj_object.rb +602 -672
  53. data/lib/proj/pj_objects.rb +45 -45
  54. data/lib/proj/pj_param_description.rb +28 -0
  55. data/lib/proj/prime_meridian.rb +65 -65
  56. data/lib/proj/projection.rb +54 -25
  57. data/lib/proj/session.rb +2 -0
  58. data/lib/proj/transformation.rb +102 -102
  59. data/lib/proj/unit.rb +81 -108
  60. data/lib/proj.rb +10 -3
  61. data/lib/proj4.rb +5 -5
  62. data/proj4rb.gemspec +10 -5
  63. data/test/abstract_test.rb +7 -5
  64. data/test/context_test.rb +210 -172
  65. data/test/context_validation_test.rb +11 -0
  66. data/test/conversion_test.rb +376 -368
  67. data/test/coordinate_metadata_test.rb +34 -0
  68. data/test/coordinate_system_test.rb +162 -144
  69. data/test/coordinate_test.rb +289 -34
  70. data/test/crs_test.rb +1112 -1082
  71. data/test/database_test.rb +407 -391
  72. data/test/datum_ensemble_test.rb +64 -64
  73. data/test/datum_test.rb +61 -54
  74. data/test/domain_test.rb +72 -0
  75. data/test/ellipsoid_test.rb +80 -80
  76. data/test/examples_test.rb +149 -0
  77. data/test/file_api_example.rb +58 -0
  78. data/test/file_api_test.rb +74 -66
  79. data/test/grid_cache_test.rb +72 -72
  80. data/test/grid_test.rb +126 -141
  81. data/test/network_api_example.rb +48 -0
  82. data/test/network_api_test.rb +33 -45
  83. data/test/operation_factory_context_test.rb +225 -205
  84. data/test/operation_test.rb +40 -29
  85. data/test/options_test.rb +17 -0
  86. data/test/parameters_test.rb +86 -40
  87. data/test/pj_object_test.rb +221 -187
  88. data/test/prime_meridian_test.rb +75 -75
  89. data/test/proj_test.rb +58 -58
  90. data/test/projection_test.rb +680 -650
  91. data/test/session_test.rb +78 -77
  92. data/test/transformation_test.rb +238 -210
  93. data/test/unit_test.rb +114 -76
  94. metadata +44 -32
  95. data/ChangeLog +0 -94
  96. data/README.rdoc +0 -189
  97. data/lib/api/api.rb +0 -117
  98. data/lib/api/api_5_0.rb +0 -338
  99. data/lib/api/api_5_1.rb +0 -7
  100. data/lib/api/api_5_2.rb +0 -5
  101. data/lib/api/api_6_0.rb +0 -146
  102. data/lib/api/api_6_1.rb +0 -5
  103. data/lib/api/api_6_2.rb +0 -10
  104. data/lib/api/api_6_3.rb +0 -6
  105. data/lib/api/api_7_0.rb +0 -69
  106. data/lib/api/api_7_1.rb +0 -73
  107. data/lib/api/api_7_2.rb +0 -14
  108. data/lib/api/api_8_0.rb +0 -6
  109. data/lib/api/api_8_1.rb +0 -24
  110. data/lib/api/api_8_2.rb +0 -6
  111. data/lib/api/api_9_1.rb +0 -7
  112. data/lib/api/api_9_2.rb +0 -9
  113. data/lib/api/api_9_4.rb +0 -6
  114. data/lib/api/api_experimental.rb +0 -201
  115. data/lib/proj/file_api.rb +0 -166
  116. data/lib/proj/network_api.rb +0 -92
data/test/crs_test.rb CHANGED
@@ -1,1082 +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
-
509
- schema_version = case
510
- when Proj::Api::PROJ_VERSION >= '9.0.0'
511
- 'v0.7'
512
- when Proj::Api::PROJ_VERSION >= '9.3.0'
513
- 'v0.5'
514
- else
515
- 'v0.4'
516
- end
517
-
518
- expected = <<~EOS
519
- {
520
- "$schema": "https://proj.org/schemas/#{schema_version}/projjson.schema.json",
521
- "type": "ProjectedCRS",
522
- "name": "NAD83 / UTM zone 15N",
523
- "base_crs": {
524
- "name": "NAD83",
525
- "datum": {
526
- "type": "GeodeticReferenceFrame",
527
- "name": "North American Datum 1983",
528
- "ellipsoid": {
529
- "name": "GRS 1980",
530
- "semi_major_axis": 6378137,
531
- "inverse_flattening": 298.257222101
532
- }
533
- },
534
- "coordinate_system": {
535
- "subtype": "ellipsoidal",
536
- "axis": [
537
- {
538
- "name": "Geodetic latitude",
539
- "abbreviation": "Lat",
540
- "direction": "north",
541
- "unit": "degree"
542
- },
543
- {
544
- "name": "Geodetic longitude",
545
- "abbreviation": "Lon",
546
- "direction": "east",
547
- "unit": "degree"
548
- }
549
- ]
550
- },
551
- "id": {
552
- "authority": "EPSG",
553
- "code": 4269
554
- }
555
- },
556
- "conversion": {
557
- "name": "UTM zone 15N",
558
- "method": {
559
- "name": "Transverse Mercator",
560
- "id": {
561
- "authority": "EPSG",
562
- "code": 9807
563
- }
564
- },
565
- "parameters": [
566
- {
567
- "name": "Latitude of natural origin",
568
- "value": 0,
569
- "unit": "degree",
570
- "id": {
571
- "authority": "EPSG",
572
- "code": 8801
573
- }
574
- },
575
- {
576
- "name": "Longitude of natural origin",
577
- "value": -93,
578
- "unit": "degree",
579
- "id": {
580
- "authority": "EPSG",
581
- "code": 8802
582
- }
583
- },
584
- {
585
- "name": "Scale factor at natural origin",
586
- "value": 0.9996,
587
- "unit": "unity",
588
- "id": {
589
- "authority": "EPSG",
590
- "code": 8805
591
- }
592
- },
593
- {
594
- "name": "False easting",
595
- "value": 500000,
596
- "unit": "metre",
597
- "id": {
598
- "authority": "EPSG",
599
- "code": 8806
600
- }
601
- },
602
- {
603
- "name": "False northing",
604
- "value": 0,
605
- "unit": "metre",
606
- "id": {
607
- "authority": "EPSG",
608
- "code": 8807
609
- }
610
- }
611
- ]
612
- },
613
- "coordinate_system": {
614
- "subtype": "Cartesian",
615
- "axis": [
616
- {
617
- "name": "Easting",
618
- "abbreviation": "E",
619
- "direction": "east",
620
- "unit": "metre"
621
- },
622
- {
623
- "name": "Northing",
624
- "abbreviation": "N",
625
- "direction": "north",
626
- "unit": "metre"
627
- }
628
- ]
629
- },
630
- "scope": "Engineering survey, topographic mapping.",
631
- "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.",
632
- "bbox": {
633
- "south_latitude": 25.61,
634
- "west_longitude": -96,
635
- "north_latitude": 84,
636
- "east_longitude": -90
637
- },
638
- "id": {
639
- "authority": "EPSG",
640
- "code": 26915
641
- }
642
- }
643
- EOS
644
-
645
- assert_equal(expected.strip, crs.to_json)
646
- end
647
-
648
- def test_to_wgs84
649
- wkt = <<~EOS
650
- BOUNDCRS[
651
- SOURCECRS[
652
- GEOGCRS["NTF (Paris)",
653
- DATUM["Nouvelle Triangulation Francaise (Paris)",
654
- ELLIPSOID["Clarke 1880 (IGN)",6378249.2,293.466021293627,
655
- LENGTHUNIT["metre",1]]],
656
- PRIMEM["Paris",2.5969213,
657
- ANGLEUNIT["grad",0.0157079632679489]],
658
- CS[ellipsoidal,2],
659
- AXIS["geodetic latitude (Lat)",north,
660
- ORDER[1],
661
- ANGLEUNIT["grad",0.0157079632679489]],
662
- AXIS["geodetic longitude (Lon)",east,
663
- ORDER[2],
664
- ANGLEUNIT["grad",0.0157079632679489]],
665
- USAGE[
666
- SCOPE["Geodesy."],
667
- AREA["France - onshore - mainland and Corsica."],
668
- BBOX[41.31,-4.87,51.14,9.63]],
669
- ID["EPSG",4807]]],
670
- TARGETCRS[
671
- GEOGCRS["WGS 84",
672
- DATUM["World Geodetic System 1984",
673
- ELLIPSOID["WGS 84",6378137,298.257223563,
674
- LENGTHUNIT["metre",1]]],
675
- PRIMEM["Greenwich",0,
676
- ANGLEUNIT["degree",0.0174532925199433]],
677
- CS[ellipsoidal,2],
678
- AXIS["latitude",north,
679
- ORDER[1],
680
- ANGLEUNIT["degree",0.0174532925199433]],
681
- AXIS["longitude",east,
682
- ORDER[2],
683
- ANGLEUNIT["degree",0.0174532925199433]],
684
- ID["EPSG",4326]]],
685
- ABRIDGEDTRANSFORMATION["NTF to WGS 84 (1)",
686
- VERSION["IGN-Fra"],
687
- METHOD["Geocentric translations (geog2D domain)",
688
- ID["EPSG",9603]],
689
- PARAMETER["X-axis translation",-168,
690
- ID["EPSG",8605]],
691
- PARAMETER["Y-axis translation",-60,
692
- ID["EPSG",8606]],
693
- PARAMETER["Z-axis translation",320,
694
- ID["EPSG",8607]],
695
- USAGE[
696
- 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."],
697
- AREA["France - onshore - mainland and Corsica."],
698
- BBOX[41.31,-4.87,51.14,9.63]],
699
- ID["EPSG",1193],
700
- REMARK["These same parameter values are used to transform to ETRS89. See NTF to ETRS89 (1) (code 1651)."]]]
701
- EOS
702
-
703
- crs = Proj::Crs.new(wkt)
704
- operation = crs.coordinate_operation
705
- values = operation.to_wgs84
706
-
707
- expected = [-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0]
708
- assert_equal(expected, values)
709
- end
710
-
711
- def test_geographic
712
- context = Proj::Context.new
713
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
714
-
715
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
716
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
717
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
718
- coordinate_system: coordinate_system)
719
-
720
- crs_2 = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
721
- assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
722
- end
723
-
724
- def test_geographic_datum
725
- context = Proj::Context.new
726
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
727
- datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
728
- crs = Proj::Crs.create_geographic_from_datum(context, name: "WGS 84", datum: datum, coordinate_system: coordinate_system)
729
- end
730
-
731
- def test_geocentric
732
- context = Proj::Context.new
733
- crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
734
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
735
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
736
- angular_units: "Degree", angular_units_conv: 0.0174532925199433,
737
- linear_units: "Metre", linear_units_conv: 1.0)
738
-
739
- crs_2 = Proj::Crs.create_from_database("EPSG", "4978", :PJ_CATEGORY_CRS)
740
- assert(crs.equivalent_to?(crs_2, :PJ_COMP_EQUIVALENT))
741
- end
742
-
743
- def test_geocentric_datum
744
- context = Proj::Context.new
745
- crs = Proj::Crs.create_geocentric(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
746
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
747
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
748
- angular_units: "Degree", angular_units_conv: 0.0174532925199433,
749
- linear_units: "Metre", linear_units_conv: 1.0)
750
- datum = crs.datum
751
-
752
- geocentric_crs = Proj::Crs.create_geocentric_from_datum(context, name: "WGS 84", datum: datum,
753
- linear_units: "Metre", linear_units_conv: 1.0)
754
-
755
- assert(crs.equivalent_to?(geocentric_crs, :PJ_COMP_STRICT))
756
- end
757
-
758
- def test_vertical_crs_ex
759
- context = Proj::Context.new
760
-
761
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS (ftUS)",
762
- datum_name: "myVertDatum",
763
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
764
- geoid_model_name: "PROJ @foo.gtx",
765
- accuracy: 123)
766
- assert(vertical_crs)
767
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
768
- end
769
-
770
- def test_vertical_crs_ex_with_geog_crs
771
- context = Proj::Context.new
772
- # NAD83(2011) / UTM zone 11N
773
- horizontal_crs = Proj::Crs.create_from_database("EPSG", "6340", :PJ_CATEGORY_CRS)
774
-
775
- # WGS84
776
- wgs84 = Proj::Crs.new("EPSG:4979", context)
777
-
778
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
779
- datum_name: "myVertDatum",
780
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219,
781
- geoid_model_name: "PROJ @foo.gtx",
782
- geoid_geog_crs: wgs84)
783
- assert(vertical_crs)
784
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
785
- end
786
-
787
- def test_bound_vertical
788
- context = Proj::Context.new
789
- vertical_crs = Proj::Crs.create_vertical_ex(context, name: "myVertCRS",
790
- datum_name: "myVertDatum")
791
-
792
- crs_4979 = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
793
- bound = Proj::Crs.create_bound_vertical(context, vertical_crs: vertical_crs,
794
- hub_crs: crs_4979, grid_name: "foo.gtx")
795
-
796
- assert_equal(:PJ_TYPE_BOUND_CRS, bound.proj_type)
797
- assert_equal("myVertCRS", bound.name)
798
- end
799
-
800
- def test_compound
801
- context = Proj::Context.new
802
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
803
-
804
- horizontal_crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
805
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
806
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
807
- coordinate_system: coordinate_system)
808
-
809
- vertical_crs = Proj::Crs.create_vertical(context, name: "myVertCRS",
810
- datum_name: "myVertDatum",
811
- linear_units: "US survey foot", linear_units_conv: 0.304800609601219)
812
-
813
- assert(vertical_crs)
814
- assert_equal(:PJ_TYPE_VERTICAL_CRS, vertical_crs.proj_type)
815
- assert_equal("myVertCRS", vertical_crs.name)
816
-
817
- compound_crs = Proj::Crs.create_compound(context, name: "myCompoundCRS",
818
- horizontal_crs: horizontal_crs, vertical_crs: vertical_crs);
819
- assert(compound_crs)
820
- assert_equal(:PJ_TYPE_COMPOUND_CRS, compound_crs.proj_type)
821
- assert_equal("myCompoundCRS", compound_crs.name)
822
-
823
- crs = compound_crs.sub_crs(0)
824
- assert(crs.equivalent_to?(horizontal_crs, :PJ_COMP_STRICT))
825
-
826
- crs = compound_crs.sub_crs(1)
827
- assert(crs.equivalent_to?(vertical_crs, :PJ_COMP_STRICT))
828
- end
829
-
830
- def test_derived_geographic
831
- context = Proj::Context.new
832
- crs = Proj::Crs.create("EPSG:4326", context)
833
-
834
- conversion = Proj::Projection.pole_rotation_grib_convention(context, south_pole_lat_in_unrotated_crs: 2, south_pole_long_in_unrotated_crs: 3,
835
- axis_rotation: 4, angular_unit_name: "Degree", angular_unit_conversion_factor: 0.0174532925199433)
836
-
837
- coordinate_system = crs.coordinate_system
838
-
839
- # Wrong type of base_geographic_crs
840
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
841
- base_geographic_crs: conversion, conversion: conversion,
842
- coordinate_system: coordinate_system)
843
- refute(derived_crs)
844
-
845
- # Wrong type of conversion
846
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
847
- base_geographic_crs: crs, conversion: crs,
848
- coordinate_system: coordinate_system)
849
- refute(derived_crs)
850
-
851
- derived_crs = Proj::Crs.create_derived_geographic(context, name: "my rotated CRS",
852
- base_geographic_crs: crs, conversion: conversion,
853
- coordinate_system: coordinate_system)
854
- refute(crs.derived?)
855
- assert(derived_crs.derived?)
856
-
857
- expected = "+proj=ob_tran +o_proj=longlat +o_lon_p=-4 +o_lat_p=-2 +lon_0=3 +datum=WGS84 +no_defs +type=crs"
858
- assert_equal(expected, derived_crs.to_proj_string)
859
- end
860
-
861
- def test_projected
862
- context = Proj::Context.new
863
- param = Proj::Parameter.new(name: "param name", value: 0.99,
864
- unit_conv_factor: 1.0, unit_type: :PJ_UT_SCALE)
865
-
866
- conversion = Proj::Conversion.create_conversion(context, name: "conv",
867
- auth_name: "conv auth", code: "conv code",
868
- method_name: "method", method_auth_name: "method auth", method_code: "method code",
869
- params: [param])
870
-
871
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LONGITUDE_LATITUDE, context)
872
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984",
873
- ellipsoid_name: "WGS 84", semi_major_meter: 6378137, inv_flattening: 298.257223563,
874
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0,
875
- pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
876
- coordinate_system: coordinate_system)
877
-
878
- cartesian = Proj::CoordinateSystem.create_cartesian_2d(context, :PJ_CART2D_EASTING_NORTHING)
879
-
880
- projected = Proj::Crs.create_projected(context, name: "My Projected CRS", geodetic_crs: crs,
881
- conversion: conversion, coordinate_system: cartesian)
882
- assert_equal(:PJ_TYPE_PROJECTED_CRS, projected.proj_type)
883
- assert_equal("My Projected CRS", projected.name)
884
- end
885
-
886
- def test_create_bound_crs_to_wgs84
887
- context = Proj::Context.new
888
- crs = Proj::Crs.create_from_database("EPSG", "4807", :PJ_CATEGORY_CRS)
889
-
890
- bounded = Proj::Crs.create_bound_to_wgs84(context, crs: crs)
891
- expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
892
- assert_equal(expected, bounded.to_proj_string)
893
-
894
- base_crs = bounded.source_crs
895
- assert(base_crs.equivalent_to?(crs, :PJ_COMP_EQUIVALENT))
896
-
897
- hub_crs = bounded.target_crs
898
- wgs84_crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
899
- assert(hub_crs.equivalent_to?(wgs84_crs, :PJ_COMP_EQUIVALENT))
900
-
901
- transform = bounded.coordinate_operation
902
- values = transform.to_wgs84(true)
903
- expected = [-168, -60, 320, 0, 0, 0, 0]
904
- assert_equal(expected, values)
905
-
906
- bounded_2 = Proj::Crs.create_bound(context, base_crs: base_crs, hub_crs: hub_crs, transformation: transform)
907
- assert_equal(:PJ_TYPE_BOUND_CRS, bounded_2.proj_type)
908
- expected = "+proj=longlat +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +no_defs +type=crs"
909
- assert_equal(expected, bounded_2.to_proj_string)
910
- end
911
-
912
- def test_create_engineering
913
- context = Proj::Context.new
914
- crs = Proj::Crs.create_engineering("EPSG", name: "4807")
915
- assert_equal("4807", crs.name)
916
- assert_equal(:PJ_TYPE_ENGINEERING_CRS, crs.proj_type)
917
-
918
- expected = <<~EOS
919
- LOCAL_CS["name",
920
- UNIT["metre",1,
921
- AUTHORITY["EPSG","9001"]],
922
- AXIS["Easting",EAST],
923
- AXIS["Northing",NORTH]]
924
- EOS
925
-
926
- # This crashes proj
927
- #assert_equal(expected, crs.to_wkt(:PJ_WKT1_GDAL))
928
- end
929
-
930
- def test_query_geodetic_from_datum
931
- context = Proj::Context.new
932
- crses = Proj::Crs.query_geodetic_from_datum(context, datum_auth_name: "EPSG", datum_code: "6326")
933
-
934
- expected = case
935
- when Proj::Api::PROJ_VERSION >= '9.0.0'
936
- 12
937
- else
938
- 11
939
- end
940
-
941
- assert_equal(expected, crses.size)
942
-
943
- crses = Proj::Crs.query_geodetic_from_datum(context, auth_name: "EPSG",
944
- datum_auth_name: "EPSG", datum_code: "6326",
945
- crs_type: "geographic 2D")
946
- assert_equal(1, crses.size)
947
- end
948
-
949
- def test_alter_name
950
- context = Proj::Context.new
951
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
952
-
953
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
954
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
955
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
956
- coordinate_system: coordinate_system)
957
- assert_equal("WGS 84", crs.name)
958
-
959
- altered = crs.alter_name("new name")
960
- assert_equal("WGS 84", crs.name)
961
- assert_equal("new name", altered.name)
962
- end
963
-
964
- def test_alter_id
965
- context = Proj::Context.new
966
- coordinate_system = Proj::CoordinateSystem.create_ellipsoidal_2d(:PJ_ELLPS2D_LATITUDE_LONGITUDE, context)
967
-
968
- crs = Proj::Crs.create_geographic(context, name: "WGS 84", datum_name: "World Geodetic System 1984", ellipsoid_name: "WGS 84",
969
- semi_major_meter: 6378137, inv_flattening: 298.257223563,
970
- prime_meridian_name: "Greenwich", prime_meridian_offset: 0.0, pm_angular_units: "Degree", pm_angular_units_conv: 0.0174532925199433,
971
- coordinate_system: coordinate_system)
972
- refute(crs.auth)
973
-
974
- altered = crs.alter_id("auth", "code")
975
- refute(crs.auth)
976
- assert_equal("auth:code", altered.auth)
977
- end
978
-
979
- def test_alter_geodetic_crs
980
- context = Proj::Context.new
981
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
982
- geod_crs = projected.geodetic_crs
983
- new_geod_crs = Proj::Crs.new("+proj=longlat +type=crs", context)
984
-
985
- altered = geod_crs.alter_geodetic_crs(new_geod_crs)
986
- assert(altered.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
987
-
988
- altered = projected.alter_geodetic_crs(new_geod_crs)
989
- assert_equal(:PJ_TYPE_PROJECTED_CRS, altered.proj_type)
990
- assert(altered.geodetic_crs.equivalent_to?(new_geod_crs, :PJ_COMP_STRICT))
991
- end
992
-
993
- def test_alter_cs_angular_unit
994
- context = Proj::Context.new
995
- crs = Proj::Crs.new('EPSG:4326')
996
- altered = crs.alter_cs_angular_unit(angular_units: "my unit", angular_units_conv: 2,
997
- unit_auth_name: "my auth", unit_code: "my code")
998
-
999
- cs = altered.coordinate_system
1000
- assert_equal(2, cs.axis_count)
1001
-
1002
- axis = cs.axis_info(0)
1003
- assert_equal("my unit", axis.unit_name)
1004
- assert_equal(2, axis.unit_conv_factor)
1005
- assert_equal("my auth", axis.unit_auth_name)
1006
- assert_equal("my code", axis.unit_code)
1007
- end
1008
-
1009
- def test_alter_alter_cs_linear_unit
1010
- context = Proj::Context.new
1011
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1012
- altered = projected.alter_cs_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1013
- unit_auth_name: "my auth", unit_code: "my code")
1014
-
1015
- cs = altered.coordinate_system
1016
- assert_equal(2, cs.axis_count)
1017
-
1018
- axis = cs.axis_info(0)
1019
- assert_equal("my unit", axis.unit_name)
1020
- assert_equal(2, axis.unit_conv_factor)
1021
- assert_equal("my auth", axis.unit_auth_name)
1022
- assert_equal("my code", axis.unit_code)
1023
- end
1024
-
1025
- def test_alter_parameters_linear_unit
1026
- context = Proj::Context.new
1027
- projected = Proj::Crs.create_from_database("EPSG", "32631", :PJ_CATEGORY_CRS)
1028
- altered = projected.alter_parameters_linear_unit(linear_units: "my unit", linear_units_conv: 2,
1029
- convert_to_new_unit: false)
1030
-
1031
- wkt = altered.to_wkt
1032
- assert_match(/500000/, wkt)
1033
- assert_match(/"my unit",2/, wkt)
1034
- end
1035
-
1036
- def test_promote_to_3d
1037
- context = Proj::Context.new
1038
- crs = Proj::Crs.new('EPSG:4326')
1039
-
1040
- crs_3d = crs.promote_to_3d
1041
- assert_equal("4979", crs_3d.id_code)
1042
-
1043
- cs = crs_3d.coordinate_system
1044
- assert_equal(3, cs.axis_count)
1045
- end
1046
-
1047
- def test_demote_to_3d
1048
- context = Proj::Context.new
1049
- crs = Proj::Crs.new('EPSG:4979')
1050
-
1051
- crs_2d = crs.demote_to_2d
1052
- assert_equal("4326", crs_2d.id_code)
1053
-
1054
- cs = crs_2d.coordinate_system
1055
- assert_equal(2, cs.axis_count)
1056
- end
1057
-
1058
- def test_projected_3d_with_base
1059
- context = Proj::Context.new
1060
- projected = Proj::Crs.new('EPSG:32631')
1061
- base_crs_3d = Proj::Crs.create_from_database("EPSG", "4979", :PJ_CATEGORY_CRS)
1062
-
1063
- crs_3d = projected.projected_3d(geog_3d_crs: base_crs_3d)
1064
- assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1065
- assert_equal(crs_3d.name, projected.name)
1066
-
1067
- cs = crs_3d.coordinate_system
1068
- assert_equal(3, cs.axis_count)
1069
- end
1070
-
1071
- def test_projected_3d_without_base
1072
- context = Proj::Context.new
1073
- projected = Proj::Crs.new('EPSG:32631')
1074
-
1075
- crs_3d = projected.projected_3d
1076
- assert_equal(:PJ_TYPE_PROJECTED_CRS, crs_3d.proj_type)
1077
- assert_equal(crs_3d.name, projected.name)
1078
-
1079
- cs = crs_3d.coordinate_system
1080
- assert_equal(3, cs.axis_count)
1081
- end
1082
- 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