proj4rb 3.0.0 → 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.
- checksums.yaml +4 -4
- data/ChangeLog +26 -15
- data/README.rdoc +82 -44
- data/Rakefile +27 -27
- data/lib/api/api.rb +96 -118
- data/lib/api/api_5_0.rb +331 -300
- data/lib/api/api_5_1.rb +6 -6
- data/lib/api/api_5_2.rb +4 -4
- data/lib/api/api_6_0.rb +116 -14
- data/lib/api/api_6_1.rb +4 -4
- data/lib/api/api_6_2.rb +9 -6
- data/lib/api/api_6_3.rb +6 -0
- data/lib/api/api_7_0.rb +68 -0
- data/lib/api/api_7_1.rb +73 -0
- data/lib/api/api_7_2.rb +14 -0
- data/lib/api/api_8_0.rb +6 -0
- data/lib/api/api_8_1.rb +24 -0
- data/lib/api/api_8_2.rb +6 -0
- data/lib/api/api_9_1.rb +7 -0
- data/lib/api/api_9_2.rb +9 -0
- data/lib/api/api_experimental.rb +196 -0
- data/lib/proj/area.rb +73 -32
- data/lib/proj/axis_info.rb +44 -0
- data/lib/proj/bounds.rb +13 -0
- data/lib/proj/context.rb +174 -28
- data/lib/proj/conversion.rb +92 -0
- data/lib/proj/coordinate.rb +281 -197
- data/lib/proj/coordinate_operation_mixin.rb +381 -0
- data/lib/proj/coordinate_system.rb +137 -0
- data/lib/proj/crs.rb +672 -204
- data/lib/proj/crs_info.rb +47 -0
- data/lib/proj/database.rb +305 -0
- data/lib/proj/datum.rb +32 -0
- data/lib/proj/datum_ensemble.rb +34 -0
- data/lib/proj/ellipsoid.rb +77 -41
- data/lib/proj/error.rb +62 -9
- data/lib/proj/file_api.rb +166 -0
- data/lib/proj/grid.rb +121 -0
- data/lib/proj/grid_cache.rb +64 -0
- data/lib/proj/grid_info.rb +19 -0
- data/lib/proj/network_api.rb +92 -0
- data/lib/proj/operation.rb +42 -42
- data/lib/proj/operation_factory_context.rb +136 -0
- data/lib/proj/parameter.rb +38 -0
- data/lib/proj/parameters.rb +106 -0
- data/lib/proj/pj_object.rb +670 -80
- data/lib/proj/pj_objects.rb +44 -0
- data/lib/proj/prime_meridian.rb +65 -39
- data/lib/proj/projection.rb +698 -207
- data/lib/proj/session.rb +46 -0
- data/lib/proj/strings.rb +32 -0
- data/lib/proj/transformation.rb +101 -60
- data/lib/proj/unit.rb +108 -53
- data/lib/proj.rb +110 -9
- data/proj4rb.gemspec +5 -5
- data/test/abstract_test.rb +23 -1
- data/test/context_test.rb +172 -82
- data/test/conversion_test.rb +368 -0
- data/test/coordinate_system_test.rb +144 -0
- data/test/crs_test.rb +770 -71
- data/test/database_test.rb +360 -0
- data/test/datum_ensemble_test.rb +65 -0
- data/test/datum_test.rb +55 -0
- data/test/ellipsoid_test.rb +64 -18
- data/test/file_api_test.rb +66 -0
- data/test/grid_cache_test.rb +72 -0
- data/test/grid_test.rb +141 -0
- data/test/network_api_test.rb +45 -0
- data/test/operation_factory_context_test.rb +201 -0
- data/test/parameters_test.rb +40 -0
- data/test/pj_object_test.rb +179 -0
- data/test/prime_meridian_test.rb +76 -0
- data/test/proj_test.rb +46 -4
- data/test/projection_test.rb +646 -222
- data/test/session_test.rb +78 -0
- data/test/transformation_test.rb +149 -7
- data/test/unit_test.rb +57 -28
- metadata +51 -13
- data/lib/api/api_4_9.rb +0 -31
- data/lib/proj/config.rb +0 -70
- data/lib/proj/point.rb +0 -72
- data/test/prime_meridians_test.rb +0 -33
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
|
5
|
+
class GridCacheTest < AbstractTest
|
6
|
+
def download(grid)
|
7
|
+
begin
|
8
|
+
grid.download
|
9
|
+
ensure
|
10
|
+
grid.delete
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_clear
|
15
|
+
context = Proj::Context.new
|
16
|
+
context.network_enabled = true
|
17
|
+
context.cache.enabled = true
|
18
|
+
|
19
|
+
cache_path = File.join(context.user_directory, "cache.db")
|
20
|
+
context.cache.clear
|
21
|
+
refute(File.exist?(cache_path))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_disable
|
25
|
+
context = Proj::Context.new
|
26
|
+
cache_path = File.join(context.user_directory, "cache.db")
|
27
|
+
|
28
|
+
context.network_enabled = true
|
29
|
+
context.cache.clear
|
30
|
+
context.cache.enabled = false
|
31
|
+
refute(File.exist?(cache_path))
|
32
|
+
|
33
|
+
database = Proj::Database.new(context)
|
34
|
+
grid = database.grid("au_icsm_GDA94_GDA2020_conformal.tif")
|
35
|
+
|
36
|
+
# Download the file to create the cache
|
37
|
+
download(grid)
|
38
|
+
|
39
|
+
refute(File.exist?(cache_path))
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_set_path
|
43
|
+
context = Proj::Context.new
|
44
|
+
context.network_enabled = true
|
45
|
+
database = Proj::Database.new(context)
|
46
|
+
grid = database.grid("au_icsm_GDA94_GDA2020_conformal.tif")
|
47
|
+
|
48
|
+
# Custom path
|
49
|
+
cache_path = context.cache.path = File.join(Dir.tmpdir, "proj_cache_test.db")
|
50
|
+
refute(File.exist?(cache_path))
|
51
|
+
|
52
|
+
# Download the file to create the cache
|
53
|
+
download(grid)
|
54
|
+
|
55
|
+
assert(File.exist?(cache_path))
|
56
|
+
|
57
|
+
context.cache.clear
|
58
|
+
refute(File.exist?(cache_path))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_ttl
|
62
|
+
context = Proj::Context.new
|
63
|
+
context.cache.ttl = 60
|
64
|
+
assert(true)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_max_size
|
68
|
+
context = Proj::Context.new
|
69
|
+
context.cache.max_size = 100
|
70
|
+
assert(true)
|
71
|
+
end
|
72
|
+
end
|
data/test/grid_test.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
|
5
|
+
class GridTest < AbstractTest
|
6
|
+
def test_grid
|
7
|
+
database = Proj::Database.new(Proj::Context.current)
|
8
|
+
grid = database.grid("au_icsm_GDA94_GDA2020_conformal.tif")
|
9
|
+
|
10
|
+
assert_equal("au_icsm_GDA94_GDA2020_conformal.tif", grid.name)
|
11
|
+
assert(grid.full_name.empty?)
|
12
|
+
assert(grid.package_name.empty?)
|
13
|
+
assert_equal("https://cdn.proj.org/au_icsm_GDA94_GDA2020_conformal.tif", grid.url.to_s)
|
14
|
+
assert(grid.downloadable?)
|
15
|
+
assert(grid.open_license?)
|
16
|
+
refute(grid.available?)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_grid_proj6_name
|
20
|
+
database = Proj::Database.new(Proj::Context.current)
|
21
|
+
grid = database.grid("GDA94_GDA2020_conformal.gsb")
|
22
|
+
|
23
|
+
assert_equal("GDA94_GDA2020_conformal.gsb", grid.name)
|
24
|
+
assert(grid.full_name.empty?)
|
25
|
+
assert(grid.package_name.empty?)
|
26
|
+
assert_instance_of(URI::HTTPS, grid.url)
|
27
|
+
assert_equal("https://cdn.proj.org/au_icsm_GDA94_GDA2020_conformal.tif", grid.url.to_s)
|
28
|
+
assert(grid.downloadable?)
|
29
|
+
assert(grid.open_license?)
|
30
|
+
refute(grid.available?)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_downloaded_network_disabled
|
34
|
+
context = Proj::Context.new
|
35
|
+
context.network_enabled = false
|
36
|
+
|
37
|
+
grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
|
38
|
+
refute(grid.downloaded?)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_downloaded_network_enabled
|
42
|
+
context = Proj::Context.new
|
43
|
+
context.network_enabled = true
|
44
|
+
|
45
|
+
grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
|
46
|
+
refute(grid.downloaded?)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_download
|
50
|
+
context = Proj::Context.new
|
51
|
+
context.network_enabled = true
|
52
|
+
|
53
|
+
grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
|
54
|
+
refute(grid.path)
|
55
|
+
|
56
|
+
begin
|
57
|
+
grid.download
|
58
|
+
assert(grid.path)
|
59
|
+
assert(grid.downloaded?)
|
60
|
+
ensure
|
61
|
+
grid.delete
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_download_with_progress
|
66
|
+
context = Proj::Context.new
|
67
|
+
context.network_enabled = true
|
68
|
+
|
69
|
+
database = Proj::Database.new(context)
|
70
|
+
grid = database.grid("au_icsm_GDA94_GDA2020_conformal.tif")
|
71
|
+
|
72
|
+
progress_values = Array.new
|
73
|
+
begin
|
74
|
+
downloaded = grid.download do |progress|
|
75
|
+
progress_values << progress
|
76
|
+
end
|
77
|
+
assert(downloaded)
|
78
|
+
ensure
|
79
|
+
grid.delete
|
80
|
+
end
|
81
|
+
|
82
|
+
assert(progress_values.count > 1)
|
83
|
+
assert(progress_values.include?(1.0))
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_download_with_progress_cancel
|
87
|
+
context = Proj::Context.new
|
88
|
+
context.network_enabled = true
|
89
|
+
|
90
|
+
database = Proj::Database.new(context)
|
91
|
+
grid = database.grid("au_icsm_GDA94_GDA2020_conformal.tif")
|
92
|
+
|
93
|
+
progress_values = Array.new
|
94
|
+
begin
|
95
|
+
downloaded = grid.download do |progress|
|
96
|
+
progress_values << progress
|
97
|
+
# Cancel download
|
98
|
+
false
|
99
|
+
end
|
100
|
+
refute(downloaded)
|
101
|
+
ensure
|
102
|
+
grid.delete
|
103
|
+
end
|
104
|
+
|
105
|
+
assert_equal(1, progress_values.count)
|
106
|
+
refute(progress_values.include?(1.0))
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_grid_info
|
110
|
+
context = Proj::Context.new
|
111
|
+
context.network_enabled = true
|
112
|
+
grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
|
113
|
+
|
114
|
+
begin
|
115
|
+
assert(grid.info.filename.empty?)
|
116
|
+
#assert_equal("dk_sdfe_dvr90.tif", grid.info.gridname)
|
117
|
+
# assert_equal("gtiff", grid.info.format)
|
118
|
+
# assert_in_delta(0, grid.info.lower_left[:lam])
|
119
|
+
# assert_in_delta(0, grid.info.lower_left[:phi])
|
120
|
+
# assert_in_delta(0, grid.info.upper_right[:lam])
|
121
|
+
# assert_in_delta(0, grid.info.upper_right[:phi])
|
122
|
+
# assert_in_delta(0, grid.info.size_lon)
|
123
|
+
# assert_in_delta(0, grid.info.size_lat)
|
124
|
+
# assert_in_delta(0, grid.info.cell_size_lon)
|
125
|
+
# assert_in_delta(0, grid.info.cell_size_lat)
|
126
|
+
ensure
|
127
|
+
grid.delete
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_grid_invalid
|
132
|
+
skip "This test sometimes raises an error and sometimes doesn't."
|
133
|
+
database = Proj::Database.new(Proj::Context.current)
|
134
|
+
grid = database.grid("invalid")
|
135
|
+
|
136
|
+
error = assert_raises(Proj::Error) do
|
137
|
+
grid = database.grid("invalid")
|
138
|
+
end
|
139
|
+
assert_equal("Unknown error (code 4096)", error.to_s)
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
|
5
|
+
class NetworkApiTest < AbstractTest
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
# Make sure downloader callbacks are not GCed
|
9
|
+
#GC.stress = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
super
|
14
|
+
GC.stress = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_download
|
18
|
+
skip "This test causes a segfault due to the way Proj cleans up on shutdown"
|
19
|
+
|
20
|
+
context = Proj::Context.new
|
21
|
+
context.network_enabled = true
|
22
|
+
|
23
|
+
# Create a grid
|
24
|
+
grid = Proj::Grid.new("dk_sdfe_dvr90.tif", context)
|
25
|
+
grid.delete
|
26
|
+
|
27
|
+
context.cache.clear
|
28
|
+
|
29
|
+
# Install custom network api
|
30
|
+
context.set_network_api(Proj::NetworkApiImpl)
|
31
|
+
|
32
|
+
conversion = Proj::Conversion.new(<<~EOS, context)
|
33
|
+
+proj=pipeline
|
34
|
+
+step +proj=unitconvert +xy_in=deg +xy_out=rad
|
35
|
+
+step +proj=vgridshift +grids=dk_sdfe_dvr90.tif +multiplier=1
|
36
|
+
+step +proj=unitconvert +xy_in=rad +xy_out=deg
|
37
|
+
EOS
|
38
|
+
|
39
|
+
coord = Proj::Coordinate.new(lon: 12, lat: 56, z: 0)
|
40
|
+
new_coord = conversion.forward(coord)
|
41
|
+
assert_in_delta(12, new_coord.lon)
|
42
|
+
assert_in_delta(56, new_coord.lat)
|
43
|
+
assert_in_delta(36.5909996032715, new_coord.z, 1e-10)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
|
5
|
+
class OperationFactoryContextTest < AbstractTest
|
6
|
+
def test_create
|
7
|
+
context = Proj::Context.new
|
8
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
9
|
+
assert(context.to_ptr)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_finalize
|
13
|
+
100.times do
|
14
|
+
context = Proj::Context.new
|
15
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
16
|
+
assert(context.to_ptr)
|
17
|
+
GC.start
|
18
|
+
end
|
19
|
+
assert(true)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_create_operations
|
23
|
+
context = Proj::Context.new
|
24
|
+
source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
|
25
|
+
target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
|
26
|
+
|
27
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
28
|
+
factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
|
29
|
+
factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
|
30
|
+
|
31
|
+
operations = factory_context.create_operations(source, target)
|
32
|
+
assert_equal(10, operations.count)
|
33
|
+
|
34
|
+
operation = operations[0]
|
35
|
+
assert_equal("NAD27 to NAD83 (4)", operation.name)
|
36
|
+
refute(operation.ballpark_transformation?)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_suggested_operation
|
40
|
+
context = Proj::Context.new
|
41
|
+
source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
|
42
|
+
target = Proj::Crs.create_from_database("EPSG", "4269", :PJ_CATEGORY_CRS)
|
43
|
+
|
44
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
45
|
+
factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
|
46
|
+
factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
|
47
|
+
|
48
|
+
operations = factory_context.create_operations(source, target)
|
49
|
+
|
50
|
+
coord = Proj::Coordinate.new(x: 40, y: -100)
|
51
|
+
index = operations.suggested_operation(:PJ_FWD, coord)
|
52
|
+
|
53
|
+
expected = case
|
54
|
+
when proj9?
|
55
|
+
2
|
56
|
+
else
|
57
|
+
7
|
58
|
+
end
|
59
|
+
assert_equal(expected, index)
|
60
|
+
|
61
|
+
operation = operations[index]
|
62
|
+
|
63
|
+
expected = case
|
64
|
+
when proj9?
|
65
|
+
"NAD27 to NAD83 (1)"
|
66
|
+
else
|
67
|
+
"Ballpark geographic offset from NAD27 to NAD83"
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_equal(expected, operation.name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_ballpark_transformations
|
74
|
+
context = Proj::Context.new
|
75
|
+
source = Proj::Crs.create_from_database("EPSG", "4267", :PJ_CATEGORY_CRS)
|
76
|
+
target = Proj::Crs.create_from_database("EPSG", "4258", :PJ_CATEGORY_CRS)
|
77
|
+
|
78
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
79
|
+
factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
|
80
|
+
factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
|
81
|
+
|
82
|
+
# Allowed implicitly
|
83
|
+
operations = factory_context.create_operations(source, target)
|
84
|
+
assert_equal(1, operations.count)
|
85
|
+
|
86
|
+
# Allow explicitly
|
87
|
+
factory_context.ballpark_transformations = true
|
88
|
+
operations = factory_context.create_operations(source, target)
|
89
|
+
assert_equal(1, operations.count)
|
90
|
+
|
91
|
+
# Disallow
|
92
|
+
factory_context.ballpark_transformations = false
|
93
|
+
operations = factory_context.create_operations(source, target)
|
94
|
+
assert_equal(0, operations.count)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_desired_accuracy
|
98
|
+
context = Proj::Context.new
|
99
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
100
|
+
factory_context.desired_accuracy = 5
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_set_area_of_interest
|
104
|
+
context = Proj::Context.new
|
105
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
106
|
+
factory_context.set_area_of_interest(10, 10, 10, 10)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_crs_extent_use
|
110
|
+
context = Proj::Context.new
|
111
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
112
|
+
factory_context.crs_extent_use = :PJ_CRS_EXTENT_SMALLEST
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_spatial_criterion
|
116
|
+
context = Proj::Context.new
|
117
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
118
|
+
factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_grid_availability
|
122
|
+
context = Proj::Context.new
|
123
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
124
|
+
factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_USE
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_use_proj_alternative_grid_names
|
128
|
+
context = Proj::Context.new
|
129
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
130
|
+
factory_context.use_proj_alternative_grid_names = true
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_allow_use_intermediate_crs
|
134
|
+
context = Proj::Context.new
|
135
|
+
# There is no direct transformations between both
|
136
|
+
source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
|
137
|
+
target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
|
138
|
+
|
139
|
+
# Default behavior: allow any pivot
|
140
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
141
|
+
operations = factory_context.create_operations(source, target)
|
142
|
+
assert_equal(1, operations.count)
|
143
|
+
|
144
|
+
operation = operations[0]
|
145
|
+
assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
|
146
|
+
refute(operation.ballpark_transformation?)
|
147
|
+
|
148
|
+
# Disallow pivots
|
149
|
+
factory_context.allow_use_intermediate_crs = :PROJ_INTERMEDIATE_CRS_USE_NEVER
|
150
|
+
operations = factory_context.create_operations(source, target)
|
151
|
+
assert_equal(1, operations.count)
|
152
|
+
|
153
|
+
operation = operations[0]
|
154
|
+
assert_equal("Ballpark geographic offset from ED50 to RGF93 v1", operation.name)
|
155
|
+
assert(operation.ballpark_transformation?)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_allowed_intermediate_crs
|
159
|
+
context = Proj::Context.new
|
160
|
+
|
161
|
+
# There is no direct transformations between both
|
162
|
+
source = Proj::Crs.create_from_database("EPSG", "4230", :PJ_CATEGORY_CRS)
|
163
|
+
target = Proj::Crs.create_from_database("EPSG", "4171", :PJ_CATEGORY_CRS)
|
164
|
+
|
165
|
+
# Restrict pivot to ETRS89
|
166
|
+
factory_context = Proj::OperationFactoryContext.new(context, authority: "EPSG")
|
167
|
+
factory_context.allowed_intermediate_crs = ["EPSG", "4258"]
|
168
|
+
|
169
|
+
operations = factory_context.create_operations(source, target)
|
170
|
+
assert_equal(1, operations.count)
|
171
|
+
|
172
|
+
operation = operations[0]
|
173
|
+
assert_equal("ED50 to ETRS89 (10) + Inverse of RGF93 v1 to ETRS89 (1)", operation.name)
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_discard_superseded
|
177
|
+
context = Proj::Context.new
|
178
|
+
source = Proj::Crs.create_from_database("EPSG", "4203", :PJ_CATEGORY_CRS)
|
179
|
+
target = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
|
180
|
+
|
181
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
182
|
+
factory_context.spatial_criterion = :PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION
|
183
|
+
factory_context.grid_availability = :PROJ_GRID_AVAILABILITY_IGNORED
|
184
|
+
|
185
|
+
factory_context.discard_superseded = true
|
186
|
+
operations = factory_context.create_operations(source, target)
|
187
|
+
assert_equal(4, operations.count)
|
188
|
+
|
189
|
+
factory_context.discard_superseded = false
|
190
|
+
operations = factory_context.create_operations(source, target)
|
191
|
+
assert_equal(5, operations.count)
|
192
|
+
end
|
193
|
+
|
194
|
+
if proj9?
|
195
|
+
def test_set_area_of_interest_name
|
196
|
+
context = Proj::Context.new
|
197
|
+
factory_context = Proj::OperationFactoryContext.new(context)
|
198
|
+
factory_context.area_of_interest_name = 'test'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
|
5
|
+
class ParametersTest < AbstractTest
|
6
|
+
def test_types_nil
|
7
|
+
params = Proj::Parameters.new
|
8
|
+
assert(params.types.empty?)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_types_one
|
12
|
+
types = [:PJ_TYPE_GEODETIC_CRS]
|
13
|
+
params = Proj::Parameters.new
|
14
|
+
params.types = types
|
15
|
+
assert_equal(types, params.types)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_types_many
|
19
|
+
types = [:PJ_TYPE_GEODETIC_CRS, :PJ_TYPE_GEOCENTRIC_CRS, :PJ_TYPE_GEOGRAPHIC_CRS]
|
20
|
+
params = Proj::Parameters.new
|
21
|
+
params.types = types
|
22
|
+
assert_equal(types, params.types)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_bbox_valid
|
26
|
+
params = Proj::Parameters.new
|
27
|
+
refute(params.bbox_valid)
|
28
|
+
|
29
|
+
params.bbox_valid = true
|
30
|
+
assert(params.bbox_valid)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_allow_deprecated
|
34
|
+
params = Proj::Parameters.new
|
35
|
+
refute(params.allow_deprecated)
|
36
|
+
|
37
|
+
params.allow_deprecated = true
|
38
|
+
assert(params.allow_deprecated)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './abstract_test'
|
4
|
+
class PjObjectTest < AbstractTest
|
5
|
+
def test_clone
|
6
|
+
object = Proj::PjObject.create("+proj=longlat")
|
7
|
+
clone = object.clone
|
8
|
+
assert(object.equivalent_to?(clone, :PJ_COMP_STRICT))
|
9
|
+
assert(object.context.equal?(clone.context))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_dup
|
13
|
+
object = Proj::PjObject.create("+proj=longlat")
|
14
|
+
clone = object.dup
|
15
|
+
assert(object.equivalent_to?(clone, :PJ_COMP_STRICT))
|
16
|
+
assert(object.context.equal?(clone.context))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_equivalent
|
20
|
+
from_epsg = Proj::PjObject.create_from_database("EPSG", "7844", :PJ_CATEGORY_CRS)
|
21
|
+
from_wkt = Proj::PjObject.create_from_wkt(<<~EOS)
|
22
|
+
GEOGCRS["GDA2020",
|
23
|
+
DATUM["GDA2020",
|
24
|
+
ELLIPSOID["GRS_1980",6378137,298.257222101,
|
25
|
+
LENGTHUNIT["metre",1]]],
|
26
|
+
PRIMEM["Greenwich",0,
|
27
|
+
ANGLEUNIT["Degree",0.0174532925199433]],
|
28
|
+
CS[ellipsoidal,2],
|
29
|
+
AXIS["geodetic latitude (Lat)",north,
|
30
|
+
ORDER[1],
|
31
|
+
ANGLEUNIT["degree",0.0174532925199433]],
|
32
|
+
AXIS["geodetic longitude (Lon)",east,
|
33
|
+
ORDER[2],
|
34
|
+
ANGLEUNIT["degree",0.0174532925199433]]]"
|
35
|
+
EOS
|
36
|
+
|
37
|
+
assert(from_epsg.equivalent_to?(from_wkt, :PJ_COMP_EQUIVALENT))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_accuracy_crs
|
41
|
+
object = Proj::PjObject.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
|
42
|
+
assert_equal(-1, object.accuracy)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_accuracy_coordinate_operation
|
46
|
+
object = Proj::PjObject.create_from_database("EPSG", "1170", :PJ_CATEGORY_COORDINATE_OPERATION)
|
47
|
+
assert_equal(16.0, object.accuracy)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_accuracy_projection
|
51
|
+
object = Proj::Conversion.new("+proj=helmert")
|
52
|
+
assert_equal(-1.0, object.accuracy)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_id_code
|
56
|
+
crs = Proj::Crs.new('EPSG:4326')
|
57
|
+
assert_equal("4326", crs.id_code)
|
58
|
+
refute(crs.id_code(1))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_remarks_transformation
|
62
|
+
transformation = Proj::PjObject.create_from_database("EPSG", "8048", :PJ_CATEGORY_COORDINATE_OPERATION)
|
63
|
+
|
64
|
+
expected = "Scale difference in ppb where 1/billion = 1E-9. See CT codes 8444-46 for NTv2 method giving equivalent results for Christmas Island, Cocos Islands and Australia respectively. See CT code 8447 for alternative including distortion model for Australia only."
|
65
|
+
assert_equal(expected, transformation.remarks)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_remarks_conversion
|
69
|
+
operation = Proj::PjObject.create_from_database("EPSG", "3811", :PJ_CATEGORY_COORDINATE_OPERATION)
|
70
|
+
|
71
|
+
expected = "Replaces Lambert 2005."
|
72
|
+
assert_equal(expected, operation.remarks)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_scope_transformation
|
76
|
+
transformation = Proj::PjObject.create_from_database("EPSG", "8048", :PJ_CATEGORY_COORDINATE_OPERATION)
|
77
|
+
|
78
|
+
expected = "Transformation of GDA94 coordinates that have been derived through GNSS CORS."
|
79
|
+
assert_equal(expected, transformation.scope)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_scope_conversion
|
83
|
+
operation = Proj::PjObject.create_from_database("EPSG", "3811", :PJ_CATEGORY_COORDINATE_OPERATION)
|
84
|
+
|
85
|
+
expected = "Engineering survey, topographic mapping."
|
86
|
+
assert_equal(expected, operation.scope)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_scope_invalid
|
90
|
+
operation = Proj::Conversion.new("+proj=noop")
|
91
|
+
refute(operation.scope)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_factors
|
95
|
+
conversion = Proj::Conversion.new("+proj=merc +ellps=WGS84")
|
96
|
+
coord = Proj::Coordinate.new(lon: Proj.degrees_to_radians(12), lat: Proj.degrees_to_radians(55))
|
97
|
+
factors = conversion.factors(coord)
|
98
|
+
|
99
|
+
assert_in_delta(1.739526610076288, factors[:meridional_scale], 1e-7)
|
100
|
+
assert_in_delta(1.739526609938368, factors[:parallel_scale], 1e-7)
|
101
|
+
assert_in_delta(3.0259528269235867, factors[:areal_scale], 1e-7)
|
102
|
+
|
103
|
+
assert_in_delta(0.0, factors[:angular_distortion], 1e-7)
|
104
|
+
assert_in_delta(1.5707963267948966, factors[:meridian_parallel_angle], 1e-7)
|
105
|
+
assert_in_delta(0.0, factors[:meridian_convergence], 1e-7)
|
106
|
+
|
107
|
+
assert_in_delta(1.7395266100073281, factors[:tissot_semimajor], 1e-7)
|
108
|
+
assert_in_delta(1.7395266100073281, factors[:tissot_semiminor], 1e-7)
|
109
|
+
|
110
|
+
assert_in_delta(0.9999999999996122, factors[:dx_dlam], 1e-7)
|
111
|
+
assert_in_delta(0.0, factors[:dx_dphi], 1e-7)
|
112
|
+
assert_in_delta(0.0, factors[:dy_dlam], 1e-7)
|
113
|
+
assert_in_delta(1.7395897312200146, factors[:dy_dphi], 1e-7)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_create_from_name
|
117
|
+
context = Proj::Context.new
|
118
|
+
objects = Proj::PjObject.create_from_name("WGS 84", context)
|
119
|
+
assert_equal(5, objects.size)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_create_from_name_with_auth_name
|
123
|
+
context = Proj::Context.new
|
124
|
+
objects = Proj::PjObject.create_from_name("WGS 84", context, auth_name: "xx")
|
125
|
+
assert_equal(0, objects.size)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_create_from_name_with_types
|
129
|
+
context = Proj::Context.new
|
130
|
+
objects = Proj::PjObject.create_from_name("WGS 84", context, types: [:PJ_TYPE_GEODETIC_CRS, :PJ_TYPE_PROJECTED_CRS])
|
131
|
+
assert_equal(3, objects.size)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_create_from_name_with_types_and_approximate_match
|
135
|
+
context = Proj::Context.new
|
136
|
+
objects = Proj::PjObject.create_from_name("WGS 84", context, approximate_match: true,
|
137
|
+
types: [:PJ_TYPE_GEODETIC_CRS, :PJ_TYPE_PROJECTED_CRS])
|
138
|
+
|
139
|
+
expected = proj9? ? 442 : 440
|
140
|
+
assert_equal(expected, objects.size)
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_create_from_name_with_types_and_approximate_match_and_limit
|
144
|
+
context = Proj::Context.new
|
145
|
+
objects = Proj::PjObject.create_from_name("WGS 84", context, approximate_match: true, limit: 25,
|
146
|
+
types: [:PJ_TYPE_GEODETIC_CRS, :PJ_TYPE_PROJECTED_CRS])
|
147
|
+
assert_equal(25, objects.size)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_deprecated_true
|
151
|
+
wkt = <<~EOS
|
152
|
+
GEOGCRS["SAD69 (deprecated)",
|
153
|
+
DATUM["South_American_Datum_1969",
|
154
|
+
ELLIPSOID["GRS 1967",6378160,298.247167427,
|
155
|
+
LENGTHUNIT["metre",1,
|
156
|
+
ID["EPSG",9001]]]],
|
157
|
+
PRIMEM["Greenwich",0,
|
158
|
+
ANGLEUNIT["degree",0.0174532925199433,
|
159
|
+
ID["EPSG",9122]]],
|
160
|
+
CS[ellipsoidal,2],
|
161
|
+
AXIS["latitude",north,
|
162
|
+
ORDER[1],
|
163
|
+
ANGLEUNIT["degree",0.0174532925199433,
|
164
|
+
ID["EPSG",9122]]],
|
165
|
+
AXIS["longitude",east,
|
166
|
+
ORDER[2],
|
167
|
+
ANGLEUNIT["degree",0.0174532925199433,
|
168
|
+
ID["EPSG",9122]]]]
|
169
|
+
EOS
|
170
|
+
|
171
|
+
crs = Proj::Crs.create(wkt)
|
172
|
+
assert(crs.deprecated?)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_deprecated_false
|
176
|
+
crs = Proj::Crs.create_from_database("EPSG", "4326", :PJ_CATEGORY_CRS)
|
177
|
+
refute(crs.deprecated?)
|
178
|
+
end
|
179
|
+
end
|