proj4rb 2.2.2 → 4.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +82 -66
  3. data/Gemfile +4 -4
  4. data/README.rdoc +82 -45
  5. data/lib/api/api.rb +96 -111
  6. data/lib/api/api_5_0.rb +331 -300
  7. data/lib/api/api_5_1.rb +6 -6
  8. data/lib/api/api_5_2.rb +4 -4
  9. data/lib/api/api_6_0.rb +116 -14
  10. data/lib/api/api_6_1.rb +4 -4
  11. data/lib/api/api_6_2.rb +9 -6
  12. data/lib/api/api_6_3.rb +6 -0
  13. data/lib/api/api_7_0.rb +68 -0
  14. data/lib/api/api_7_1.rb +73 -0
  15. data/lib/api/api_7_2.rb +14 -0
  16. data/lib/api/api_8_0.rb +6 -0
  17. data/lib/api/api_8_1.rb +24 -0
  18. data/lib/api/api_8_2.rb +6 -0
  19. data/lib/api/api_9_1.rb +7 -0
  20. data/lib/api/api_9_2.rb +9 -0
  21. data/lib/api/api_experimental.rb +196 -0
  22. data/lib/proj/area.rb +73 -0
  23. data/lib/proj/axis_info.rb +44 -0
  24. data/lib/proj/bounds.rb +13 -0
  25. data/lib/proj/context.rb +249 -0
  26. data/lib/proj/conversion.rb +92 -0
  27. data/lib/{coordinate.rb → proj/coordinate.rb} +281 -197
  28. data/lib/proj/coordinate_operation_mixin.rb +381 -0
  29. data/lib/proj/coordinate_system.rb +137 -0
  30. data/lib/proj/crs.rb +672 -0
  31. data/lib/proj/crs_info.rb +47 -0
  32. data/lib/proj/database.rb +305 -0
  33. data/lib/proj/datum.rb +32 -0
  34. data/lib/proj/datum_ensemble.rb +34 -0
  35. data/lib/proj/ellipsoid.rb +78 -0
  36. data/lib/proj/error.rb +71 -0
  37. data/lib/proj/file_api.rb +166 -0
  38. data/lib/proj/grid.rb +121 -0
  39. data/lib/proj/grid_cache.rb +64 -0
  40. data/lib/proj/grid_info.rb +19 -0
  41. data/lib/proj/network_api.rb +92 -0
  42. data/lib/{operation.rb → proj/operation.rb} +42 -42
  43. data/lib/proj/operation_factory_context.rb +136 -0
  44. data/lib/proj/parameter.rb +38 -0
  45. data/lib/proj/parameters.rb +106 -0
  46. data/lib/proj/pj_object.rb +670 -0
  47. data/lib/proj/pj_objects.rb +44 -0
  48. data/lib/proj/prime_meridian.rb +66 -0
  49. data/lib/proj/projection.rb +698 -0
  50. data/lib/proj/session.rb +46 -0
  51. data/lib/proj/strings.rb +32 -0
  52. data/lib/proj/transformation.rb +102 -0
  53. data/lib/proj/unit.rb +109 -0
  54. data/lib/proj.rb +118 -17
  55. data/proj4rb.gemspec +32 -32
  56. data/test/abstract_test.rb +29 -7
  57. data/test/context_test.rb +172 -82
  58. data/test/conversion_test.rb +368 -0
  59. data/test/coordinate_system_test.rb +144 -0
  60. data/test/coordinate_test.rb +34 -34
  61. data/test/crs_test.rb +1071 -372
  62. data/test/database_test.rb +360 -0
  63. data/test/datum_ensemble_test.rb +65 -0
  64. data/test/datum_test.rb +55 -0
  65. data/test/ellipsoid_test.rb +80 -34
  66. data/test/file_api_test.rb +66 -0
  67. data/test/grid_cache_test.rb +72 -0
  68. data/test/grid_test.rb +141 -0
  69. data/test/network_api_test.rb +45 -0
  70. data/test/operation_factory_context_test.rb +201 -0
  71. data/test/operation_test.rb +29 -29
  72. data/test/parameters_test.rb +40 -0
  73. data/test/pj_object_test.rb +179 -0
  74. data/test/prime_meridian_test.rb +76 -0
  75. data/test/proj_test.rb +58 -16
  76. data/test/projection_test.rb +650 -224
  77. data/test/session_test.rb +78 -0
  78. data/test/transformation_test.rb +209 -67
  79. data/test/unit_test.rb +76 -47
  80. metadata +67 -29
  81. data/lib/api/api_4_9.rb +0 -31
  82. data/lib/area.rb +0 -32
  83. data/lib/config.rb +0 -70
  84. data/lib/context.rb +0 -103
  85. data/lib/crs.rb +0 -204
  86. data/lib/ellipsoid.rb +0 -42
  87. data/lib/error.rb +0 -18
  88. data/lib/pj_object.rb +0 -80
  89. data/lib/point.rb +0 -72
  90. data/lib/prime_meridian.rb +0 -40
  91. data/lib/projection.rb +0 -207
  92. data/lib/transformation.rb +0 -61
  93. data/lib/unit.rb +0 -54
  94. data/test/prime_meridians_test.rb +0 -33
data/test/crs_test.rb CHANGED
@@ -1,373 +1,1072 @@
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_proj4
51
- crs = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
52
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs.proj_type)
53
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', crs.to_proj_string)
54
- end
55
-
56
- def test_compound
57
- crs = Proj::Crs.new('EPSG:2393+5717')
58
- assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
59
- 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)
60
-
61
- crs = Proj::Crs.new('urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717')
62
- assert_equal(:PJ_TYPE_COMPOUND_CRS, crs.proj_type)
63
- 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)
64
- end
65
-
66
- def test_not_crs
67
- error = assert_raises(Proj::Error) do
68
- Proj::Crs.new('+proj=utm +zone=32 +datum=WGS84')
69
- end
70
- assert_equal('Invalid crs definition. Proj created an instance of: PJ_TYPE_OTHER_COORDINATE_OPERATION.', error.message)
71
- end
72
-
73
- def test_finalize
74
- 500.times do
75
- crs = Proj::Crs.new('EPSG:4326')
76
- assert(crs.to_ptr)
77
- GC.start
78
- end
79
- assert(true)
80
- end
81
-
82
- def test_geodetic_crs
83
- crs = Proj::Crs.new('EPSG:4326')
84
- geodetic = crs.geodetic_crs
85
- assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, geodetic.proj_type)
86
- assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', geodetic.to_proj_string)
87
- end
88
-
89
- def test_datum
90
- crs = Proj::Crs.new('EPSG:4326')
91
- datum = crs.datum
92
- assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, datum.proj_type)
93
- end
94
-
95
- def test_horizontal_datum
96
- crs = Proj::Crs.new('EPSG:4326')
97
- datum = crs.horizontal_datum
98
- assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, datum.proj_type)
99
- end
100
-
101
- def test_coordinate_system
102
- crs = Proj::Crs.new('EPSG:4326')
103
- cs = crs.coordinate_system
104
- assert_equal(:PJ_TYPE_UNKNOWN, cs.proj_type)
105
- end
106
-
107
- def test_axis_count
108
- crs = Proj::Crs.new('EPSG:4326')
109
- count = crs.axis_count
110
- assert_equal(2, count)
111
- end
112
-
113
- def test_axis_info
114
- crs = Proj::Crs.new('EPSG:4326')
115
- info = crs.axis_info
116
- expected = [{:name=>"Geodetic latitude",
117
- :abbreviation=>"Lat",
118
- :direction=>"north",
119
- :unit_conv_factor=>0.017453292519943295,
120
- :unit_name=>"degree",
121
- :unit_auth_name=>"EPSG",
122
- :unit_code=>"9122"},
123
- {:name=>"Geodetic longitude",
124
- :abbreviation=>"Lon",
125
- :direction=>"east",
126
- :unit_conv_factor=>0.017453292519943295,
127
- :unit_name=>"degree",
128
- :unit_auth_name=>"EPSG",
129
- :unit_code=>"9122"}]
130
-
131
- assert_equal(expected, info)
132
- end
133
-
134
- def test_crs_type
135
- crs = Proj::Crs.new('EPSG:4326')
136
- crs_type = crs.crs_type
137
- assert_equal(:PJ_CS_TYPE_ELLIPSOIDAL, crs_type)
138
- end
139
-
140
- def test_ellipsoid
141
- crs = Proj::Crs.new('EPSG:4326')
142
- ellipsoid = crs.ellipsoid
143
- assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
144
- end
145
-
146
- def test_prime_meridian
147
- crs = Proj::Crs.new('EPSG:4326')
148
- prime_meridian = crs.prime_meridian
149
- assert_equal('Greenwich', prime_meridian.name)
150
- end
151
-
152
- #def test_operation
153
- # crs = Proj::Crs.new('EPSG:4326')
154
- # operation = crs.operation
155
- # assert_equal('Greenwich', operation.name)
156
- #end
157
-
158
- def test_area
159
- crs = Proj::Crs.new('EPSG:4326')
160
- assert_kind_of(Proj::Area, crs.area)
161
- assert_equal('World', crs.area.name)
162
- assert_in_delta(-180.0, crs.area.west_lon_degree, 0.1)
163
- assert_in_delta(-90.0, crs.area.south_lat_degree, 0.1)
164
- assert_in_delta(180.0, crs.area.east_lon_degree, 0.1)
165
- assert_in_delta(90.0, crs.area.north_lat_degree, 0.1)
166
- end
167
-
168
- def test_to_proj_string
169
- crs = Proj::Crs.new('EPSG:26915')
170
- assert_equal('+proj=utm +zone=15 +datum=NAD83 +units=m +no_defs +type=crs', crs.to_proj_string)
171
- end
172
-
173
- def test_to_wkt
174
- crs = Proj::Crs.new('EPSG:26915')
175
-
176
- expected = <<~EOS
177
- PROJCRS["NAD83 / UTM zone 15N",
178
- BASEGEOGCRS["NAD83",
179
- DATUM["North American Datum 1983",
180
- ELLIPSOID["GRS 1980",6378137,298.257222101,
181
- LENGTHUNIT["metre",1]]],
182
- PRIMEM["Greenwich",0,
183
- ANGLEUNIT["degree",0.0174532925199433]],
184
- ID["EPSG",4269]],
185
- CONVERSION["UTM zone 15N",
186
- METHOD["Transverse Mercator",
187
- ID["EPSG",9807]],
188
- PARAMETER["Latitude of natural origin",0,
189
- ANGLEUNIT["degree",0.0174532925199433],
190
- ID["EPSG",8801]],
191
- PARAMETER["Longitude of natural origin",-93,
192
- ANGLEUNIT["degree",0.0174532925199433],
193
- ID["EPSG",8802]],
194
- PARAMETER["Scale factor at natural origin",0.9996,
195
- SCALEUNIT["unity",1],
196
- ID["EPSG",8805]],
197
- PARAMETER["False easting",500000,
198
- LENGTHUNIT["metre",1],
199
- ID["EPSG",8806]],
200
- PARAMETER["False northing",0,
201
- LENGTHUNIT["metre",1],
202
- ID["EPSG",8807]]],
203
- CS[Cartesian,2],
204
- AXIS["(E)",east,
205
- ORDER[1],
206
- LENGTHUNIT["metre",1]],
207
- AXIS["(N)",north,
208
- ORDER[2],
209
- LENGTHUNIT["metre",1]],
210
- USAGE[
211
- SCOPE["unknown"],
212
- AREA["North America - 96\xC2\xB0W to 90\xC2\xB0W and NAD83 by country"],
213
- BBOX[25.61,-96,84,-90]],
214
- ID["EPSG",26915]]
215
- EOS
216
-
217
- assert_equal(expected.strip, crs.to_wkt)
218
- end
219
-
220
- def test_to_json
221
- crs = Proj::Crs.new('EPSG:26915')
222
- expected = <<~EOS
223
- {
224
- "$schema": "https://proj.org/schemas/v0.1/projjson.schema.json",
225
- "type": "ProjectedCRS",
226
- "name": "NAD83 / UTM zone 15N",
227
- "base_crs": {
228
- "name": "NAD83",
229
- "datum": {
230
- "type": "GeodeticReferenceFrame",
231
- "name": "North American Datum 1983",
232
- "ellipsoid": {
233
- "name": "GRS 1980",
234
- "semi_major_axis": 6378137,
235
- "inverse_flattening": 298.257222101
236
- }
237
- },
238
- "coordinate_system": {
239
- "subtype": "ellipsoidal",
240
- "axis": [
241
- {
242
- "name": "Geodetic latitude",
243
- "abbreviation": "Lat",
244
- "direction": "north",
245
- "unit": "degree"
246
- },
247
- {
248
- "name": "Geodetic longitude",
249
- "abbreviation": "Lon",
250
- "direction": "east",
251
- "unit": "degree"
252
- }
253
- ]
254
- },
255
- "id": {
256
- "authority": "EPSG",
257
- "code": 4269
258
- }
259
- },
260
- "conversion": {
261
- "name": "UTM zone 15N",
262
- "method": {
263
- "name": "Transverse Mercator",
264
- "id": {
265
- "authority": "EPSG",
266
- "code": 9807
267
- }
268
- },
269
- "parameters": [
270
- {
271
- "name": "Latitude of natural origin",
272
- "value": 0,
273
- "unit": "degree",
274
- "id": {
275
- "authority": "EPSG",
276
- "code": 8801
277
- }
278
- },
279
- {
280
- "name": "Longitude of natural origin",
281
- "value": -93,
282
- "unit": "degree",
283
- "id": {
284
- "authority": "EPSG",
285
- "code": 8802
286
- }
287
- },
288
- {
289
- "name": "Scale factor at natural origin",
290
- "value": 0.9996,
291
- "unit": "unity",
292
- "id": {
293
- "authority": "EPSG",
294
- "code": 8805
295
- }
296
- },
297
- {
298
- "name": "False easting",
299
- "value": 500000,
300
- "unit": "metre",
301
- "id": {
302
- "authority": "EPSG",
303
- "code": 8806
304
- }
305
- },
306
- {
307
- "name": "False northing",
308
- "value": 0,
309
- "unit": "metre",
310
- "id": {
311
- "authority": "EPSG",
312
- "code": 8807
313
- }
314
- }
315
- ]
316
- },
317
- "coordinate_system": {
318
- "subtype": "Cartesian",
319
- "axis": [
320
- {
321
- "name": "Easting",
322
- "abbreviation": "E",
323
- "direction": "east",
324
- "unit": "metre"
325
- },
326
- {
327
- "name": "Northing",
328
- "abbreviation": "N",
329
- "direction": "north",
330
- "unit": "metre"
331
- }
332
- ]
333
- },
334
- "area": "North America - 96°W to 90°W and NAD83 by country",
335
- "bbox": {
336
- "south_latitude": 25.61,
337
- "west_longitude": -96,
338
- "north_latitude": 84,
339
- "east_longitude": -90
340
- },
341
- "id": {
342
- "authority": "EPSG",
343
- "code": 26915
344
- }
345
- }
346
- EOS
347
-
348
- assert_equal(expected.strip, crs.to_json)
349
- end
350
-
351
- def test_inspect
352
- crs = Proj::Crs.new('EPSG:26915')
353
-
354
- expected = <<~EOS
355
- <Proj::Crs>: EPSG:26915
356
- NAD83 / UTM zone 15N
357
- Axis Info [PJ_CS_TYPE_CARTESIAN]:
358
- - E[east]: Easting (metre)
359
- - N[north]: Northing (metre)
360
- Area of Use:
361
- - name: North America - 96°W to 90°W and NAD83 by country
362
- - bounds: (-96.0, 25.61, -90.0, 84.0)
363
- Coordinate operation:
364
- - name: ?
365
- - method: ?
366
- Datum: North American Datum 1983
367
- - Ellipsoid: GRS 1980
368
- - Prime Meridian: Greenwich
369
- EOS
370
-
371
- assert_equal(expected, crs.inspect)
372
- 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.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", ellps_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_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", ellps_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", ellps_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", ellps_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_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
+ ellps_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_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", ellps_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_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", ellps_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_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
373
1072
  end