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,45 +1,45 @@
1
- # encoding: UTF-8
2
- module Proj
3
- class PjObjects
4
- # @!visibility private
5
- def self.finalize(pointer)
6
- proc do
7
- Api.proj_list_destroy(pointer)
8
- end
9
- end
10
-
11
- def initialize(pointer, context)
12
- @pointer = pointer
13
- @context = context
14
- ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
15
- end
16
-
17
- def to_ptr
18
- @pointer
19
- end
20
-
21
- def context
22
- @context || Context.current
23
- end
24
-
25
- def count
26
- Api.proj_list_get_count(self)
27
- end
28
- alias :size :count
29
-
30
- def [](index)
31
- ptr = Api.proj_list_get(context, self, index)
32
- PjObject.create_object(ptr, self.context)
33
- end
34
-
35
- # Returns the index of the operation that would be the most appropriate to transform the specified coordinates.
36
- #
37
- # @param direction [PJ_DIRECTION] - Direction into which to transform the point.
38
- # @param coord [Coordinate] - Coordinate to transform
39
- #
40
- # @return [Integer] - Index of operation
41
- def suggested_operation(direction, coord)
42
- Api.proj_get_suggested_operation(self.context, self, direction, coord)
43
- end
44
- end
45
- end
1
+ # encoding: UTF-8
2
+ module Proj
3
+ class PjObjects
4
+ # @!visibility private
5
+ def self.finalize(pointer)
6
+ proc do
7
+ Api.proj_list_destroy(pointer)
8
+ end
9
+ end
10
+
11
+ def initialize(pointer, context)
12
+ @pointer = pointer
13
+ @context = context
14
+ ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
15
+ end
16
+
17
+ def to_ptr
18
+ @pointer
19
+ end
20
+
21
+ def context
22
+ @context || Context.current
23
+ end
24
+
25
+ def count
26
+ Api.proj_list_get_count(self)
27
+ end
28
+ alias :size :count
29
+
30
+ def [](index)
31
+ ptr = Api.proj_list_get(context, self, index)
32
+ PjObject.create_object(ptr, self.context)
33
+ end
34
+
35
+ # Returns the index of the operation that would be the most appropriate to transform the specified coordinates.
36
+ #
37
+ # @param direction [PJ_DIRECTION] - Direction into which to transform the point.
38
+ # @param coord [Coordinate] - Coordinate to transform
39
+ #
40
+ # @return [Integer] - Index of operation
41
+ def suggested_operation(direction, coord)
42
+ Api.proj_get_suggested_operation(self.context, self, direction, coord)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ module Proj
2
+ module Api
3
+ class PjParamDescription
4
+ attr_accessor :retained_ptrs
5
+
6
+ def self.create(name:, auth_name: nil, code: nil, value:, unit_name: nil, unit_conv_factor:, unit_type:)
7
+ result = PjParamDescription.new
8
+ result.retained_ptrs = []
9
+ result.put_string(:name, name)
10
+ result.put_string(:auth_name, auth_name)
11
+ result.put_string(:code, code)
12
+ result[:value] = value
13
+ result.put_string(:unit_name, unit_name)
14
+ result[:unit_conv_factor] = unit_conv_factor
15
+ result[:unit_type] = unit_type
16
+ result
17
+ end
18
+
19
+ # Write a string into a :string field and retain the pointer to prevent GC.
20
+ def put_string(field, value)
21
+ return if value.nil?
22
+ ptr = FFI::MemoryPointer.from_string(value)
23
+ @retained_ptrs << ptr
24
+ pointer.put_pointer(offset_of(field), ptr)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,66 +1,66 @@
1
- module Proj
2
- class PrimeMeridian < PjObject
3
- # Returns a list of Prime Meridians that are built into Proj. A more comprehensive
4
- # list is stored in the Proj database and can be queried via PjObject#create_from_database
5
- def self.built_in
6
- pointer_to_array = FFI::Pointer.new(Api::PJ_PRIME_MERIDIANS, Api.proj_list_prime_meridians)
7
- result = Array.new
8
- 0.step do |i|
9
- prime_meridian_info = Api::PJ_PRIME_MERIDIANS.new(pointer_to_array[i])
10
- break result if prime_meridian_info[:id].nil?
11
- result << prime_meridian_info
12
- end
13
- result
14
- end
15
-
16
- # Returns prime meridian parameters
17
- #
18
- # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
19
- #
20
- # @return [Hash] Hash of ellipsoid parameters. Axes are in meters
21
- def parameters
22
- @parameters ||= begin
23
- out_longitude = FFI::MemoryPointer.new(:double)
24
- out_unit_conv_factor = FFI::MemoryPointer.new(:double)
25
- out_unit_name = FFI::MemoryPointer.new(:string)
26
-
27
- result = Api.proj_prime_meridian_get_parameters(self.context, self, out_longitude, out_unit_conv_factor, out_unit_name)
28
-
29
- if result != 1
30
- Error.check_object(self)
31
- end
32
-
33
- {longitude: out_longitude.read_double,
34
- unit_conv_factor: out_unit_conv_factor.read_double,
35
- unit_name: out_unit_name.read_pointer.read_string_to_null}
36
- end
37
- end
38
-
39
- # Returns the longitude of the prime meridian in its native unit
40
- #
41
- # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
42
- #
43
- # @return [Float]
44
- def longitude
45
- self.parameters[:longitude]
46
- end
47
-
48
- # Returns the conversion factor of the prime meridian longitude unit to radians
49
- #
50
- # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
51
- #
52
- # @return [Float]
53
- def unit_conv_factor
54
- self.parameters[:unit_conv_factor]
55
- end
56
-
57
- # Returns the unit name
58
- #
59
- # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
60
- #
61
- # @return [String ]
62
- def unit_name
63
- self.parameters[:unit_name]
64
- end
65
- end
1
+ module Proj
2
+ class PrimeMeridian < PjObject
3
+ # Returns a list of Prime Meridians that are built into Proj. A more comprehensive
4
+ # list is stored in the Proj database and can be queried via PjObject#create_from_database
5
+ def self.built_in
6
+ pointer_to_array = FFI::Pointer.new(Api::PjPrimeMeridians, Api.proj_list_prime_meridians)
7
+ result = Array.new
8
+ 0.step do |i|
9
+ prime_meridian_info = Api::PjPrimeMeridians.new(pointer_to_array[i])
10
+ break result if prime_meridian_info[:id].nil?
11
+ result << prime_meridian_info
12
+ end
13
+ result
14
+ end
15
+
16
+ # Returns prime meridian parameters
17
+ #
18
+ # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
19
+ #
20
+ # @return [Hash] Hash of ellipsoid parameters. Axes are in meters
21
+ def parameters
22
+ @parameters ||= begin
23
+ out_longitude = FFI::MemoryPointer.new(:double)
24
+ out_unit_conv_factor = FFI::MemoryPointer.new(:double)
25
+ out_unit_name = FFI::MemoryPointer.new(:string)
26
+
27
+ result = Api.proj_prime_meridian_get_parameters(self.context, self, out_longitude, out_unit_conv_factor, out_unit_name)
28
+
29
+ if result != 1
30
+ Error.check_object(self)
31
+ end
32
+
33
+ {longitude: out_longitude.read_double,
34
+ unit_conv_factor: out_unit_conv_factor.read_double,
35
+ unit_name: out_unit_name.read_pointer.read_string_to_null}
36
+ end
37
+ end
38
+
39
+ # Returns the longitude of the prime meridian in its native unit
40
+ #
41
+ # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
42
+ #
43
+ # @return [Float]
44
+ def longitude
45
+ self.parameters[:longitude]
46
+ end
47
+
48
+ # Returns the conversion factor of the prime meridian longitude unit to radians
49
+ #
50
+ # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
51
+ #
52
+ # @return [Float]
53
+ def unit_conv_factor
54
+ self.parameters[:unit_conv_factor]
55
+ end
56
+
57
+ # Returns the unit name
58
+ #
59
+ # @see https://proj.org/development/reference/functions.html#c.proj_prime_meridian_get_parameters
60
+ #
61
+ # @return [String ]
62
+ def unit_name
63
+ self.parameters[:unit_name]
64
+ end
65
+ end
66
66
  end
@@ -129,31 +129,6 @@ module Proj
129
129
  Conversion.create_object(ptr, context)
130
130
  end
131
131
 
132
- # Create a new tunisia_mapping_grid projection
133
- #
134
- # @see https://proj.org/operations/projections/index.html
135
- #
136
- # @param context [Context] Proj Context
137
- # @param center_latitude [Float] Latitude of natural origin/Center Latitude
138
- # @param center_longitude [Float] Longitude of natural origin/Central Meridian
139
- # @param false_easting [Float] False Easting. Default is 0.
140
- # @param false_northing [Float] False Northing. Default is 0.
141
- # @param angular_unit_name [String] Name of the angular units. Default is Degree.
142
- # @param angular_unit_conversion_factor [Float] Conversion factor from angular unit to radians. Default is 0.0174532925199433.
143
- # @param linear_unit_name [String] Name of the linear units. Default is Metre
144
- # @param linear_unit_conversion_factor [Float] Conversion factor from linear unit to meters. Default is 1.
145
- #
146
- # @return [Crs]
147
- def self.tunisia_mapping_grid(context, center_latitude:, center_longitude:, false_easting: 0, false_northing: 0, angular_unit_name: "Degree", angular_unit_conversion_factor: 0.0174532925199433, linear_unit_name: "Metre", linear_unit_conversion_factor: 1)
148
- ptr = Api.proj_create_conversion_tunisia_mapping_grid(context, center_latitude, center_longitude, false_easting, false_northing, angular_unit_name, angular_unit_conversion_factor, linear_unit_name, linear_unit_conversion_factor)
149
-
150
- if ptr.null?
151
- Error.check_context(context)
152
- end
153
-
154
- Conversion.create_object(ptr, context)
155
- end
156
-
157
132
  # Create a new tunisia_mining_grid projection
158
133
  #
159
134
  # @see https://proj.org/operations/projections/index.html
@@ -232,6 +207,33 @@ module Proj
232
207
  Conversion.create_object(ptr, context)
233
208
  end
234
209
 
210
+ # Create a new lambert_conic_conformal_1sp_variant_b projection
211
+ #
212
+ # @see https://proj.org/operations/projections/index.html
213
+ #
214
+ # @param context [Context] Proj Context
215
+ # @param latitude_nat_origin [Float] Latitude of natural origin
216
+ # @param scale [Float] Scale factor
217
+ # @param latitude_false_origin [Float] Latitude of false origin
218
+ # @param longitude_false_origin [Float] Longitude of false origin
219
+ # @param easting_false_origin [Float] Easting of false origin
220
+ # @param northing_false_origin [Float] Northing of false origin
221
+ # @param angular_unit_name [String] Name of the angular units. Default is Degree.
222
+ # @param angular_unit_conversion_factor [Float] Conversion factor from angular unit to radians. Default is 0.0174532925199433.
223
+ # @param linear_unit_name [String] Name of the linear units. Default is Metre
224
+ # @param linear_unit_conversion_factor [Float] Conversion factor from linear unit to meters. Default is 1.
225
+ #
226
+ # @return [Crs]
227
+ def self.lambert_conic_conformal_1sp_variant_b(context, latitude_nat_origin:, scale:, latitude_false_origin:, longitude_false_origin:, easting_false_origin:, northing_false_origin:, angular_unit_name: "Degree", angular_unit_conversion_factor: 0.0174532925199433, linear_unit_name: "Metre", linear_unit_conversion_factor: 1)
228
+ ptr = Api.proj_create_conversion_lambert_conic_conformal_1sp_variant_b(context, latitude_nat_origin, scale, latitude_false_origin, longitude_false_origin, easting_false_origin, northing_false_origin, angular_unit_name, angular_unit_conversion_factor, linear_unit_name, linear_unit_conversion_factor)
229
+
230
+ if ptr.null?
231
+ Error.check_context(context)
232
+ end
233
+
234
+ Conversion.create_object(ptr, context)
235
+ end
236
+
235
237
  # Create a new lambert_conic_conformal_2sp projection
236
238
  #
237
239
  # @see https://proj.org/operations/projections/index.html
@@ -1738,5 +1740,32 @@ module Proj
1738
1740
 
1739
1741
  Conversion.create_object(ptr, context)
1740
1742
  end
1743
+
1744
+ # Create a new local_orthographic projection
1745
+ #
1746
+ # @see https://proj.org/operations/projections/index.html
1747
+ #
1748
+ # @param context [Context] Proj Context
1749
+ # @param latitude_nat_origin [Float] Latitude of natural origin
1750
+ # @param longitude_nat_origin [Float] Longitude of natural origin
1751
+ # @param ellipsoidal_height [Float] Ellipsoidal height
1752
+ # @param geocentric_x_origin [Float] Geocentric X origin
1753
+ # @param geocentric_y_origin [Float] Geocentric Y origin
1754
+ # @param geocentric_z_origin [Float] Geocentric Z origin
1755
+ # @param angular_unit_name [String] Name of the angular units. Default is Degree.
1756
+ # @param angular_unit_conversion_factor [Float] Conversion factor from angular unit to radians. Default is 0.0174532925199433.
1757
+ # @param linear_unit_name [String] Name of the linear units. Default is Metre
1758
+ # @param linear_unit_conversion_factor [Float] Conversion factor from linear unit to meters. Default is 1.
1759
+ #
1760
+ # @return [Crs]
1761
+ def self.local_orthographic(context, latitude_nat_origin:, longitude_nat_origin:, ellipsoidal_height:, geocentric_x_origin:, geocentric_y_origin:, geocentric_z_origin:, angular_unit_name: "Degree", angular_unit_conversion_factor: 0.0174532925199433, linear_unit_name: "Metre", linear_unit_conversion_factor: 1)
1762
+ ptr = Api.proj_create_conversion_local_orthographic(context, latitude_nat_origin, longitude_nat_origin, ellipsoidal_height, geocentric_x_origin, geocentric_y_origin, geocentric_z_origin, angular_unit_name, angular_unit_conversion_factor, linear_unit_name, linear_unit_conversion_factor)
1763
+
1764
+ if ptr.null?
1765
+ Error.check_context(context)
1766
+ end
1767
+
1768
+ Conversion.create_object(ptr, context)
1769
+ end
1741
1770
  end
1742
1771
  end
data/lib/proj/session.rb CHANGED
@@ -4,7 +4,9 @@ module Proj
4
4
 
5
5
  # @!visibility private
6
6
  def self.finalize(context, pointer)
7
+ life_span = context.life_span
7
8
  proc do
9
+ next unless life_span.alive?
8
10
  Api.proj_insert_object_session_destroy(context, pointer)
9
11
  end
10
12
  end
@@ -1,102 +1,102 @@
1
- module Proj
2
- # Transformations are {CoordinateOperationMixin coordinate operations} that
3
- # convert {Coordinate coordinates} from one {Crs} to another.
4
- # In Proj they are defined as operations that exert a change in reference frame
5
- # while {Conversion conversions } do not.
6
- class Transformation < PjObject
7
- include CoordinateOperationMixin
8
-
9
- # Create a Transformation
10
- #
11
- # @param context [Context] Context
12
- # @param name [String] Name of the transformation. Default is nil.
13
- # @param auth_name [String] Transformation authority name. Default is nil.
14
- # @param code [String] Transformation code. Default is nil.
15
- # @param source_crs [CoordinateSystem] Source CRS
16
- # @param target_crs [CoordinateSystem] Target CRS
17
- # @param interpolation_crs [CoordinateSystem] Interpolation. Default is nil
18
- # @param method_name [String] Method name. Default is nil.
19
- # @param method_auth_name [String] Method authority name. Default is nil.
20
- # @param method_code [String] Method code. Default is nil.
21
- # @param params [Array<Parameter>] Parameter descriptions
22
- # @param accuracy [Float] Accuracy of the transformation in meters. A negative value means unknown.
23
- #
24
- # @return [Transformation]
25
- def self.create(context, name: nil, auth_name: nil, code: nil,
26
- source_crs:, target_crs:, interpolation_crs: nil,
27
- method_name: nil, method_auth_name: nil, method_code: nil,
28
- params:, accuracy:)
29
-
30
- params_ptr = FFI::MemoryPointer.new(Api::PJ_PARAM_DESCRIPTION, params.size)
31
- params.each_with_index do |param, i|
32
- param_description_target = Api::PJ_PARAM_DESCRIPTION.new(params_ptr[i])
33
- param_description_source = param.to_description
34
- param_description_target.to_ptr.__copy_from__(param_description_source.to_ptr, Api::PJ_PARAM_DESCRIPTION.size)
35
- end
36
-
37
- ptr = Api.proj_create_transformation(context, name, auth_name, code,
38
- source_crs, target_crs, interpolation_crs,
39
- method_name, method_auth_name, method_code,
40
- params.count, params_ptr, accuracy)
41
- self.create_object(ptr, context)
42
- end
43
-
44
- # Transforms a {Coordinate} from the source {Crs} to the target {Crs}. Coordinates should be expressed in
45
- # the units and axis order of the definition of the source CRS. The returned transformed coordinate will
46
- # be in the units and axis order of the definition of the target CRS.
47
- #
48
- # For most geographic Crses, the units will be in degrees. For geographic CRS defined by the EPSG authority,
49
- # the order of coordinates is latitude first, longitude second. When using a PROJ initialization string,
50
- # on contrary, the order will be longitude first, latitude second.
51
- #
52
- # For projected CRS, the units may vary (metre, us-foot, etc..).
53
- #
54
- # For projected CRS defined by the EPSG authority, and with EAST / NORTH directions, the axis order might be
55
- # easting first, northing second, or the reverse. When using a PROJ string, the order will be
56
- # easting first, northing second, except if the +axis parameter modifies it.
57
- #
58
- # @see https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs_from_pj
59
- # @see https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs proj_create_crs_to_crs
60
- #
61
- # @param source [Crs, String] The source Crs. See the Crs documentation for the string format
62
- # @param target [Crs, String] The target Crs. See the Crs documentation for the string format
63
- # @param area [Area] If an area is specified a more accurate transformation between two given systems can be chosen
64
- # @param context [Context]
65
- # @param authority [String] Restricts the authority of coordinate operations looked up in the database
66
- # @param accuracy [Float] Sets the minimum desired accuracy (in metres) of the candidate coordinate operations
67
- # @param allow_ballpark [Boolean] Set to false to disallow the use of Ballpark transformation in the candidate coordinate operations.
68
- # @param only_best [Boolean] Set to true to cause PROJ to error out if the best transformation cannot be used. Requires Proj 9.2 and higher
69
- #
70
- # @return [Transformation] A new transformation
71
- def initialize(source, target, context=nil,
72
- area: nil, authority: nil, accuracy: nil, allow_ballpark: nil, only_best: nil, force_over: nil)
73
-
74
- context ||= Context.current
75
-
76
- options = {"AUTHORITY": authority,
77
- "ACCURACY": accuracy.nil? ? nil : accuracy.to_s,
78
- "ALLOW_BALLPARK": allow_ballpark.nil? ? nil : (allow_ballpark ? "YES" : "NO"),
79
- "ONLY_BEST": only_best.nil? ? nil : (only_best ? "YES" : "NO"),
80
- "FORCE_OVER": force_over.nil? ? nil : (force_over ? "YES" : "NO")}
81
- options_ptr = create_options_pointer(options)
82
-
83
- ptr = if source.is_a?(Crs) && target.is_a?(Crs)
84
- if Api.method_defined?(:proj_create_crs_to_crs_from_pj)
85
- Api.proj_create_crs_to_crs_from_pj(context, source, target, area, options_ptr)
86
- else
87
- Api.proj_create_crs_to_crs(context, source.definition, target.definition, area)
88
- end
89
- else
90
- Api.proj_create_crs_to_crs(context, source, target, nil)
91
- end
92
-
93
- if ptr.null?
94
- Error.check_context(context)
95
- # If that does not raise an error then no operation was found
96
- raise(Error, "No operation found matching criteria")
97
- end
98
-
99
- super(ptr, context)
100
- end
101
- end
102
- end
1
+ module Proj
2
+ # Transformations are {CoordinateOperationMixin coordinate operations} that
3
+ # convert {Coordinate coordinates} from one {Crs} to another.
4
+ # In Proj they are defined as operations that exert a change in reference frame
5
+ # while {Conversion conversions } do not.
6
+ class Transformation < PjObject
7
+ include CoordinateOperationMixin
8
+
9
+ # Create a Transformation
10
+ #
11
+ # @param context [Context] Context
12
+ # @param name [String] Name of the transformation. Default is nil.
13
+ # @param auth_name [String] Transformation authority name. Default is nil.
14
+ # @param code [String] Transformation code. Default is nil.
15
+ # @param source_crs [CoordinateSystem] Source CRS
16
+ # @param target_crs [CoordinateSystem] Target CRS
17
+ # @param interpolation_crs [CoordinateSystem] Interpolation. Default is nil
18
+ # @param method_name [String] Method name. Default is nil.
19
+ # @param method_auth_name [String] Method authority name. Default is nil.
20
+ # @param method_code [String] Method code. Default is nil.
21
+ # @param params [Array<Parameter>] Parameter descriptions
22
+ # @param accuracy [Float] Accuracy of the transformation in meters. A negative value means unknown.
23
+ #
24
+ # @return [Transformation]
25
+ def self.create(context, name: nil, auth_name: nil, code: nil,
26
+ source_crs:, target_crs:, interpolation_crs: nil,
27
+ method_name: nil, method_auth_name: nil, method_code: nil,
28
+ params:, accuracy:)
29
+ Error.validate_context!(context)
30
+
31
+ params_ptr = FFI::MemoryPointer.new(Api::PjParamDescription, params.size)
32
+ params.each_with_index do |param, i|
33
+ param_description_target = Api::PjParamDescription.new(params_ptr[i])
34
+ param_description_source = param.to_description
35
+ param_description_target.to_ptr.__copy_from__(param_description_source.to_ptr, Api::PjParamDescription.size)
36
+ end
37
+
38
+ ptr = Api.proj_create_transformation(context, name, auth_name, code,
39
+ source_crs, target_crs, interpolation_crs,
40
+ method_name, method_auth_name, method_code,
41
+ params.count, params_ptr, accuracy)
42
+ self.create_object(ptr, context)
43
+ end
44
+
45
+ # Transforms a {Coordinate} from the source {Crs} to the target {Crs}. Coordinates should be expressed in
46
+ # the units and axis order of the definition of the source CRS. The returned transformed coordinate will
47
+ # be in the units and axis order of the definition of the target CRS.
48
+ #
49
+ # For most geographic Crses, the units will be in degrees. For geographic CRS defined by the EPSG authority,
50
+ # the order of coordinates is latitude first, longitude second. When using a PROJ initialization string,
51
+ # on contrary, the order will be longitude first, latitude second.
52
+ #
53
+ # For projected CRS, the units may vary (metre, us-foot, etc..).
54
+ #
55
+ # For projected CRS defined by the EPSG authority, and with EAST / NORTH directions, the axis order might be
56
+ # easting first, northing second, or the reverse. When using a PROJ string, the order will be
57
+ # easting first, northing second, except if the +axis parameter modifies it.
58
+ #
59
+ # @see https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs_from_pj
60
+ # @see https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs proj_create_crs_to_crs
61
+ #
62
+ # @param source [Crs, String] The source Crs. See the Crs documentation for the string format
63
+ # @param target [Crs, String] The target Crs. See the Crs documentation for the string format
64
+ # @param area [Area] If an area is specified a more accurate transformation between two given systems can be chosen
65
+ # @param context [Context]
66
+ # @param authority [String] Restricts the authority of coordinate operations looked up in the database
67
+ # @param accuracy [Float] Sets the minimum desired accuracy (in metres) of the candidate coordinate operations
68
+ # @param allow_ballpark [Boolean] Set to false to disallow the use of Ballpark transformation in the candidate coordinate operations.
69
+ # @param only_best [Boolean] Set to true to cause PROJ to error out if the best transformation cannot be used. Requires Proj 9.2 and higher
70
+ #
71
+ # @return [Transformation] A new transformation
72
+ def initialize(source, target, context=nil,
73
+ area: nil, authority: nil, accuracy: nil, allow_ballpark: nil, only_best: nil, force_over: nil)
74
+
75
+ context ||= Context.current
76
+
77
+ options = Options.new("AUTHORITY": authority,
78
+ "ACCURACY": accuracy.nil? ? nil : accuracy.to_s,
79
+ "ALLOW_BALLPARK": allow_ballpark.nil? ? nil : (allow_ballpark ? "YES" : "NO"),
80
+ "ONLY_BEST": only_best.nil? ? nil : (only_best ? "YES" : "NO"),
81
+ "FORCE_OVER": force_over.nil? ? nil : (force_over ? "YES" : "NO"))
82
+
83
+ ptr = if source.is_a?(Crs) && target.is_a?(Crs)
84
+ if Api.method_defined?(:proj_create_crs_to_crs_from_pj)
85
+ Api.proj_create_crs_to_crs_from_pj(context, source, target, area, options)
86
+ else
87
+ Api.proj_create_crs_to_crs(context, source.definition, target.definition, area)
88
+ end
89
+ else
90
+ Api.proj_create_crs_to_crs(context, source, target, nil)
91
+ end
92
+
93
+ if ptr.null?
94
+ Error.check_context(context)
95
+ # If that does not raise an error then no operation was found
96
+ raise(Error, "No operation found matching criteria")
97
+ end
98
+
99
+ super(ptr, context)
100
+ end
101
+ end
102
+ end