proj4rb 4.1.0 → 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 (115) 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 -0
  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 -672
  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 -670
  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 +1771 -698
  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 -28
  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 -1072
  71. data/test/database_test.rb +407 -359
  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 -201
  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 -179
  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 +45 -31
  95. data/ChangeLog +0 -89
  96. data/README.rdoc +0 -207
  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_experimental.rb +0 -201
  114. data/lib/proj/file_api.rb +0 -166
  115. data/lib/proj/network_api.rb +0 -92
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+
3
+ module Proj
4
+ # Represents a 3D bounding box defined by minimum and maximum x/y/z values.
5
+ # Used with {CoordinateOperationMixin#transform_bounds_3d} to transform 3D
6
+ # regions between coordinate reference systems. Requires PROJ 9.6+.
7
+ class Bounds3d
8
+ # @!attribute [r] xmin
9
+ # @return [Float] Minimum x value (e.g., west longitude)
10
+ # @!attribute [r] ymin
11
+ # @return [Float] Minimum y value (e.g., south latitude)
12
+ # @!attribute [r] zmin
13
+ # @return [Float] Minimum z value (e.g., lower elevation)
14
+ # @!attribute [r] xmax
15
+ # @return [Float] Maximum x value (e.g., east longitude)
16
+ # @!attribute [r] ymax
17
+ # @return [Float] Maximum y value (e.g., north latitude)
18
+ # @!attribute [r] zmax
19
+ # @return [Float] Maximum z value (e.g., upper elevation)
20
+ # @!attribute [r] name
21
+ # @return [String, nil] Optional name for this bounds
22
+ attr_reader :name, :xmin, :ymin, :zmin, :xmax, :ymax, :zmax
23
+
24
+ # Creates a new 3D bounding box.
25
+ #
26
+ # @param xmin [Float] Minimum x value
27
+ # @param ymin [Float] Minimum y value
28
+ # @param zmin [Float] Minimum z value
29
+ # @param xmax [Float] Maximum x value
30
+ # @param ymax [Float] Maximum y value
31
+ # @param zmax [Float] Maximum z value
32
+ # @param name [String, nil] Optional name
33
+ #
34
+ # @return [Bounds3d]
35
+ def initialize(xmin, ymin, zmin, xmax, ymax, zmax, name = nil)
36
+ @xmin = xmin
37
+ @ymin = ymin
38
+ @zmin = zmin
39
+ @xmax = xmax
40
+ @ymax = ymax
41
+ @zmax = zmax
42
+ @name = name
43
+ end
44
+ end
45
+ end
data/lib/proj/context.rb CHANGED
@@ -2,7 +2,7 @@ module Proj
2
2
  # Proj 4.8 introduced the concept of a thread context object to support multi-threaded programs. The bindings
3
3
  # automatically create one context per thread (its stored in local thread storage).
4
4
  class Context
5
- attr_reader :database
5
+ attr_reader :database, :life_span
6
6
 
7
7
  # Returns the default Proj context. This context *must* only be used in the main thread
8
8
  # In general it is better to create new contexts
@@ -12,6 +12,7 @@ module Proj
12
12
  result = Context.allocate
13
13
  # The default Proj Context is represented by a null pointer
14
14
  result.instance_variable_set(:@pointer, FFI::Pointer::NULL)
15
+ result.instance_variable_set(:@life_span, LifeSpan.new)
15
16
  result
16
17
  end
17
18
 
@@ -24,15 +25,17 @@ module Proj
24
25
  end
25
26
 
26
27
  # @!visibility private
27
- def self.finalize(pointer)
28
+ def self.finalize(pointer, life_span)
28
29
  proc do
30
+ life_span.ended!
29
31
  Api.proj_context_destroy(pointer)
30
32
  end
31
33
  end
32
34
 
33
35
  def initialize
34
36
  @pointer = Api.proj_context_create
35
- ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
37
+ @life_span = LifeSpan.new
38
+ ObjectSpace.define_finalizer(self, self.class.finalize(@pointer, @life_span))
36
39
 
37
40
  @database = Database.new(self)
38
41
  end
@@ -43,9 +46,19 @@ module Proj
43
46
  super
44
47
 
45
48
  @pointer = Api.proj_context_clone(original)
49
+ @life_span = LifeSpan.new
46
50
  @database = Database.new(self)
47
51
 
48
- ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
52
+ ObjectSpace.define_finalizer(self, self.class.finalize(@pointer, @life_span))
53
+ end
54
+
55
+ # Explicitly free the underlying PROJ context.
56
+ def destroy
57
+ @life_span.ended!
58
+ Api.proj_context_destroy(@pointer)
59
+ @pointer = FFI::Pointer::NULL
60
+ ObjectSpace.undefine_finalizer(self)
61
+ nil
49
62
  end
50
63
 
51
64
  def to_ptr
@@ -73,6 +86,8 @@ module Proj
73
86
  #
74
87
  # @return [nil]
75
88
  def set_log_function(pointer = nil, &proc)
89
+ @log_data_pointer = pointer
90
+ @log_function = proc
76
91
  Api.proj_log_func(self, pointer, proc)
77
92
  end
78
93
 
@@ -127,7 +142,7 @@ module Proj
127
142
  #
128
143
  # @return [nil]
129
144
  def ca_bundle_path=(path)
130
- Api.proj_context_set_ca_bundle_path(self, path.encode(:utf8))
145
+ Api.proj_context_set_ca_bundle_path(self, path.encode('utf-8'))
131
146
  end
132
147
 
133
148
  # Returns the cache used to store grid files locally
@@ -182,7 +197,19 @@ module Proj
182
197
  #
183
198
  # @return [String] Directory
184
199
  def user_directory(create = false)
185
- Api.proj_context_get_user_writable_directory(self, create ? 1 : 0)
200
+ path = Api.proj_context_get_user_writable_directory(self, create ? 1 : 0)
201
+ # Normalizes path names
202
+ File.expand_path(path)
203
+ end
204
+
205
+ # Sets the user directory used to save grid files.
206
+ #
207
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_set_user_writable_directory
208
+ #
209
+ # @param path [String] Directory path
210
+ # @param create [Boolean] If true, create the directory if needed. Defaults to true.
211
+ def set_user_writable_directory(path, create: true)
212
+ Api.proj_context_set_user_writable_directory(self, path, create ? 1 : 0)
186
213
  end
187
214
 
188
215
  # Sets the paths that Proj will search when opening one of its resource files
@@ -207,9 +234,29 @@ module Proj
207
234
  end
208
235
  end
209
236
 
210
- # Installs a new {FileApiImpl FileApi}
237
+ # Installs a custom file API that PROJ will use for all file operations.
238
+ #
239
+ # The class must include {FileApiCallbacks} and implement the following methods
240
+ # that receive a file handle as their first argument:
241
+ #
242
+ # * +open(path, access_mode)+ - Open a file. Return a file object or nil on error.
243
+ # * +read(file, size_bytes)+ - Read size_bytes from file, return data string.
244
+ # * +write(file, data)+ - Write data to file, return bytes written.
245
+ # * +seek(file, offset, whence)+ - Seek within file.
246
+ # * +tell(file)+ - Return current file position.
247
+ # * +close(file)+ - Close the file.
248
+ # * +exists(path)+ - Return true if file exists.
249
+ # * +mkdir(path)+ - Create directory, return true on success.
250
+ # * +unlink(path)+ - Remove file, return true on success.
251
+ # * +rename(original_path, new_path)+ - Rename file, return true on success.
211
252
  #
212
253
  # @see https://proj.org/development/reference/functions.html#c.proj_context_set_fileapi
254
+ # @see FileApiCallbacks
255
+ #
256
+ # @example
257
+ # context.set_file_api(MyCustomFileApi)
258
+ #
259
+ # @param file_api_klass [Class] A class whose initializer accepts a single Context argument
213
260
  def set_file_api(file_api_klass)
214
261
  unless file_api_klass.kind_of?(Class)
215
262
  raise("#{file_api_klass} must be a class whose initializer has single argument which is a context")
@@ -220,7 +267,7 @@ module Proj
220
267
  @file_api = file_api_klass.new(self)
221
268
  end
222
269
 
223
- # Installs a new {NetworkApiImpl NetworkApi}
270
+ # Installs a new {NetworkApiCallbacks NetworkApi}
224
271
  #
225
272
  # @see https://proj.org/development/reference/functions.html#c.proj_context_set_network_callbacks
226
273
  def set_network_api(network_api_klass)
@@ -228,23 +275,10 @@ module Proj
228
275
  raise("#{network_api_klass} must be a class whose initializer has single argument which is a context")
229
276
  end
230
277
 
231
- # There is no API to "uninstall" a FileApi. Thus it needs to stay alive
278
+ # There is no API to "uninstall" a NetworkApi. Thus it needs to stay alive
232
279
  # until the context is GCed
233
280
  @network_api = network_api_klass.new(self)
234
281
  end
235
282
 
236
- # --- Deprecated -------
237
- def database_path
238
- self.database.path
239
- end
240
-
241
- # Sets the path to the Proj database
242
- def database_path=(value)
243
- self.database.path = value
244
- end
245
-
246
- extend Gem::Deprecate
247
- deprecate :database_path, "context.database.path", 2023, 6
248
- deprecate :database_path=, "context.database.path=", 2023, 6
249
283
  end
250
- end
284
+ end
@@ -1,91 +1,94 @@
1
- # encoding: UTF-8
2
- require 'stringio'
3
-
4
- module Proj
5
- # Conversions are {CoordinateOperationMixin 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
- #
24
- # @return [Conversion]
25
- def self.create_conversion(context, name:, auth_name:, code:, method_name:, method_auth_name:, method_code:, params:)
26
- params_ptr = FFI::MemoryPointer.new(Api::PJ_PARAM_DESCRIPTION, params.size)
27
- params.each_with_index do |param, i|
28
- param_description_target = Api::PJ_PARAM_DESCRIPTION.new(params_ptr[i])
29
- param_description_source = param.to_description
30
- param_description_target.to_ptr.__copy_from__(param_description_source.to_ptr, Api::PJ_PARAM_DESCRIPTION.size)
31
- end
32
-
33
- pointer = Api.proj_create_conversion(context, name, auth_name, code, method_name, method_auth_name, method_code, params.size, params_ptr)
34
- Error.check_context(context)
35
- self.create_object(pointer, context)
36
- end
37
-
38
- # Instantiates an conversion from a string. The string can be:
39
- #
40
- # * proj-string,
41
- # * WKT string,
42
- # * object code (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326", "urn:ogc:def:coordinateOperation:EPSG::1671"),
43
- # * 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.
44
- # * 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"),
45
- # * OGC URN combining references for concatenated operations (e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618")
46
- # * PROJJSON string. The jsonschema is at https://proj.org/schemas/v0.4/projjson.schema.json (added in 6.2)
47
- # * compound CRS made from two object names separated with " + ". e.g. "WGS 84 + EGM96 height" (added in 7.1)
48
- #
49
- # @see https://proj.org/development/reference/functions.html#c.proj_create
50
- #
51
- # @param value [String]. See above
52
- #
53
- # @return [Conversion]
54
- def initialize(value, context=nil)
55
- context ||= Context.current
56
- ptr = Api.proj_create(context, value)
57
-
58
- if ptr.null?
59
- Error.check_context(context)
60
- end
61
-
62
- if Api.method_defined?(:proj_is_crs) && Api.proj_is_crs(ptr)
63
- raise(Error, "Invalid conversion. Proj created an instance of: #{self.proj_type}.")
64
- end
65
-
66
- super(ptr, context)
67
- end
68
-
69
- # Return an equivalent projection. Currently implemented:
70
- # * EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP)
71
- # * EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP)
72
- # * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP
73
- # * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP
74
- #
75
- # @param new_method_epsg_code [String] EPSG code of the target method. Or nil in which case new_method_name must be specified.
76
- # @param new_method_name [String] EPSG or PROJ target method name. Or nil in which case new_method_epsg_code must be specified
77
- #
78
- # @return [Conversion]
79
- def convert_to_other_method(new_method_epsg_code: nil, new_method_name: nil)
80
- ptr = Api.proj_convert_conversion_to_other_method(self.context, self,
81
- new_method_epsg_code ? new_method_epsg_code: 0,
82
- new_method_name)
83
-
84
- if ptr.null?
85
- Error.check_context(context)
86
- end
87
-
88
- self.class.create_object(ptr, context)
89
- end
90
- end
91
- end
1
+ # encoding: UTF-8
2
+ require 'stringio'
3
+
4
+ module Proj
5
+ # Conversions are {CoordinateOperationMixin 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
+ #
24
+ # @return [Conversion]
25
+ def self.create_conversion(context, name:, auth_name:, code:, method_name:, method_auth_name:, method_code:, params:)
26
+ Error.validate_context!(context)
27
+ params_ptr = FFI::MemoryPointer.new(Api::PjParamDescription, params.size)
28
+ params.each_with_index do |param, i|
29
+ param_description_target = Api::PjParamDescription.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::PjParamDescription.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
+ pj_type = Api.proj_get_type(ptr)
65
+ Api.proj_destroy(ptr)
66
+ raise(Error, "Invalid conversion. Proj created an instance of: #{pj_type}.")
67
+ end
68
+
69
+ super(ptr, context)
70
+ end
71
+
72
+ # Return an equivalent projection. Currently implemented:
73
+ # * EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP)
74
+ # * EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP) to EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP)
75
+ # * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP
76
+ # * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP to EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP
77
+ #
78
+ # @param new_method_epsg_code [String] EPSG code of the target method. Or nil in which case new_method_name must be specified.
79
+ # @param new_method_name [String] EPSG or PROJ target method name. Or nil in which case new_method_epsg_code must be specified
80
+ #
81
+ # @return [Conversion]
82
+ def convert_to_other_method(new_method_epsg_code: nil, new_method_name: nil)
83
+ ptr = Api.proj_convert_conversion_to_other_method(self.context, self,
84
+ new_method_epsg_code ? new_method_epsg_code: 0,
85
+ new_method_name)
86
+
87
+ if ptr.null?
88
+ Error.check_context(context)
89
+ end
90
+
91
+ self.class.create_object(ptr, context)
92
+ end
93
+ end
94
+ end