proj4rb 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +26 -15
  3. data/README.rdoc +82 -44
  4. data/Rakefile +27 -27
  5. data/lib/api/api.rb +96 -118
  6. data/lib/api/api_5_0.rb +331 -300
  7. data/lib/api/api_5_1.rb +6 -6
  8. data/lib/api/api_5_2.rb +4 -4
  9. data/lib/api/api_6_0.rb +116 -14
  10. data/lib/api/api_6_1.rb +4 -4
  11. data/lib/api/api_6_2.rb +9 -6
  12. data/lib/api/api_6_3.rb +6 -0
  13. data/lib/api/api_7_0.rb +68 -0
  14. data/lib/api/api_7_1.rb +73 -0
  15. data/lib/api/api_7_2.rb +14 -0
  16. data/lib/api/api_8_0.rb +6 -0
  17. data/lib/api/api_8_1.rb +24 -0
  18. data/lib/api/api_8_2.rb +6 -0
  19. data/lib/api/api_9_1.rb +7 -0
  20. data/lib/api/api_9_2.rb +9 -0
  21. data/lib/api/api_experimental.rb +196 -0
  22. data/lib/proj/area.rb +73 -32
  23. data/lib/proj/axis_info.rb +44 -0
  24. data/lib/proj/bounds.rb +13 -0
  25. data/lib/proj/context.rb +174 -28
  26. data/lib/proj/conversion.rb +92 -0
  27. data/lib/proj/coordinate.rb +281 -197
  28. data/lib/proj/coordinate_operation_mixin.rb +381 -0
  29. data/lib/proj/coordinate_system.rb +137 -0
  30. data/lib/proj/crs.rb +672 -204
  31. data/lib/proj/crs_info.rb +47 -0
  32. data/lib/proj/database.rb +305 -0
  33. data/lib/proj/datum.rb +32 -0
  34. data/lib/proj/datum_ensemble.rb +34 -0
  35. data/lib/proj/ellipsoid.rb +77 -41
  36. data/lib/proj/error.rb +62 -9
  37. data/lib/proj/file_api.rb +166 -0
  38. data/lib/proj/grid.rb +121 -0
  39. data/lib/proj/grid_cache.rb +64 -0
  40. data/lib/proj/grid_info.rb +19 -0
  41. data/lib/proj/network_api.rb +92 -0
  42. data/lib/proj/operation.rb +42 -42
  43. data/lib/proj/operation_factory_context.rb +136 -0
  44. data/lib/proj/parameter.rb +38 -0
  45. data/lib/proj/parameters.rb +106 -0
  46. data/lib/proj/pj_object.rb +670 -80
  47. data/lib/proj/pj_objects.rb +44 -0
  48. data/lib/proj/prime_meridian.rb +65 -39
  49. data/lib/proj/projection.rb +698 -207
  50. data/lib/proj/session.rb +46 -0
  51. data/lib/proj/strings.rb +32 -0
  52. data/lib/proj/transformation.rb +101 -60
  53. data/lib/proj/unit.rb +108 -53
  54. data/lib/proj.rb +110 -9
  55. data/proj4rb.gemspec +5 -5
  56. data/test/abstract_test.rb +23 -1
  57. data/test/context_test.rb +172 -82
  58. data/test/conversion_test.rb +368 -0
  59. data/test/coordinate_system_test.rb +144 -0
  60. data/test/crs_test.rb +770 -71
  61. data/test/database_test.rb +360 -0
  62. data/test/datum_ensemble_test.rb +65 -0
  63. data/test/datum_test.rb +55 -0
  64. data/test/ellipsoid_test.rb +64 -18
  65. data/test/file_api_test.rb +66 -0
  66. data/test/grid_cache_test.rb +72 -0
  67. data/test/grid_test.rb +141 -0
  68. data/test/network_api_test.rb +45 -0
  69. data/test/operation_factory_context_test.rb +201 -0
  70. data/test/parameters_test.rb +40 -0
  71. data/test/pj_object_test.rb +179 -0
  72. data/test/prime_meridian_test.rb +76 -0
  73. data/test/proj_test.rb +46 -4
  74. data/test/projection_test.rb +646 -222
  75. data/test/session_test.rb +78 -0
  76. data/test/transformation_test.rb +149 -7
  77. data/test/unit_test.rb +57 -28
  78. metadata +51 -13
  79. data/lib/api/api_4_9.rb +0 -31
  80. data/lib/proj/config.rb +0 -70
  81. data/lib/proj/point.rb +0 -72
  82. data/test/prime_meridians_test.rb +0 -33
@@ -0,0 +1,381 @@
1
+ # encoding: UTF-8
2
+ require 'stringio'
3
+
4
+ module Proj
5
+ Param = Struct.new(:name, :auth_name, :code, :value, :value_string,
6
+ :unit_conv_factor, :unit_name, :unit_auth_name, :unit_code, :unit_category,
7
+ keyword_init: true)
8
+
9
+ # Coordinate Operations convert {Coordinate coordintates} to a new value. In Proj they are
10
+ # can either by {Conversion conversions} that do not exert a change in reference frame
11
+ # or {Transformation transformations} which do.
12
+ module CoordinateOperationMixin
13
+ # Return whether a coordinate operation can be instantiated as a PROJ pipeline, checking in particular that referenced grids are available.
14
+ #
15
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_is_instantiable
16
+ #
17
+ # @return [Boolean]
18
+ def instantiable?
19
+ result = Api.proj_coordoperation_is_instantiable(self.context, self)
20
+ result == 1 ? true : false
21
+ end
22
+
23
+ # Returns a coordinate operation that represents the inverse operation of this operation
24
+ #
25
+ # @return [Conversion, Transformation] Returns nil on error
26
+ def create_inverse
27
+ ptr = Api.proj_coordoperation_create_inverse(self.context, self)
28
+ self.class.create_object(ptr, self.context)
29
+ end
30
+
31
+ # @!visibility private
32
+ def method_info
33
+ out_method_name = FFI::MemoryPointer.new(:string)
34
+ out_method_auth_name = FFI::MemoryPointer.new(:string)
35
+ out_method_code = FFI::MemoryPointer.new(:string)
36
+
37
+ result = Api.proj_coordoperation_get_method_info(self.context, self, out_method_name, out_method_auth_name, out_method_code)
38
+
39
+ if result != 1
40
+ Error.check_object(self)
41
+ end
42
+
43
+ {:method_name => out_method_name.read_pointer.read_string_to_null,
44
+ :method_auth_name => out_method_auth_name.read_pointer.read_string_to_null,
45
+ :method_code => out_method_code.read_pointer.read_string_to_null}
46
+ end
47
+
48
+ # Returns the operation name
49
+ #
50
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info
51
+ #
52
+ # @return [String]
53
+ def method_name
54
+ method_info[:method_name]
55
+ end
56
+
57
+ # Returns the operation authority name
58
+ #
59
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info
60
+ #
61
+ # @return [String]
62
+ def method_auth_name
63
+ method_info[:method_auth_name]
64
+ end
65
+
66
+ # Returns the operation code
67
+ #
68
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info
69
+ #
70
+ # @return [String]
71
+ def method_code
72
+ method_info[:method_code]
73
+ end
74
+
75
+ # Returns the number of parameters of a SingleOperation
76
+ #
77
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_param_count
78
+ #
79
+ # @return [Integer]
80
+ def param_count
81
+ Api.proj_coordoperation_get_param_count(self.context, self)
82
+ end
83
+
84
+ # Returns the index of a parameter of a SingleOperation
85
+ #
86
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_param_index
87
+ #
88
+ # @param name [String] Name of the parameter. Must not be nil
89
+ #
90
+ # @return [Integer] Index of the parameter or -1 in case of error.
91
+ def param_index(name)
92
+ Api.proj_coordoperation_get_param_index(self.context, self, name)
93
+ end
94
+
95
+ # Returns a parameter of a SingleOperation
96
+ #
97
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_param
98
+ #
99
+ # @param index [Integer] Parameter index
100
+ #
101
+ # @return [Param]
102
+ def param(index)
103
+ out_name = FFI::MemoryPointer.new(:string)
104
+ out_auth_name = FFI::MemoryPointer.new(:string)
105
+ out_code = FFI::MemoryPointer.new(:string)
106
+ out_value = FFI::MemoryPointer.new(:double)
107
+ out_value_string = FFI::MemoryPointer.new(:string)
108
+ out_unit_conv_factor = FFI::MemoryPointer.new(:double)
109
+ out_unit_name = FFI::MemoryPointer.new(:string)
110
+ out_unit_auth_name = FFI::MemoryPointer.new(:string)
111
+ out_unit_code = FFI::MemoryPointer.new(:string)
112
+ out_unit_category = FFI::MemoryPointer.new(:string)
113
+
114
+ result = Api.proj_coordoperation_get_param(self.context, self, index,
115
+ out_name, out_auth_name, out_code,
116
+ out_value, out_value_string,
117
+ out_unit_conv_factor,
118
+ out_unit_name, out_unit_auth_name,out_unit_code,
119
+ out_unit_category)
120
+ if result != 1
121
+ Error.check_object(self)
122
+ end
123
+
124
+ name_ptr = out_name.read_pointer
125
+ auth_name_ptr = out_auth_name.read_pointer
126
+ code_ptr = out_code.read_pointer
127
+ value_string_ptr = out_value_string.read_pointer
128
+ unit_name_ptr = out_unit_name.read_pointer
129
+ unit_auth_name_ptr = out_unit_auth_name.read_pointer
130
+ unit_code_ptr = out_unit_code.read_pointer
131
+ unit_category_ptr = out_unit_category.read_pointer
132
+
133
+ Param.new(name: name_ptr.null? ? nil : name_ptr.read_string_to_null,
134
+ auth_name: auth_name_ptr.null? ? nil : auth_name_ptr.read_string_to_null,
135
+ code: code_ptr.null? ? nil : code_ptr.read_string_to_null,
136
+ value: out_value.null? ? nil : out_value.read_double,
137
+ value_string: value_string_ptr.null? ? nil : value_string_ptr.read_string_to_null,
138
+ unit_conv_factor: out_unit_conv_factor.null? ? nil : out_unit_conv_factor.read_double,
139
+ unit_name: unit_name_ptr.null? ? nil : unit_name_ptr.read_string_to_null,
140
+ unit_auth_name: unit_auth_name_ptr.null? ? nil : unit_auth_name_ptr.read_string_to_null,
141
+ unit_code: unit_code_ptr.null? ? nil : unit_code_ptr.read_string_to_null,
142
+ unit_category: unit_category_ptr.null? ? nil : unit_category_ptr.read_string_to_null)
143
+ end
144
+
145
+ # Transforms a {Coordinate} from the source {Crs} to the target {Crs}. Coordinates should be expressed in
146
+ # the units and axis order of the definition of the source CRS. The returned transformed coordinate will
147
+ # be in the units and axis order of the definition of the target CRS.
148
+ #
149
+ # @see https://proj.org/development/reference/functions.html#c.proj_trans
150
+ #
151
+ # @param coord [Coordinate]
152
+ #
153
+ # @return [Coordinate]
154
+ def forward(coord)
155
+ self.transform(coord, :PJ_FWD)
156
+ end
157
+
158
+ # Transforms a {Coordinate} from the target {Crs} to the source {Crs}. Coordinates should be expressed in
159
+ # the units and axis order of the definition of the source CRS. The returned transformed coordinate will
160
+ # be in the units and axis order of the definition of the target CRS.
161
+ #
162
+ # @see https://proj.org/development/reference/functions.html#c.proj_trans
163
+ #
164
+ # @param coord [Coordinate]
165
+ #
166
+ # @return [Coordinate]
167
+ def inverse(coord)
168
+ self.transform(coord, :PJ_INV)
169
+ end
170
+
171
+ # Transforms a {Coordinate} in the specified direction. See {CoordinateOperation#forward forward} and
172
+ # {CoordinateOperation#inverse inverse}
173
+ #
174
+ # @see https://proj.org/development/reference/functions.html#c.proj_trans
175
+ #
176
+ # @param direction [PJ_DIRECTION] Direction of transformation (:PJ_FWD or :PJ_INV)
177
+ # @param coord [Coordinate]
178
+ #
179
+ # @return [Coordinate]
180
+ def transform(coord, direction)
181
+ struct = Api.proj_trans(self, direction, coord)
182
+ Coordinate.from_coord(struct)
183
+ end
184
+
185
+ # Transform boundary densifying the edges to account for nonlinear transformations along these edges
186
+ # and extracting the outermost bounds.
187
+ #
188
+ # @see https://proj.org/development/reference/functions.html#c.proj_trans_bounds
189
+ #
190
+ # @param bounds [Area] Bounding box in source CRS (target CRS if direction is inverse).
191
+ # @param direction [PJ_DIRECTION] The direction of the transformation.
192
+ # @param densify_points [Integer] Recommended to use 21. This is the number of points to use to densify the bounding polygon in the transformation.
193
+ #
194
+ # @return [Area] Bounding box in target CRS (target CRS if direction is inverse).
195
+ def transform_bounds(bounds, direction, densify_points = 21)
196
+ out_xmin = FFI::MemoryPointer.new(:double)
197
+ out_ymin = FFI::MemoryPointer.new(:double)
198
+ out_xmax = FFI::MemoryPointer.new(:double)
199
+ out_ymax = FFI::MemoryPointer.new(:double)
200
+
201
+ result = Api.proj_trans_bounds(self.context, self, direction,
202
+ bounds.xmin, bounds.ymin, bounds.xmax, bounds.ymax,
203
+ out_xmin, out_ymin, out_xmax, out_ymax, densify_points)
204
+
205
+ unless result == 0
206
+ Error.check_object(self)
207
+ end
208
+
209
+ Bounds.new(out_xmin.read_double, out_ymin.read_double, out_xmax.read_double, out_ymax.read_double)
210
+ end
211
+
212
+ # Transforms an array of {Coordinate coordinates}. Individual points that fail to transform
213
+ # will have their components set to Infinity.
214
+ #
215
+ # @param array [Array<Coordinate>] Coordinates to transform
216
+ # @param direction [PJ_DIRECTION] The direction of the transformation
217
+ #
218
+ # @return [Array<Coordinate>] Array of transformed coordinates
219
+ def transform_array(coordinates, direction)
220
+ coords_ptr = FFI::MemoryPointer.new(Api::PJ_COORD, coordinates.size)
221
+ coordinates.each_with_index do |coordinate, i|
222
+ pj_coord = Api::PJ_COORD.new(coords_ptr[i])
223
+ pj_coord.to_ptr.__copy_from__(coordinate.to_ptr, Api::PJ_COORD.size)
224
+ end
225
+
226
+ int = Api.proj_trans_array(self, direction, coordinates.size, coords_ptr)
227
+ unless int == 0
228
+ Error.check_object(self)
229
+ end
230
+
231
+ result = Array.new(coordinates.size)
232
+ 0.upto(coordinates.size) do |i|
233
+ pj_coord = Api::PJ_COORD.new(coords_ptr[i])
234
+ result[i] = Coordinate.from_coord(pj_coord)
235
+ end
236
+ result
237
+ end
238
+
239
+ # Measure the internal consistency of a given transformation. The function performs n round trip
240
+ # transformations starting in either the forward or reverse direction.
241
+ #
242
+ # @see https://proj.org/development/reference/functions.html#c.proj_roundtrip
243
+ #
244
+ # @param direction [PJ_DIRECTION] The starting direction of transformation
245
+ # @param iterations [Integer] The number of roundtrip transformations
246
+ # @param coordinate [Coordinate] The input coordinate
247
+ #
248
+ # @return [Double] The euclidean distance of the starting point coordinate and the last coordinate after n iterations back and forth.
249
+ def roundtrip(direction, iterations, coordinate)
250
+ Api.proj_roundtrip(self, direction, iterations, coordinate.pj_coord)
251
+ end
252
+
253
+ # Returns a new PJ object whose axis order is the one expected for visualization purposes
254
+ #
255
+ # @see https://proj.org/development/reference/functions.html#c.proj_normalize_for_visualization
256
+ #
257
+ # @return [CoordinateOperation] A new CoordinateOperation or nil in case of error
258
+ def normalize_for_visualization
259
+ ptr = Api.proj_normalize_for_visualization(self.context, self)
260
+ self.class.create_object(ptr, self.context)
261
+ end
262
+
263
+ # Return the operation used during the last invocation of Transformation#forward or Transformation#inverse
264
+ #
265
+ # @see }https://proj.org/development/reference/functions.html#c.proj_trans_get_last_used_operation proj_trans_get_last_used_operation
266
+ #
267
+ # @return [CoordinateOperation] The last used operation
268
+ def last_used_operation
269
+ ptr = Api.proj_trans_get_last_used_operation(self)
270
+ self.class.create_object(ptr, self.context)
271
+ end
272
+
273
+ # Return whether a coordinate operation has a "ballpark" transformation
274
+ #
275
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_has_ballpark_transformation
276
+ #
277
+ # @return [Boolean]
278
+ def ballpark_transformation?
279
+ result = Api.proj_coordoperation_has_ballpark_transformation(Context.current, self)
280
+ result == 1 ? true : false
281
+ end
282
+
283
+ # Returns the accuracy (in meters) of a coordinate operation.
284
+ #
285
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_accuracy
286
+ #
287
+ # @return [Double] The accuracy, or a negative value if unknown or in case of error.
288
+ def accuracy
289
+ Api.proj_coordoperation_get_accuracy(self.context, self)
290
+ end
291
+
292
+ # Returns the number of grids used by a CoordinateOperation
293
+ #
294
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_grid_used_count
295
+ #
296
+ # @return [Integer]
297
+ def grid_count
298
+ Api.proj_coordoperation_get_grid_used_count(self.context, self)
299
+ end
300
+
301
+ # Returns information about a Grid
302
+ #
303
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_grid_used
304
+ #
305
+ # @param index [Integer] Grid index
306
+ #
307
+ # @return [Integer]
308
+ def grid(index)
309
+ out_short_name = FFI::MemoryPointer.new(:string)
310
+ out_full_name = FFI::MemoryPointer.new(:string)
311
+ out_package_name = FFI::MemoryPointer.new(:string)
312
+ out_url = FFI::MemoryPointer.new(:string)
313
+ out_direct_download = FFI::MemoryPointer.new(:int)
314
+ out_open_license = FFI::MemoryPointer.new(:int)
315
+ out_available = FFI::MemoryPointer.new(:int)
316
+
317
+ result = Api.proj_coordoperation_get_grid_used(self.context, self, index,
318
+ out_short_name, out_full_name, out_package_name,
319
+ out_url, out_direct_download ,
320
+ out_open_license, out_available)
321
+
322
+ if result != 1
323
+ Error.check_object(self)
324
+ end
325
+
326
+ name_ptr = out_short_name.read_pointer
327
+ full_name_ptr = out_full_name.read_pointer
328
+ package_name_ptr = out_package_name.read_pointer
329
+ url_ptr = out_url.read_pointer
330
+ downloadable_ptr = out_direct_download
331
+ open_license_ptr = out_open_license
332
+ available_ptr = out_available
333
+
334
+ unless name_ptr.null?
335
+ Grid.new(name_ptr.read_string_to_null, self.context,
336
+ full_name: full_name_ptr.null? ? nil : full_name_ptr.read_string_to_null,
337
+ package_name: package_name_ptr.null? ? nil : package_name_ptr.read_string_to_null,
338
+ url: url_ptr.null? ? nil : url_ptr.read_string_to_null,
339
+ downloadable: downloadable_ptr.null? ? nil : downloadable_ptr.read_int == 1 ? true : false,
340
+ open_license: open_license_ptr.null? ? nil : open_license_ptr.read_int == 1 ? true : false,
341
+ available: available_ptr.null? ? nil : available_ptr.read_int == 1 ? true : false)
342
+ end
343
+ end
344
+
345
+ # Return the parameters of a Helmert transformation as WKT1 TOWGS84 values
346
+ #
347
+ # @see https://proj.org/development/reference/functions.html#c.proj_coordoperation_get_towgs84_values
348
+ #
349
+ # @param error_if_incompatible [Boolean] If true an exception is thrown if the coordinate operation is not compatible with a WKT1 TOWGS84 representation
350
+ #
351
+ # @return [Array<Double>] Array of 7 numbers that represent translation, rotation and scale parameters.
352
+ # Rotation and scale difference terms might be zero if the transformation only includes translation parameters
353
+ def to_wgs84(error_if_incompatible = false)
354
+ parameter_count = 7
355
+ out_values = FFI::MemoryPointer.new(:double, parameter_count)
356
+ Api.proj_coordoperation_get_towgs84_values(self.context, self, out_values, parameter_count, error_if_incompatible ? 1 : 0)
357
+ out_values.read_array_of_double(parameter_count)
358
+ end
359
+
360
+ # Returns the number of steps in a concatenated operation
361
+ #
362
+ # @see https://proj.org/development/reference/functions.html#c.proj_concatoperation_get_step_count
363
+ #
364
+ # @return [Integer] The number of steps
365
+ def step_count
366
+ Api.proj_concatoperation_get_step_count(self.context, self)
367
+ end
368
+
369
+ # Returns a step of a concatenated operation
370
+ #
371
+ # @see https://proj.org/development/reference/functions.html#c.proj_concatoperation_get_step
372
+ #
373
+ # @param index [Integer] Index of the step
374
+ #
375
+ # @return [PjObject]
376
+ def step(index)
377
+ ptr = Api.proj_concatoperation_get_step(self.context, self, index)
378
+ self.class.create_object(ptr, self.context)
379
+ end
380
+ end
381
+ end
@@ -0,0 +1,137 @@
1
+ # encoding: UTF-8
2
+
3
+ module Proj
4
+ # Represents a coordinate system for a {Crs CRS}
5
+ class CoordinateSystem < PjObject
6
+ # Create a CoordinateSystem
7
+ #
8
+ # @param context [Context] The context associated with the CoordinateSystem
9
+ # @param type [PJ_COORDINATE_SYSTEM_TYPE] Coordinate system type
10
+ # @param axes [Array<PJ_AXIS_DESCRIPTION>] Array of Axes
11
+ #
12
+ # @return [CoordinateSystem]
13
+ def self.create(type, axes, context)
14
+ axes_ptr = FFI::MemoryPointer.new(Api::PJ_AXIS_DESCRIPTION, axes.size)
15
+ axes.each_with_index do |axis, i|
16
+ axis_description_target = Api::PJ_AXIS_DESCRIPTION.new(axes_ptr[i])
17
+ axis_description_source = axis.to_description
18
+ axis_description_target.to_ptr.__copy_from__(axis_description_source.to_ptr, Api::PJ_AXIS_DESCRIPTION.size)
19
+ end
20
+
21
+ pointer = Api.proj_create_cs(context, type, axes.count, axes_ptr)
22
+ Error.check_context(context)
23
+ self.create_object(pointer, context)
24
+ end
25
+
26
+ # Create an Ellipsoidal 2D CoordinateSystem
27
+ #
28
+ # @param context [Context] The context associated with the CoordinateSystem
29
+ # @param type [PJ_COORDINATE_SYSTEM_TYPE] Coordinate system type
30
+ # @param unit_name [String] Name of the angular units. Or nil for degree
31
+ # @param unit_conv_factor [Double] Conversion factor from the angular unit to radian. Set to 0 if unit name is degree
32
+ #
33
+ # @return [CoordinateSystem]
34
+ def self.create_ellipsoidal_2d(type, context, unit_name: nil, unit_conv_factor: 0)
35
+ pointer = Api.proj_create_ellipsoidal_2D_cs(context, type, unit_name, unit_conv_factor)
36
+ Error.check_context(context)
37
+ self.create_object(pointer, context)
38
+ end
39
+
40
+ # Create an Ellipsoidal 3D CoordinateSystem
41
+ #
42
+ # @param context [Context] The context associated with the CoordinateSystem
43
+ # @param type [PJ_COORDINATE_SYSTEM_TYPE] Coordinate system type
44
+ # @param horizontal_angular_unit_name [String] Name of the angular units. Or nil for degree
45
+ # @param horizontal_angular_unit_conv_factor [Double] Conversion factor from the angular unit to radian. Set to 0 if horizontal_angular_unit_name name is degree
46
+ # @param vertical_linear_unit_name [String] Name of the angular units. Or nil for meter
47
+ # @param vertical_linear_unit_conv_factor [Double] Conversion factor from the linear unit to meter. Set to 0 if vertical_linear_unit_name name is meter
48
+ #
49
+ # @return [CoordinateSystem]
50
+ def self.create_ellipsoidal_3d(type, context, horizontal_angular_unit_name: nil, horizontal_angular_unit_conv_factor: 0, vertical_linear_unit_name: nil, vertical_linear_unit_conv_factor: 0)
51
+ pointer = Api.proj_create_ellipsoidal_3D_cs(context, type, horizontal_angular_unit_name, horizontal_angular_unit_conv_factor, vertical_linear_unit_name, vertical_linear_unit_conv_factor)
52
+ Error.check_context(context)
53
+ self.create_object(pointer, context)
54
+ end
55
+
56
+ # Create a CartesiansCS 2D coordinate system
57
+ #
58
+ # @param context [Context] The context associated with the CoordinateSystem
59
+ # @param type [PJ_COORDINATE_SYSTEM_TYPE] Coordinate system type
60
+ # @param unit_name [String] Name of the unit. Default is nil.
61
+ # @param unit_conv_factor [Double] Unit conversion factor to SI. Default is 0.
62
+ #
63
+ # @return [CoordinateSystem]
64
+ def self.create_cartesian_2d(context, type, unit_name: nil, unit_conv_factor: 0)
65
+ pointer = Api.proj_create_cartesian_2D_cs(context, type, unit_name, unit_conv_factor)
66
+ Error.check_context(context)
67
+ self.create_object(pointer, context)
68
+ end
69
+
70
+ # Returns the type of the coordinate system
71
+ #
72
+ # @see https://proj.org/development/reference/functions.html#c.proj_cs_get_type
73
+ #
74
+ # @return [PJ_COORDINATE_SYSTEM_TYPE]
75
+ def type
76
+ result = Api.proj_cs_get_type(self.context, self)
77
+ if result == :PJ_CS_TYPE_UNKNOWN
78
+ Error.check_object(self)
79
+ end
80
+ result
81
+ end
82
+
83
+ # Returns the number of axes in the coordinate system
84
+ #
85
+ # @see https://proj.org/development/reference/functions.html#c.proj_cs_get_axis_count
86
+ #
87
+ # @return [Integer]
88
+ def axis_count
89
+ result = Api.proj_cs_get_axis_count(self.context, self)
90
+ if result == -1
91
+ Error.check_object(self)
92
+ end
93
+ result
94
+ end
95
+
96
+ # Returns information about a single axis
97
+ #
98
+ # @see https://proj.org/development/reference/functions.html#c.proj_cs_get_axis_info
99
+ #
100
+ # @param index [Integer] Index of the axis
101
+ #
102
+ # @return [AxisInfo]
103
+ def axis_info(index)
104
+ p_name = FFI::MemoryPointer.new(:pointer)
105
+ p_abbreviation = FFI::MemoryPointer.new(:pointer)
106
+ p_direction = FFI::MemoryPointer.new(:pointer)
107
+ p_unit_conv_factor = FFI::MemoryPointer.new(:double)
108
+ p_unit_name = FFI::MemoryPointer.new(:pointer)
109
+ p_unit_auth_name = FFI::MemoryPointer.new(:pointer)
110
+ p_unit_code = FFI::MemoryPointer.new(:pointer)
111
+
112
+ result = Api.proj_cs_get_axis_info(self.context, self, index,
113
+ p_name, p_abbreviation, p_direction, p_unit_conv_factor, p_unit_name, p_unit_auth_name, p_unit_code)
114
+
115
+ unless result
116
+ Error.check_object(self)
117
+ end
118
+
119
+ AxisInfo.new(name: p_name.read_pointer.read_string,
120
+ abbreviation: p_abbreviation.read_pointer.read_string_to_null,
121
+ direction: p_direction.read_pointer.read_string_to_null,
122
+ unit_conv_factor: p_unit_conv_factor.read_double,
123
+ unit_name: p_unit_name.read_pointer.read_string_to_null,
124
+ unit_auth_name: p_unit_auth_name.read_pointer.read_string_to_null,
125
+ unit_code: p_unit_code.read_pointer.read_string_to_null)
126
+ end
127
+
128
+ # Returns information about all axes
129
+ #
130
+ # @return [Array<AxisInfo>]
131
+ def axes
132
+ self.axis_count.times.map do |index|
133
+ self.axis_info(index)
134
+ end
135
+ end
136
+ end
137
+ end