proj4rb 4.1.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/Gemfile +4 -4
  4. data/README.md +53 -0
  5. data/lib/api/proj.rb +750 -0
  6. data/lib/api/proj_experimental.rb +7 -0
  7. data/lib/api/proj_ffi.rb +47 -0
  8. data/lib/api/proj_version.rb +26 -0
  9. data/lib/examples/axis_order_normalization.rb +13 -0
  10. data/lib/examples/batch_transformation.rb +25 -0
  11. data/lib/examples/context_logging.rb +26 -0
  12. data/lib/examples/crs_identification.rb +18 -0
  13. data/lib/examples/database_query.rb +27 -0
  14. data/lib/examples/geodetic_distance.rb +38 -0
  15. data/lib/examples/geodetic_to_projected.rb +18 -0
  16. data/lib/examples/operation_factory_context.rb +19 -0
  17. data/lib/examples/pipeline_operator.rb +21 -0
  18. data/lib/examples/promote_demote_3d.rb +23 -0
  19. data/lib/examples/serialization_formats.rb +17 -0
  20. data/lib/examples/transform_bounds.rb +18 -0
  21. data/lib/examples/transformation_with_area.rb +18 -0
  22. data/lib/proj/area.rb +74 -74
  23. data/lib/proj/axis_info.rb +44 -44
  24. data/lib/proj/bounds.rb +22 -0
  25. data/lib/proj/bounds3d.rb +45 -0
  26. data/lib/proj/context.rb +57 -23
  27. data/lib/proj/conversion.rb +94 -91
  28. data/lib/proj/coordinate.rb +304 -281
  29. data/lib/proj/coordinate_metadata.rb +38 -38
  30. data/lib/proj/coordinate_operation_mixin.rb +464 -381
  31. data/lib/proj/coordinate_system.rb +143 -137
  32. data/lib/proj/crs.rb +688 -680
  33. data/lib/proj/crs_info.rb +47 -47
  34. data/lib/proj/database.rb +310 -305
  35. data/lib/proj/datum.rb +32 -32
  36. data/lib/proj/datum_ensemble.rb +34 -34
  37. data/lib/proj/domain.rb +82 -0
  38. data/lib/proj/ellipsoid.rb +77 -77
  39. data/lib/proj/error.rb +7 -8
  40. data/lib/proj/file_api_callbacks.rb +165 -0
  41. data/lib/proj/grid.rb +121 -121
  42. data/lib/proj/grid_cache.rb +65 -64
  43. data/lib/proj/grid_info.rb +19 -19
  44. data/lib/proj/life_span.rb +21 -0
  45. data/lib/proj/network_api_callbacks.rb +86 -0
  46. data/lib/proj/operation.rb +66 -42
  47. data/lib/proj/operation_factory_context.rb +4 -2
  48. data/lib/proj/options.rb +41 -0
  49. data/lib/proj/parameter.rb +37 -37
  50. data/lib/proj/parameters.rb +106 -107
  51. data/lib/proj/pj_axis_description.rb +26 -0
  52. data/lib/proj/pj_object.rb +602 -672
  53. data/lib/proj/pj_objects.rb +45 -45
  54. data/lib/proj/pj_param_description.rb +28 -0
  55. data/lib/proj/prime_meridian.rb +65 -65
  56. data/lib/proj/projection.rb +54 -25
  57. data/lib/proj/session.rb +2 -0
  58. data/lib/proj/transformation.rb +102 -102
  59. data/lib/proj/unit.rb +81 -108
  60. data/lib/proj.rb +10 -3
  61. data/lib/proj4.rb +5 -5
  62. data/proj4rb.gemspec +10 -5
  63. data/test/abstract_test.rb +7 -5
  64. data/test/context_test.rb +210 -172
  65. data/test/context_validation_test.rb +11 -0
  66. data/test/conversion_test.rb +376 -368
  67. data/test/coordinate_metadata_test.rb +34 -0
  68. data/test/coordinate_system_test.rb +162 -144
  69. data/test/coordinate_test.rb +289 -34
  70. data/test/crs_test.rb +1112 -1082
  71. data/test/database_test.rb +407 -391
  72. data/test/datum_ensemble_test.rb +64 -64
  73. data/test/datum_test.rb +61 -54
  74. data/test/domain_test.rb +72 -0
  75. data/test/ellipsoid_test.rb +80 -80
  76. data/test/examples_test.rb +149 -0
  77. data/test/file_api_example.rb +58 -0
  78. data/test/file_api_test.rb +74 -66
  79. data/test/grid_cache_test.rb +72 -72
  80. data/test/grid_test.rb +126 -141
  81. data/test/network_api_example.rb +48 -0
  82. data/test/network_api_test.rb +33 -45
  83. data/test/operation_factory_context_test.rb +225 -205
  84. data/test/operation_test.rb +40 -29
  85. data/test/options_test.rb +17 -0
  86. data/test/parameters_test.rb +86 -40
  87. data/test/pj_object_test.rb +221 -187
  88. data/test/prime_meridian_test.rb +75 -75
  89. data/test/proj_test.rb +58 -58
  90. data/test/projection_test.rb +680 -650
  91. data/test/session_test.rb +78 -77
  92. data/test/transformation_test.rb +238 -210
  93. data/test/unit_test.rb +114 -76
  94. metadata +44 -32
  95. data/ChangeLog +0 -94
  96. data/README.rdoc +0 -189
  97. data/lib/api/api.rb +0 -117
  98. data/lib/api/api_5_0.rb +0 -338
  99. data/lib/api/api_5_1.rb +0 -7
  100. data/lib/api/api_5_2.rb +0 -5
  101. data/lib/api/api_6_0.rb +0 -146
  102. data/lib/api/api_6_1.rb +0 -5
  103. data/lib/api/api_6_2.rb +0 -10
  104. data/lib/api/api_6_3.rb +0 -6
  105. data/lib/api/api_7_0.rb +0 -69
  106. data/lib/api/api_7_1.rb +0 -73
  107. data/lib/api/api_7_2.rb +0 -14
  108. data/lib/api/api_8_0.rb +0 -6
  109. data/lib/api/api_8_1.rb +0 -24
  110. data/lib/api/api_8_2.rb +0 -6
  111. data/lib/api/api_9_1.rb +0 -7
  112. data/lib/api/api_9_2.rb +0 -9
  113. data/lib/api/api_9_4.rb +0 -6
  114. data/lib/api/api_experimental.rb +0 -201
  115. data/lib/proj/file_api.rb +0 -166
  116. data/lib/proj/network_api.rb +0 -92
@@ -1,65 +1,65 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class DatumEnsembleTest < AbstractTest
6
- def get_datum_ensemble
7
- wkt = <<~EOS
8
- GEOGCRS["ETRS89",
9
- ENSEMBLE["European Terrestrial Reference System 1989 ensemble",
10
- MEMBER["European Terrestrial Reference Frame 1989"],
11
- MEMBER["European Terrestrial Reference Frame 1990"],
12
- MEMBER["European Terrestrial Reference Frame 1991"],
13
- MEMBER["European Terrestrial Reference Frame 1992"],
14
- MEMBER["European Terrestrial Reference Frame 1993"],
15
- MEMBER["European Terrestrial Reference Frame 1994"],
16
- MEMBER["European Terrestrial Reference Frame 1996"],
17
- MEMBER["European Terrestrial Reference Frame 1997"],
18
- MEMBER["European Terrestrial Reference Frame 2000"],
19
- MEMBER["European Terrestrial Reference Frame 2005"],
20
- MEMBER["European Terrestrial Reference Frame 2014"],
21
- ELLIPSOID["GRS 1980",6378137,298.257222101,
22
- LENGTHUNIT["metre",1]],
23
- ENSEMBLEACCURACY[0.1]],
24
- PRIMEM["Greenwich",0,
25
- ANGLEUNIT["degree",0.0174532925199433]],
26
- CS[ellipsoidal,2],
27
- AXIS["geodetic latitude (Lat)",north,
28
- ORDER[1],
29
- ANGLEUNIT["degree",0.0174532925199433]],
30
- AXIS["geodetic longitude (Lon)",east,
31
- ORDER[2],
32
- ANGLEUNIT["degree",0.0174532925199433]]]
33
- EOS
34
-
35
- crs = Proj::Crs.create(wkt)
36
- crs.datum_ensemble
37
- end
38
-
39
- def test_count
40
- ensemble = get_datum_ensemble
41
- assert_equal(11, ensemble.count)
42
- end
43
-
44
- def test_member
45
- ensemble = get_datum_ensemble
46
-
47
- member = ensemble[0]
48
- assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, member.proj_type)
49
- assert_equal("European Terrestrial Reference Frame 1989", member.name)
50
- end
51
-
52
- def test_member_invalid
53
- ensemble = get_datum_ensemble
54
- member = ensemble[-1]
55
- refute(member)
56
-
57
- member = ensemble[100]
58
- refute(member)
59
- end
60
-
61
- def test_accuracy
62
- ensemble = get_datum_ensemble
63
- assert_equal(0.1, ensemble.accuracy)
64
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class DatumEnsembleTest < AbstractTest
6
+ def get_datum_ensemble
7
+ wkt = <<~EOS
8
+ GEOGCRS["ETRS89",
9
+ ENSEMBLE["European Terrestrial Reference System 1989 ensemble",
10
+ MEMBER["European Terrestrial Reference Frame 1989"],
11
+ MEMBER["European Terrestrial Reference Frame 1990"],
12
+ MEMBER["European Terrestrial Reference Frame 1991"],
13
+ MEMBER["European Terrestrial Reference Frame 1992"],
14
+ MEMBER["European Terrestrial Reference Frame 1993"],
15
+ MEMBER["European Terrestrial Reference Frame 1994"],
16
+ MEMBER["European Terrestrial Reference Frame 1996"],
17
+ MEMBER["European Terrestrial Reference Frame 1997"],
18
+ MEMBER["European Terrestrial Reference Frame 2000"],
19
+ MEMBER["European Terrestrial Reference Frame 2005"],
20
+ MEMBER["European Terrestrial Reference Frame 2014"],
21
+ ELLIPSOID["GRS 1980",6378137,298.257222101,
22
+ LENGTHUNIT["metre",1]],
23
+ ENSEMBLEACCURACY[0.1]],
24
+ PRIMEM["Greenwich",0,
25
+ ANGLEUNIT["degree",0.0174532925199433]],
26
+ CS[ellipsoidal,2],
27
+ AXIS["geodetic latitude (Lat)",north,
28
+ ORDER[1],
29
+ ANGLEUNIT["degree",0.0174532925199433]],
30
+ AXIS["geodetic longitude (Lon)",east,
31
+ ORDER[2],
32
+ ANGLEUNIT["degree",0.0174532925199433]]]
33
+ EOS
34
+
35
+ crs = Proj::Crs.create(wkt)
36
+ crs.datum_ensemble
37
+ end
38
+
39
+ def test_count
40
+ ensemble = get_datum_ensemble
41
+ assert_equal(11, ensemble.count)
42
+ end
43
+
44
+ def test_member
45
+ ensemble = get_datum_ensemble
46
+
47
+ member = ensemble[0]
48
+ assert_equal(:PJ_TYPE_GEODETIC_REFERENCE_FRAME, member.proj_type)
49
+ assert_equal("European Terrestrial Reference Frame 1989", member.name)
50
+ end
51
+
52
+ def test_member_invalid
53
+ ensemble = get_datum_ensemble
54
+ member = ensemble[-1]
55
+ refute(member)
56
+
57
+ member = ensemble[100]
58
+ refute(member)
59
+ end
60
+
61
+ def test_accuracy
62
+ ensemble = get_datum_ensemble
63
+ assert_equal(0.1, ensemble.accuracy)
64
+ end
65
65
  end
data/test/datum_test.rb CHANGED
@@ -1,55 +1,62 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class DatumTest < AbstractTest
6
- def test_datum
7
- datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
8
- assert_equal(:PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME, datum.proj_type)
9
- assert_equal("International Terrestrial Reference Frame 2008", datum.name)
10
- end
11
-
12
- def test_frame_reference_epoch
13
- datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
14
- epoch = datum.frame_reference_epoch
15
- assert_equal(2005.0, epoch)
16
- end
17
-
18
- def test_ellipsoid
19
- wkt = <<~EOS
20
- PROJCS["WGS 84 / UTM zone 31N",
21
- GEOGCS["WGS 84",
22
- DATUM["WGS_1984",
23
- SPHEROID["WGS 84",6378137,298.257223563,
24
- AUTHORITY["EPSG","7030"]],
25
- AUTHORITY["EPSG","6326"]],
26
- PRIMEM["Greenwich",0,
27
- AUTHORITY["EPSG","8901"]],
28
- UNIT["degree",0.0174532925199433,
29
- AUTHORITY["EPSG","9122"]],
30
- AUTHORITY["EPSG","4326"]],
31
- PROJECTION["Transverse_Mercator"],
32
- PARAMETER["latitude_of_origin",0],
33
- PARAMETER["central_meridian",3],
34
- PARAMETER["scale_factor",0.9996],
35
- PARAMETER["false_easting",500000],
36
- PARAMETER["false_northing",0],
37
- UNIT["metre",1,
38
- AUTHORITY["EPSG","9001"]],
39
- AXIS["Easting",EAST],
40
- AXIS["Northing",NORTH],
41
- AUTHORITY["EPSG","32631"]]
42
- EOS
43
-
44
- crs = Proj::Crs.new(wkt)
45
- ellipsoid = crs.ellipsoid
46
- assert_equal("WGS 84", ellipsoid.name)
47
- assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
48
-
49
- ellipsoid_from_datum = crs.datum.ellipsoid
50
- assert_equal("WGS 84", ellipsoid_from_datum.name)
51
- assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid_from_datum.proj_type)
52
-
53
- assert(ellipsoid_from_datum.equivalent_to?(ellipsoid, :PJ_COMP_STRICT))
54
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class DatumTest < AbstractTest
6
+ def test_datum
7
+ datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
8
+ assert_equal(:PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME, datum.proj_type)
9
+ assert_equal("International Terrestrial Reference Frame 2008", datum.name)
10
+ end
11
+
12
+ def test_frame_reference_epoch
13
+ datum = Proj::PjObject.create_from_database("EPSG", "1061", :PJ_CATEGORY_DATUM)
14
+ epoch = datum.frame_reference_epoch
15
+ assert_equal(2005.0, epoch)
16
+ end
17
+
18
+ def test_ellipsoid
19
+ wkt = <<~EOS
20
+ PROJCS["WGS 84 / UTM zone 31N",
21
+ GEOGCS["WGS 84",
22
+ DATUM["WGS_1984",
23
+ SPHEROID["WGS 84",6378137,298.257223563,
24
+ AUTHORITY["EPSG","7030"]],
25
+ AUTHORITY["EPSG","6326"]],
26
+ PRIMEM["Greenwich",0,
27
+ AUTHORITY["EPSG","8901"]],
28
+ UNIT["degree",0.0174532925199433,
29
+ AUTHORITY["EPSG","9122"]],
30
+ AUTHORITY["EPSG","4326"]],
31
+ PROJECTION["Transverse_Mercator"],
32
+ PARAMETER["latitude_of_origin",0],
33
+ PARAMETER["central_meridian",3],
34
+ PARAMETER["scale_factor",0.9996],
35
+ PARAMETER["false_easting",500000],
36
+ PARAMETER["false_northing",0],
37
+ UNIT["metre",1,
38
+ AUTHORITY["EPSG","9001"]],
39
+ AXIS["Easting",EAST],
40
+ AXIS["Northing",NORTH],
41
+ AUTHORITY["EPSG","32631"]]
42
+ EOS
43
+
44
+ crs = Proj::Crs.new(wkt)
45
+ ellipsoid = crs.ellipsoid
46
+ assert_equal("WGS 84", ellipsoid.name)
47
+ assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
48
+
49
+ ellipsoid_from_datum = crs.datum.ellipsoid
50
+ assert_equal("WGS 84", ellipsoid_from_datum.name)
51
+ assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid_from_datum.proj_type)
52
+
53
+ assert(ellipsoid_from_datum.equivalent_to?(ellipsoid, :PJ_COMP_STRICT))
54
+ end
55
+
56
+ def test_prime_meridian
57
+ datum = Proj::PjObject.create_from_database("EPSG", "6326", :PJ_CATEGORY_DATUM)
58
+ pm = datum.prime_meridian
59
+ assert_equal("Greenwich", pm.name)
60
+ assert_equal(:PJ_TYPE_PRIME_MERIDIAN, pm.proj_type)
61
+ end
55
62
  end
@@ -0,0 +1,72 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class DomainTest < AbstractTest
6
+ def test_domain_count
7
+ crs = Proj::Crs.new('EPSG:4326')
8
+ count = Proj::Domain.count(crs)
9
+ assert_kind_of(Integer, count)
10
+ assert_operator(count, :>=, 1)
11
+ end
12
+
13
+ def test_domains
14
+ crs = Proj::Crs.new('EPSG:4326')
15
+ domains = Proj::Domain.domains(crs)
16
+ assert_kind_of(Array, domains)
17
+ refute_empty(domains)
18
+
19
+ domain = domains.first
20
+ assert_kind_of(Proj::Domain, domain)
21
+ assert_kind_of(String, domain.scope)
22
+ assert_kind_of(Proj::Area, domain.area_of_use)
23
+ end
24
+
25
+ def test_domain_scope
26
+ crs = Proj::Crs.new('EPSG:4326')
27
+ domain = Proj::Domain.domains(crs).first
28
+ assert_equal("Horizontal component of 3D system.", domain.scope)
29
+ end
30
+
31
+ def test_domain_area_of_use
32
+ crs = Proj::Crs.new('EPSG:4326')
33
+ domain = Proj::Domain.domains(crs).first
34
+ area = domain.area_of_use
35
+ assert_equal('World.', area.name)
36
+ assert_in_delta(-180.0, area.west_lon_degree, 0.1)
37
+ assert_in_delta(-90.0, area.south_lat_degree, 0.1)
38
+ assert_in_delta(180.0, area.east_lon_degree, 0.1)
39
+ assert_in_delta(90.0, area.north_lat_degree, 0.1)
40
+ end
41
+
42
+ def test_domains_matches_area_of_use
43
+ crs = Proj::Crs.new('EPSG:4326')
44
+ domain = Proj::Domain.domains(crs).first
45
+ area = crs.area_of_use
46
+ assert_equal(area.name, domain.area_of_use.name)
47
+ assert_in_delta(area.west_lon_degree, domain.area_of_use.west_lon_degree, 0.001)
48
+ assert_in_delta(area.south_lat_degree, domain.area_of_use.south_lat_degree, 0.001)
49
+ assert_in_delta(area.east_lon_degree, domain.area_of_use.east_lon_degree, 0.001)
50
+ assert_in_delta(area.north_lat_degree, domain.area_of_use.north_lat_degree, 0.001)
51
+ end
52
+
53
+ def test_domains_matches_scope
54
+ crs = Proj::Crs.new('EPSG:4326')
55
+ domain = Proj::Domain.domains(crs).first
56
+ assert_equal(crs.scope, domain.scope)
57
+ end
58
+
59
+ def test_pj_object_domains
60
+ crs = Proj::Crs.new('EPSG:4326')
61
+ domains = crs.domains
62
+ assert_kind_of(Array, domains)
63
+ refute_empty(domains)
64
+ assert_kind_of(Proj::Domain, domains.first)
65
+ end
66
+
67
+ def test_domains_noop
68
+ conversion = Proj::Conversion.new("+proj=noop")
69
+ domains = Proj::Domain.domains(conversion)
70
+ assert_empty(domains)
71
+ end
72
+ end
@@ -1,80 +1,80 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './abstract_test'
4
-
5
- class EllipsoidTest < AbstractTest
6
- def parameter_crs
7
- wkt = <<~EOS
8
- PROJCS["WGS 84 / UTM zone 31N",
9
- GEOGCS["WGS 84",
10
- DATUM["WGS_1984",
11
- SPHEROID["WGS 84",6378137,298.257223563,
12
- AUTHORITY["EPSG","7030"]],
13
- AUTHORITY["EPSG","6326"]],
14
- PRIMEM["Greenwich",0,
15
- AUTHORITY["EPSG","8901"]],
16
- UNIT["degree",0.0174532925199433,
17
- AUTHORITY["EPSG","9122"]],
18
- AUTHORITY["EPSG","4326"]],
19
- PROJECTION["Transverse_Mercator"],
20
- PARAMETER["latitude_of_origin",0],
21
- PARAMETER["central_meridian",3],
22
- PARAMETER["scale_factor",0.9996],
23
- PARAMETER["false_easting",500000],
24
- PARAMETER["false_northing",0],
25
- UNIT["metre",1,
26
- AUTHORITY["EPSG","9001"]],
27
- AXIS["Easting",EAST],
28
- AXIS["Northing",NORTH],
29
- AUTHORITY["EPSG","32631"]]
30
- EOS
31
- Proj::Crs.new(wkt)
32
- end
33
-
34
- def test_built_in
35
- ellipsoids = Proj::Ellipsoid.built_in.map {|ellipsoid| ellipsoid[:id] }
36
- assert(ellipsoids.include?('WGS84'))
37
- assert(ellipsoids.include?('bessel'))
38
- assert(ellipsoids.include?('lerch'))
39
- end
40
-
41
- def test_from_database
42
- ellipsoid = Proj::Ellipsoid.create_from_database("EPSG", "7030", :PJ_CATEGORY_ELLIPSOID)
43
- assert_instance_of(Proj::Ellipsoid, ellipsoid)
44
- assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
45
- assert_equal("EPSG", ellipsoid.auth_name)
46
- assert_equal("WGS 84", ellipsoid.name)
47
- assert_equal("7030", ellipsoid.id_code)
48
- end
49
-
50
- def test_parameters
51
- ellipsoid = parameter_crs.ellipsoid
52
- params = ellipsoid.parameters
53
-
54
- expected = {semi_major_axis: 6378137.0,
55
- semi_minor_axis: 6356752.314245179,
56
- semi_minor_axis_computed: true,
57
- inverse_flattening: 298.257223563}
58
- assert_equal(expected, params)
59
- end
60
-
61
- def test_semi_major_axis
62
- meridian = parameter_crs.ellipsoid
63
- assert_equal(6378137.0, meridian.semi_major_axis)
64
- end
65
-
66
- def test_semi_minor_axis
67
- meridian = parameter_crs.ellipsoid
68
- assert_equal(6356752.314245179, meridian.semi_minor_axis)
69
- end
70
-
71
- def test_semi_minor_axis_computed
72
- meridian = parameter_crs.ellipsoid
73
- assert(meridian.semi_minor_axis_computed)
74
- end
75
-
76
- def test_inverse_flattening
77
- meridian = parameter_crs.ellipsoid
78
- assert_equal(298.257223563, meridian.inverse_flattening)
79
- end
80
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './abstract_test'
4
+
5
+ class EllipsoidTest < AbstractTest
6
+ def parameter_crs
7
+ wkt = <<~EOS
8
+ PROJCS["WGS 84 / UTM zone 31N",
9
+ GEOGCS["WGS 84",
10
+ DATUM["WGS_1984",
11
+ SPHEROID["WGS 84",6378137,298.257223563,
12
+ AUTHORITY["EPSG","7030"]],
13
+ AUTHORITY["EPSG","6326"]],
14
+ PRIMEM["Greenwich",0,
15
+ AUTHORITY["EPSG","8901"]],
16
+ UNIT["degree",0.0174532925199433,
17
+ AUTHORITY["EPSG","9122"]],
18
+ AUTHORITY["EPSG","4326"]],
19
+ PROJECTION["Transverse_Mercator"],
20
+ PARAMETER["latitude_of_origin",0],
21
+ PARAMETER["central_meridian",3],
22
+ PARAMETER["scale_factor",0.9996],
23
+ PARAMETER["false_easting",500000],
24
+ PARAMETER["false_northing",0],
25
+ UNIT["metre",1,
26
+ AUTHORITY["EPSG","9001"]],
27
+ AXIS["Easting",EAST],
28
+ AXIS["Northing",NORTH],
29
+ AUTHORITY["EPSG","32631"]]
30
+ EOS
31
+ Proj::Crs.new(wkt)
32
+ end
33
+
34
+ def test_built_in
35
+ ellipsoids = Proj::Ellipsoid.built_in.map {|ellipsoid| ellipsoid[:id] }
36
+ assert(ellipsoids.include?('WGS84'))
37
+ assert(ellipsoids.include?('bessel'))
38
+ assert(ellipsoids.include?('lerch'))
39
+ end
40
+
41
+ def test_from_database
42
+ ellipsoid = Proj::Ellipsoid.create_from_database("EPSG", "7030", :PJ_CATEGORY_ELLIPSOID)
43
+ assert_instance_of(Proj::Ellipsoid, ellipsoid)
44
+ assert_equal(:PJ_TYPE_ELLIPSOID, ellipsoid.proj_type)
45
+ assert_equal("EPSG", ellipsoid.auth_name)
46
+ assert_equal("WGS 84", ellipsoid.name)
47
+ assert_equal("7030", ellipsoid.id_code)
48
+ end
49
+
50
+ def test_parameters
51
+ ellipsoid = parameter_crs.ellipsoid
52
+ params = ellipsoid.parameters
53
+
54
+ expected = {semi_major_axis: 6378137.0,
55
+ semi_minor_axis: 6356752.314245179,
56
+ semi_minor_axis_computed: true,
57
+ inverse_flattening: 298.257223563}
58
+ assert_equal(expected, params)
59
+ end
60
+
61
+ def test_semi_major_axis
62
+ meridian = parameter_crs.ellipsoid
63
+ assert_equal(6378137.0, meridian.semi_major_axis)
64
+ end
65
+
66
+ def test_semi_minor_axis
67
+ meridian = parameter_crs.ellipsoid
68
+ assert_equal(6356752.314245179, meridian.semi_minor_axis)
69
+ end
70
+
71
+ def test_semi_minor_axis_computed
72
+ meridian = parameter_crs.ellipsoid
73
+ assert(meridian.semi_minor_axis_computed)
74
+ end
75
+
76
+ def test_inverse_flattening
77
+ meridian = parameter_crs.ellipsoid
78
+ assert_equal(298.257223563, meridian.inverse_flattening)
79
+ end
80
+ end
@@ -0,0 +1,149 @@
1
+ require_relative 'abstract_test'
2
+
3
+ class ExamplesTest < AbstractTest
4
+ def test_geodetic_distance
5
+ crs = Proj::Crs.new('EPSG:4326')
6
+
7
+ paris = Proj::Coordinate.new(x: Proj.degrees_to_radians(2.3522),
8
+ y: Proj.degrees_to_radians(48.8566))
9
+ berlin = Proj::Coordinate.new(x: Proj.degrees_to_radians(13.4050),
10
+ y: Proj.degrees_to_radians(52.5200))
11
+
12
+ distance = crs.lp_distance(paris, berlin)
13
+ assert_in_delta(879_700, distance, 5_000)
14
+ end
15
+
16
+ def test_geod_distance_with_azimuth
17
+ crs = Proj::Crs.new('EPSG:4326')
18
+
19
+ paris = Proj::Coordinate.new(x: Proj.degrees_to_radians(2.3522),
20
+ y: Proj.degrees_to_radians(48.8566))
21
+ berlin = Proj::Coordinate.new(x: Proj.degrees_to_radians(13.4050),
22
+ y: Proj.degrees_to_radians(52.5200))
23
+
24
+ result = crs.geod_distance(paris, berlin)
25
+ assert_in_delta(879_700, result.x, 5_000)
26
+ # Forward azimuth: roughly northeast
27
+ assert_in_delta(58.24, result.y, 1.0)
28
+ # Reverse azimuth: roughly southwest
29
+ assert_in_delta(66.81, result.z, 1.0)
30
+ end
31
+
32
+ if Proj::Api::PROJ_VERSION >= Gem::Version.new('9.7.0')
33
+ def test_geod_direct
34
+ crs = Proj::Crs.new('EPSG:4326')
35
+
36
+ paris = Proj::Coordinate.new(x: Proj.degrees_to_radians(2.3522),
37
+ y: Proj.degrees_to_radians(48.8566))
38
+
39
+ # 100 km due north
40
+ endpoint = crs.geod_direct(paris, 0.0, 100_000)
41
+ assert(endpoint.x.finite?)
42
+ assert(endpoint.y.finite?)
43
+ # Longitude should be approximately the same
44
+ assert_in_delta(2.3522, Proj.radians_to_degrees(endpoint.x), 0.01)
45
+ # Latitude should be ~0.9 degrees further north
46
+ assert_in_delta(49.76, Proj.radians_to_degrees(endpoint.y), 0.1)
47
+ end
48
+ end
49
+
50
+ def test_transform_bounds
51
+ transform = Proj::Transformation.new('EPSG:4326',
52
+ '+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs')
53
+
54
+ bounds = Proj::Bounds.new(40, -120, 64, -80)
55
+ result = transform.transform_bounds(bounds, :PJ_FWD, 21)
56
+
57
+ assert(result.xmin.finite?)
58
+ assert(result.ymin.finite?)
59
+ assert(result.xmax.finite?)
60
+ assert(result.ymax.finite?)
61
+ assert_operator(result.xmin, :<, result.xmax)
62
+ assert_operator(result.ymin, :<, result.ymax)
63
+ end
64
+
65
+ def test_database_query_authorities
66
+ database = Proj::Database.new(Proj::Context.current)
67
+ authorities = database.authorities
68
+ assert_operator(authorities.count, :>, 0)
69
+ assert_includes(authorities.to_a, 'EPSG')
70
+ end
71
+
72
+ def test_database_query_codes
73
+ database = Proj::Database.new(Proj::Context.current)
74
+ codes = database.codes('EPSG', :PJ_TYPE_GEOGRAPHIC_2D_CRS)
75
+ assert_operator(codes.count, :>, 0)
76
+ end
77
+
78
+ def test_database_query_crs_info
79
+ database = Proj::Database.new(Proj::Context.current)
80
+ crs_infos = database.crs_info('EPSG')
81
+ assert_operator(crs_infos.count, :>, 0)
82
+
83
+ info = crs_infos.first
84
+ assert_equal('EPSG', info.auth_name)
85
+ refute_nil(info.name)
86
+ refute_nil(info.crs_type)
87
+ end
88
+
89
+ def test_crs_identification
90
+ crs = Proj::Crs.new('OGC:CRS84')
91
+ objects, confidences = crs.identify('OGC')
92
+
93
+ assert_equal(1, objects.count)
94
+ assert_equal(100, confidences[0])
95
+ end
96
+
97
+ def test_promote_to_3d
98
+ crs_2d = Proj::Crs.new('EPSG:4326')
99
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs_2d.proj_type)
100
+
101
+ crs_3d = crs_2d.promote_to_3d
102
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_3D_CRS, crs_3d.proj_type)
103
+ end
104
+
105
+ def test_demote_to_2d
106
+ crs_2d = Proj::Crs.new('EPSG:4326')
107
+ crs_3d = crs_2d.promote_to_3d
108
+ crs_back = crs_3d.demote_to_2d
109
+ assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, crs_back.proj_type)
110
+ end
111
+
112
+ def test_batch_transformation
113
+ conversion = Proj::Conversion.new('+proj=utm +zone=32 +ellps=GRS80')
114
+
115
+ coordinates = [
116
+ Proj::Coordinate.new(lon: Proj.degrees_to_radians(12), lat: Proj.degrees_to_radians(55), z: 45),
117
+ Proj::Coordinate.new(lon: Proj.degrees_to_radians(12), lat: Proj.degrees_to_radians(56), z: 50),
118
+ Proj::Coordinate.new(lon: Proj.degrees_to_radians(13), lat: Proj.degrees_to_radians(55), z: 30)
119
+ ]
120
+
121
+ results = conversion.transform_array(coordinates, :PJ_FWD)
122
+
123
+ assert_equal(3, results.size)
124
+ results.each do |coord|
125
+ assert(coord.x.finite?)
126
+ assert(coord.y.finite?)
127
+ end
128
+
129
+ assert_in_delta(691875.63, results[0].x, 1)
130
+ assert_in_delta(6098907.83, results[0].y, 1)
131
+ end
132
+
133
+ def test_context_logging
134
+ context = Proj::Context.new
135
+ messages = []
136
+
137
+ context.set_log_function do |_pointer, level, message|
138
+ messages << { level: level, message: message }
139
+ end
140
+
141
+ begin
142
+ context.database.path = '/nonexistent'
143
+ rescue Proj::Error
144
+ end
145
+
146
+ refute_empty(messages)
147
+ assert(messages.any? { |m| m[:message].include?('/nonexistent') })
148
+ end
149
+ end