proj4rb 3.0.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/proj/area.rb
CHANGED
@@ -1,32 +1,73 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Proj
|
4
|
+
# Areas are used to specify the area of use for the choice of relevant coordinate operations.
|
5
|
+
# See Transformation#new
|
6
|
+
class Area
|
7
|
+
attr_reader :name, :west_lon_degree, :south_lat_degree, :east_lon_degree, :north_lat_degree
|
8
|
+
|
9
|
+
def self.finalize(pointer)
|
10
|
+
proc do
|
11
|
+
Api.proj_area_destroy(pointer)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(west_lon_degree:, south_lat_degree:, east_lon_degree:, north_lat_degree:, name: nil)
|
16
|
+
@west_lon_degree = west_lon_degree
|
17
|
+
@south_lat_degree = south_lat_degree
|
18
|
+
@east_lon_degree = east_lon_degree
|
19
|
+
@north_lat_degree = north_lat_degree
|
20
|
+
@name = name
|
21
|
+
create_area
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_ptr
|
25
|
+
@area
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sets the bounds for an area
|
29
|
+
#
|
30
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_area_set_bbox
|
31
|
+
#
|
32
|
+
# @param west_lon_degree [Float] West longitude, in degrees. In [-180,180] range.
|
33
|
+
# @param south_lat_degree [Float] South latitude, in degrees. In [-90,90] range.
|
34
|
+
# @param east_lon_degree [Float] East longitude, in degrees. In [-180,180] range.
|
35
|
+
# @param north_lat_degree [Float] North latitude, in degrees. In [-90,90] range.
|
36
|
+
def set_bounds(west_lon_degree:, south_lat_degree:, east_lon_degree:, north_lat_degree:)
|
37
|
+
Api.proj_area_set_bbox(self, west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets the name for an area
|
41
|
+
#
|
42
|
+
# @param value [String] The name of the area
|
43
|
+
def name=(value)
|
44
|
+
@name = name
|
45
|
+
# This Api wasn't added until proj 9.1
|
46
|
+
if defined?(Api.proj_area_set_name)
|
47
|
+
Api.proj_area_set_name(self, value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns nice printout of an Area
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def to_s
|
55
|
+
"Area west_lon_degree: #{self.west_lon_degree}, south_lat_degree: #{self.south_lat_degree}, east_lon_degree: #{self.east_lon_degree}, north_lat_degree: #{self.north_lat_degree}"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# Creates an area
|
61
|
+
#
|
62
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_area_create
|
63
|
+
def create_area
|
64
|
+
@area = Api.proj_area_create
|
65
|
+
self.set_bounds(west_lon_degree: west_lon_degree, south_lat_degree: south_lat_degree,
|
66
|
+
east_lon_degree: east_lon_degree, north_lat_degree: north_lat_degree)
|
67
|
+
if name
|
68
|
+
self.name = name
|
69
|
+
end
|
70
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@area))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Proj
|
2
|
+
class AxisInfo
|
3
|
+
# @!attribute [r] name
|
4
|
+
# @return [String] Axis name
|
5
|
+
# @!attribute [r] abbreviation
|
6
|
+
# @return [String] Axis abbreviation
|
7
|
+
# @!attribute [r] direction
|
8
|
+
# @return [String] Axis direction
|
9
|
+
# @!attribute [r] unit_conv_factor
|
10
|
+
# @return [String] Axis unit_conv_factor
|
11
|
+
# @!attribute [r] unit_name
|
12
|
+
# @return [String] Axis unit_name
|
13
|
+
# @!attribute [r] unit_auth_name
|
14
|
+
# @return [String] Axis unit_auth_name
|
15
|
+
# @!attribute [r] unit_code
|
16
|
+
# @return [String] Axis unit_code
|
17
|
+
attr_reader :name, :abbreviation, :direction,
|
18
|
+
:unit_name, :unit_auth_name, :unit_code, :unit_conv_factor
|
19
|
+
|
20
|
+
def initialize(name:, abbreviation:, direction:, unit_conv_factor:, unit_name:, unit_auth_name:, unit_code:)
|
21
|
+
@name = name
|
22
|
+
@abbreviation = abbreviation
|
23
|
+
@direction = direction
|
24
|
+
@unit_conv_factor = unit_conv_factor
|
25
|
+
@unit_name = unit_name
|
26
|
+
@unit_auth_name = unit_auth_name
|
27
|
+
@unit_code = unit_code
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns axis information in PJ_AXIS_DESCRIPTION structure
|
31
|
+
#
|
32
|
+
# @return [PJ_AXIS_DESCRIPTION]
|
33
|
+
def to_description
|
34
|
+
Api::PJ_AXIS_DESCRIPTION.create(name: name, abbreviation: abbreviation, direction: direction,
|
35
|
+
unit_conv_factor: unit_conv_factor, unit_name: name, unit_type: self.unit_type)
|
36
|
+
end
|
37
|
+
|
38
|
+
def unit_type
|
39
|
+
database = Database.new(Context.default)
|
40
|
+
unit = database.unit(self.unit_auth_name, self.unit_code)
|
41
|
+
unit.type
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/proj/bounds.rb
ADDED
data/lib/proj/context.rb
CHANGED
@@ -1,10 +1,24 @@
|
|
1
1
|
module Proj
|
2
2
|
# Proj 4.8 introduced the concept of a thread context object to support multi-threaded programs. The bindings
|
3
|
-
# automatically create
|
3
|
+
# automatically create one context per thread (its stored in local thread storage).
|
4
4
|
class Context
|
5
|
-
|
5
|
+
attr_reader :database
|
6
|
+
|
7
|
+
# Returns the default Proj context. This context *must* only be used in the main thread
|
8
|
+
# In general it is better to create new contexts
|
6
9
|
#
|
7
|
-
# @return [Context]
|
10
|
+
# @return [Context] The default context
|
11
|
+
def self.default
|
12
|
+
result = Context.allocate
|
13
|
+
# The default Proj Context is represented by a null pointer
|
14
|
+
result.instance_variable_set(:@pointer, FFI::Pointer::NULL)
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
# The context for the current thread. If a context does not exist
|
19
|
+
# a new one is created
|
20
|
+
#
|
21
|
+
# @return [Context] The context for the current thread
|
8
22
|
def self.current
|
9
23
|
Thread.current[:proj_context] ||= Context.new
|
10
24
|
end
|
@@ -19,43 +33,33 @@ module Proj
|
|
19
33
|
@pointer = Api.proj_context_create
|
20
34
|
ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
|
21
35
|
|
22
|
-
|
36
|
+
@database = Database.new(self)
|
23
37
|
end
|
24
38
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
39
|
+
def initialize_copy(original)
|
40
|
+
ObjectSpace.undefine_finalizer(self)
|
41
|
+
|
42
|
+
super
|
29
43
|
|
30
|
-
|
44
|
+
@pointer = Api.proj_context_clone(original)
|
45
|
+
@database = Database.new(self)
|
46
|
+
|
47
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
|
31
48
|
end
|
32
49
|
|
33
50
|
def to_ptr
|
34
51
|
@pointer
|
35
52
|
end
|
36
53
|
|
37
|
-
#
|
54
|
+
# Returns the current error-state of the context. An non-zero error codes indicates an error.
|
55
|
+
#
|
56
|
+
# See https://proj.org/development/reference/functions.html#c.proj_context_errno proj_context_errno
|
38
57
|
#
|
39
58
|
# return [Integer]
|
40
59
|
def errno
|
41
60
|
Api.proj_context_errno(self)
|
42
61
|
end
|
43
62
|
|
44
|
-
# Gets the path the Proj database
|
45
|
-
#
|
46
|
-
# return [String]
|
47
|
-
def database_path
|
48
|
-
Api.proj_context_get_database_path(self)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Sets the path to the Proj database
|
52
|
-
def database_path=(value)
|
53
|
-
result = Api.proj_context_set_database_path(self, value, nil, nil)
|
54
|
-
unless result == 1
|
55
|
-
Error.check(self.errno)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
63
|
# Sets a custom log function
|
60
64
|
#
|
61
65
|
# @example
|
@@ -65,6 +69,7 @@ module Proj
|
|
65
69
|
#
|
66
70
|
# @param pointer [FFI::MemoryPointer] Optional pointer to custom data
|
67
71
|
# @param proc [Proc] Custom logging procedure
|
72
|
+
#
|
68
73
|
# @return [nil]
|
69
74
|
def set_log_function(pointer = nil, &proc)
|
70
75
|
Api.proj_log_func(self, pointer, proc)
|
@@ -72,14 +77,14 @@ module Proj
|
|
72
77
|
|
73
78
|
# Gets the current log level
|
74
79
|
#
|
75
|
-
# @return [
|
80
|
+
# @return [PJ_LOG_LEVEL]
|
76
81
|
def log_level
|
77
82
|
Api.proj_log_level(self, :PJ_LOG_TELL)
|
78
83
|
end
|
79
84
|
|
80
85
|
# Sets the current log level
|
81
86
|
#
|
82
|
-
# @param value [
|
87
|
+
# @param value [PJ_LOG_LEVEL]
|
83
88
|
# @return [nil]
|
84
89
|
def log_level=(value)
|
85
90
|
Api.proj_log_level(self, value)
|
@@ -89,15 +94,156 @@ module Proj
|
|
89
94
|
#
|
90
95
|
# @return [Boolean]
|
91
96
|
def use_proj4_init_rules
|
92
|
-
Api.proj_context_get_use_proj4_init_rules(self, 0)
|
97
|
+
result = Api.proj_context_get_use_proj4_init_rules(self, 0)
|
98
|
+
result == 1 ? true : false
|
93
99
|
end
|
94
100
|
|
95
101
|
# Sets if proj4 init rules should be used
|
96
102
|
#
|
97
103
|
# @param value [Boolean]
|
104
|
+
#
|
98
105
|
# @return [nil]
|
99
106
|
def use_proj4_init_rules=(value)
|
100
107
|
Api.proj_context_use_proj4_init_rules(self, value ? 1 : 0)
|
101
108
|
end
|
109
|
+
|
110
|
+
# Guess the "dialect" of the specified WKT string
|
111
|
+
#
|
112
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_guess_wkt_dialect
|
113
|
+
#
|
114
|
+
# @param wkt [String] A WKT string
|
115
|
+
#
|
116
|
+
# @return [PJ_GUESSED_WKT_DIALECT]
|
117
|
+
def wkt_dialect(wkt)
|
118
|
+
Api.proj_context_guess_wkt_dialect(self, wkt)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Sets the CA Bundle path which will be used by PROJ when curl and PROJ_NETWORK are enabled.
|
122
|
+
#
|
123
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_ca_bundle_path
|
124
|
+
#
|
125
|
+
# @param path [String] Path to CA bundle.
|
126
|
+
#
|
127
|
+
# @return [nil]
|
128
|
+
def ca_bundle_path=(path)
|
129
|
+
Api.proj_context_set_ca_bundle_path(self, path.encode(:utf8))
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the cache used to store grid files locally
|
133
|
+
#
|
134
|
+
# @return [GridCache]
|
135
|
+
def cache
|
136
|
+
GridCache.new(self)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns if network access is enabled allowing {Grid} files to be downloaded
|
140
|
+
#
|
141
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_is_network_enabled
|
142
|
+
#
|
143
|
+
# @return [Boolean] True if network access is enabled, otherwise false
|
144
|
+
def network_enabled?
|
145
|
+
result = Api.proj_context_is_network_enabled(self)
|
146
|
+
result == 1 ? true : false
|
147
|
+
end
|
148
|
+
|
149
|
+
# Enable or disable network access for downloading grid files
|
150
|
+
#
|
151
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_enable_network
|
152
|
+
#
|
153
|
+
# @param value [Boolean] Specifies if network access should be enabled or disabled
|
154
|
+
def network_enabled=(value)
|
155
|
+
Api.proj_context_set_enable_network(self, value ? 1 : 0)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the URL endpoint to query for remote grids
|
159
|
+
#
|
160
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_get_url_endpoint
|
161
|
+
#
|
162
|
+
# @return [String] Endpoint URL
|
163
|
+
def url
|
164
|
+
Api.proj_context_get_url_endpoint(self)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Sets the URL endpoint to query for remote grids. This overrides the default endpoint in the PROJ configuration file or with the PROJ_NETWORK_ENDPOINT environment variable.
|
168
|
+
#
|
169
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_url_endpoint
|
170
|
+
#
|
171
|
+
# @param value [String] Endpoint URL
|
172
|
+
def url=(value)
|
173
|
+
Api.proj_context_set_url_endpoint(self, value)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns the user directory used to save grid files.
|
177
|
+
#
|
178
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_get_user_writable_directory
|
179
|
+
#
|
180
|
+
# @param [Boolean] If set to TRUE, create the directory if it does not exist already. Defaults to false
|
181
|
+
#
|
182
|
+
# @return [String] Directory
|
183
|
+
def user_directory(create = false)
|
184
|
+
Api.proj_context_get_user_writable_directory(self, create ? 1 : 0)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Sets the paths that Proj will search when opening one of its resource files
|
188
|
+
# such as the proj.db database, grids, etc.
|
189
|
+
#
|
190
|
+
# If set on the default context, they will be inherited by contexts created later.
|
191
|
+
#
|
192
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_search_paths
|
193
|
+
def search_paths=(paths)
|
194
|
+
# Convert paths to C chars
|
195
|
+
paths_ptr = paths.map do |path|
|
196
|
+
FFI::MemoryPointer.from_string(path)
|
197
|
+
end
|
198
|
+
|
199
|
+
pointer = FFI::MemoryPointer.new(:pointer, paths.size)
|
200
|
+
pointer.write_array_of_pointer(paths_ptr)
|
201
|
+
|
202
|
+
if Api.method_defined?(:proj_context_set_search_paths)
|
203
|
+
Api.proj_context_set_search_paths(self, paths.size, pointer)
|
204
|
+
elsif Api.method_defined?(:pj_set_searchpath)
|
205
|
+
Api.pj_set_searchpath(paths.size, pointer)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Installs a new {FileApi FileApiImpl}
|
210
|
+
#
|
211
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_fileapi
|
212
|
+
def set_file_api(file_api_klass)
|
213
|
+
unless file_api_klass.kind_of?(Class)
|
214
|
+
raise("#{file_api_klass} must be a class whose initializer has single argument which is a context")
|
215
|
+
end
|
216
|
+
|
217
|
+
# There is no API to "uninstall" a FileApi. Thus it needs to stay alive
|
218
|
+
# until the context is GCed
|
219
|
+
@file_api = file_api_klass.new(self)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Installs a new {NetworkApi NetworkApiImpl}
|
223
|
+
#
|
224
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_context_set_network_callbacks
|
225
|
+
def set_network_api(network_api_klass)
|
226
|
+
unless network_api_klass.kind_of?(Class)
|
227
|
+
raise("#{network_api_klass} must be a class whose initializer has single argument which is a context")
|
228
|
+
end
|
229
|
+
|
230
|
+
# There is no API to "uninstall" a FileApi. Thus it needs to stay alive
|
231
|
+
# until the context is GCed
|
232
|
+
@network_api = network_api_klass.new(self)
|
233
|
+
end
|
234
|
+
|
235
|
+
# --- Deprecated -------
|
236
|
+
def database_path
|
237
|
+
self.database.path
|
238
|
+
end
|
239
|
+
|
240
|
+
# Sets the path to the Proj database
|
241
|
+
def database_path=(value)
|
242
|
+
self.database.path = value
|
243
|
+
end
|
244
|
+
|
245
|
+
extend Gem::Deprecate
|
246
|
+
deprecate :database_path, "context.database.path", 2023, 6
|
247
|
+
deprecate :database_path=, "context.database.path=", 2023, 6
|
102
248
|
end
|
103
249
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Proj
|
5
|
+
# Conversions are {CoordinateOperationMix coordinate operations} that convert a source
|
6
|
+
# {Coordinate coordinate} to a new value. In Proj they are defined as operations that
|
7
|
+
# do not exert a change in reference frame while {Transformation transformations } do.
|
8
|
+
class Conversion < PjObject
|
9
|
+
include CoordinateOperationMixin
|
10
|
+
|
11
|
+
# Instantiate a Conversion
|
12
|
+
|
13
|
+
# Create a Transformation
|
14
|
+
#
|
15
|
+
# @param context [Context] Context
|
16
|
+
# @param name [String] Name of the transformation. Default is nil.
|
17
|
+
# @param auth_name [String] Transformation authority name. Default is nil.
|
18
|
+
# @param code [String] Transformation code. Default is nil.
|
19
|
+
# @param method_name [String] Method name. Default is nil.
|
20
|
+
# @param method_auth_name [String] Method authority name. Default is nil.
|
21
|
+
# @param method_code [String] Method code. Default is nil.
|
22
|
+
# @param params [Array<Parameter>] Parameter descriptions
|
23
|
+
# @param accuracy [Double] Accuracy of the transformation in meters. A negative value means unknown.
|
24
|
+
#
|
25
|
+
# @return [Conversion]
|
26
|
+
def self.create_conversion(context, name:, auth_name:, code:, method_name:, method_auth_name:, method_code:, params:)
|
27
|
+
params_ptr = FFI::MemoryPointer.new(Api::PJ_PARAM_DESCRIPTION, params.size)
|
28
|
+
params.each_with_index do |param, i|
|
29
|
+
param_description_target = Api::PJ_PARAM_DESCRIPTION.new(params_ptr[i])
|
30
|
+
param_description_source = param.to_description
|
31
|
+
param_description_target.to_ptr.__copy_from__(param_description_source.to_ptr, Api::PJ_PARAM_DESCRIPTION.size)
|
32
|
+
end
|
33
|
+
|
34
|
+
pointer = Api.proj_create_conversion(context, name, auth_name, code, method_name, method_auth_name, method_code, params.size, params_ptr)
|
35
|
+
Error.check_context(context)
|
36
|
+
self.create_object(pointer, context)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Instantiates an conversion from a string. The string can be:
|
40
|
+
#
|
41
|
+
# * proj-string,
|
42
|
+
# * WKT string,
|
43
|
+
# * object code (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326", "urn:ogc:def:coordinateOperation:EPSG::1671"),
|
44
|
+
# * Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as uniqueness is not guaranteed, heuristics are applied to determine the appropriate best match.
|
45
|
+
# * OGC URN combining references for compound coordinate reference systems (e.g "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" or custom abbreviated syntax "EPSG:2393+5717"),
|
46
|
+
# * OGC URN combining references for concatenated operations (e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618")
|
47
|
+
# * PROJJSON string. The jsonschema is at https://proj.org/schemas/v0.4/projjson.schema.json (added in 6.2)
|
48
|
+
# * compound CRS made from two object names separated with " + ". e.g. "WGS 84 + EGM96 height" (added in 7.1)
|
49
|
+
#
|
50
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_create
|
51
|
+
#
|
52
|
+
# @param value [String]. See above
|
53
|
+
#
|
54
|
+
# @return [Conversion]
|
55
|
+
def initialize(value, context=nil)
|
56
|
+
context ||= Context.current
|
57
|
+
ptr = Api.proj_create(context, value)
|
58
|
+
|
59
|
+
if ptr.null?
|
60
|
+
Error.check_context(context)
|
61
|
+
end
|
62
|
+
|
63
|
+
if Api.method_defined?(:proj_is_crs) && Api.proj_is_crs(ptr)
|
64
|
+
raise(Error, "Invalid conversion. Proj created an instance of: #{self.proj_type}.")
|
65
|
+
end
|
66
|
+
|
67
|
+
super(ptr, context)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return an equivalent projection. Currently implemented:
|
71
|
+
# * EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP)
|
72
|
+
# * EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP)
|
73
|
+
# * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP
|
74
|
+
# * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP
|
75
|
+
#
|
76
|
+
# @param new_method_epsg_code [String] EPSG code of the target method. Or nil in which case new_method_name must be specified.
|
77
|
+
# @param new_method_name [String] EPSG or PROJ target method name. Or nil in which case new_method_epsg_code must be specified
|
78
|
+
#
|
79
|
+
# @return [Conversion]
|
80
|
+
def convert_to_other_method(new_method_epsg_code: nil, new_method_name: nil)
|
81
|
+
ptr = Api.proj_convert_conversion_to_other_method(self.context, self,
|
82
|
+
new_method_epsg_code ? new_method_epsg_code: 0,
|
83
|
+
new_method_name)
|
84
|
+
|
85
|
+
if ptr.null?
|
86
|
+
Error.check_context(context)
|
87
|
+
end
|
88
|
+
|
89
|
+
self.class.create_object(ptr, context)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|