proj4rb 2.2.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +82 -66
  3. data/Gemfile +4 -4
  4. data/README.rdoc +82 -45
  5. data/lib/api/api.rb +96 -111
  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 -0
  23. data/lib/proj/axis_info.rb +44 -0
  24. data/lib/proj/bounds.rb +13 -0
  25. data/lib/proj/context.rb +249 -0
  26. data/lib/proj/conversion.rb +92 -0
  27. data/lib/{coordinate.rb → 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 -0
  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 +78 -0
  36. data/lib/proj/error.rb +71 -0
  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/{operation.rb → 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 -0
  47. data/lib/proj/pj_objects.rb +44 -0
  48. data/lib/proj/prime_meridian.rb +66 -0
  49. data/lib/proj/projection.rb +698 -0
  50. data/lib/proj/session.rb +46 -0
  51. data/lib/proj/strings.rb +32 -0
  52. data/lib/proj/transformation.rb +102 -0
  53. data/lib/proj/unit.rb +109 -0
  54. data/lib/proj.rb +118 -17
  55. data/proj4rb.gemspec +32 -32
  56. data/test/abstract_test.rb +29 -7
  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/coordinate_test.rb +34 -34
  61. data/test/crs_test.rb +1071 -372
  62. data/test/database_test.rb +360 -0
  63. data/test/datum_ensemble_test.rb +65 -0
  64. data/test/datum_test.rb +55 -0
  65. data/test/ellipsoid_test.rb +80 -34
  66. data/test/file_api_test.rb +66 -0
  67. data/test/grid_cache_test.rb +72 -0
  68. data/test/grid_test.rb +141 -0
  69. data/test/network_api_test.rb +45 -0
  70. data/test/operation_factory_context_test.rb +201 -0
  71. data/test/operation_test.rb +29 -29
  72. data/test/parameters_test.rb +40 -0
  73. data/test/pj_object_test.rb +179 -0
  74. data/test/prime_meridian_test.rb +76 -0
  75. data/test/proj_test.rb +58 -16
  76. data/test/projection_test.rb +650 -224
  77. data/test/session_test.rb +78 -0
  78. data/test/transformation_test.rb +209 -67
  79. data/test/unit_test.rb +76 -47
  80. metadata +67 -29
  81. data/lib/api/api_4_9.rb +0 -31
  82. data/lib/area.rb +0 -32
  83. data/lib/config.rb +0 -70
  84. data/lib/context.rb +0 -103
  85. data/lib/crs.rb +0 -204
  86. data/lib/ellipsoid.rb +0 -42
  87. data/lib/error.rb +0 -18
  88. data/lib/pj_object.rb +0 -80
  89. data/lib/point.rb +0 -72
  90. data/lib/prime_meridian.rb +0 -40
  91. data/lib/projection.rb +0 -207
  92. data/lib/transformation.rb +0 -61
  93. data/lib/unit.rb +0 -54
  94. data/test/prime_meridians_test.rb +0 -33
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ module Proj
3
+ class CrsInfo
4
+ attr_reader :auth_name, :code, :name, :type, :deprecated, :bbox_valid,
5
+ :west_lon_degree, :south_lat_degree, :east_lon_degree, :north_lat_degree,
6
+ :area_name, :projection_method_name, :celestial_body_name
7
+
8
+ def self.from_proj_crs_info(proj_crs_info)
9
+ data = {auth_name: proj_crs_info[:auth_name],
10
+ code: proj_crs_info[:code],
11
+ name: proj_crs_info[:name],
12
+ type: proj_crs_info[:type],
13
+ deprecated: proj_crs_info[:deprecated] == 1 ? true : false,
14
+ bbox_valid: proj_crs_info[:bbox_valid] == 1 ? true : false,
15
+ west_lon_degree: proj_crs_info[:west_lon_degree],
16
+ south_lat_degree: proj_crs_info[:south_lat_degree],
17
+ east_lon_degree: proj_crs_info[:east_lon_degree],
18
+ north_lat_degree: proj_crs_info[:north_lat_degree],
19
+ area_name: proj_crs_info[:area_name],
20
+ projection_method_name: proj_crs_info[:projection_method_name]}
21
+
22
+ if Api::PROJ_VERSION >= Gem::Version.new('8.1.0')
23
+ data[:celestial_body_name] = proj_crs_info[:celestial_body_name]
24
+ end
25
+
26
+ new(**data)
27
+ end
28
+
29
+ def initialize(auth_name:, code:, name:, type:, deprecated:, bbox_valid:,
30
+ west_lon_degree:, south_lat_degree:, east_lon_degree:, north_lat_degree:,
31
+ area_name:, projection_method_name:, celestial_body_name: nil)
32
+ @auth_name = auth_name
33
+ @code = code
34
+ @name = name
35
+ @type = type
36
+ @deprecated = deprecated
37
+ @bbox_valid = bbox_valid
38
+ @west_lon_degree = west_lon_degree
39
+ @south_lat_degree = south_lat_degree
40
+ @east_lon_degree = east_lon_degree
41
+ @north_lat_degree = north_lat_degree
42
+ @area_name = area_name
43
+ @projection_method_name = projection_method_name
44
+ @celestial_body_name = celestial_body_name
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,305 @@
1
+ module Proj
2
+ CelestialBody = Struct.new(:auth_name, :name)
3
+
4
+ # This class provides access the Proj SQLite database called proj.db. The database
5
+ # stores transformation information that must be accessible for the library to work properly.
6
+ #
7
+ # @see https://proj.org/resource_files.html#proj-db
8
+ class Database
9
+ attr_reader :context
10
+
11
+ # Create a new database instance to query the Proj database
12
+ #
13
+ # @param context [Context] A proj Context
14
+ #
15
+ # @return [Database]
16
+ def initialize(context)
17
+ @context = context
18
+ end
19
+
20
+ # Returns the path the Proj database
21
+ #
22
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_path
23
+ #
24
+ # return [String]
25
+ def path
26
+ if Api.method_defined?(:proj_context_get_database_path)
27
+ Api.proj_context_get_database_path(self.context)
28
+ end
29
+ end
30
+
31
+ # Sets the path to the Proj database
32
+ #
33
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_set_database_path
34
+ #
35
+ # @param value [String] Path to the proj database
36
+ #
37
+ # @return [Database] Returns reference to the current database instance
38
+ def path=(value)
39
+ result = Api.proj_context_set_database_path(self.context, value, nil, nil)
40
+ unless result == 1
41
+ Error.check_context(self.context)
42
+ end
43
+ self
44
+ end
45
+
46
+ # Returns SQL statements to run to initiate a new valid auxiliary empty database.
47
+ #
48
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_structure
49
+ #
50
+ # @return [Array<Strings>] List of sql statements
51
+ def structure
52
+ ptr = Api.proj_context_get_database_structure(self.context, nil)
53
+ Strings.new(ptr)
54
+ end
55
+
56
+ # Return a metadata from the database.
57
+ #
58
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_metadata
59
+ #
60
+ # @param key [String] The name of the metadata item. Must not be nil
61
+ # Available keys:
62
+ # DATABASE.LAYOUT.VERSION.MAJOR
63
+ # DATABASE.LAYOUT.VERSION.MINOR
64
+ # EPSG.VERSION
65
+ # EPSG.DATE
66
+ # ESRI.VERSION
67
+ # ESRI.DATE
68
+ # IGNF.SOURCE
69
+ # IGNF.VERSION
70
+ # IGNF.DATE
71
+ # NKG.SOURCE
72
+ # NKG.VERSION
73
+ # NKG.DATE
74
+ # PROJ.VERSION
75
+ # PROJ_DATA.VERSION
76
+ #
77
+ # @return [String] Returned metadata
78
+ def metadata(key)
79
+ Api.proj_context_get_database_metadata(self.context, key)
80
+ end
81
+
82
+ # Returns the set of authority codes of the given object type.
83
+ #
84
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_codes_from_database
85
+ #
86
+ # @param auth_name [String] Authority name. Must not be nil.
87
+ # @param type [PJ_TYPE] Object type.
88
+ # @param allow_deprecated [Boolean] Specifies if deprecated objects should be returned. Default is false.
89
+ #
90
+ # @return [Strings] Returned authority codes
91
+ def codes(auth_name, type, allow_deprecated = false)
92
+ ptr = Api.proj_get_codes_from_database(self.context, auth_name, type, allow_deprecated ? 1 : 0)
93
+ Strings.new(ptr)
94
+ end
95
+
96
+ # Return a list of authorities used in the database
97
+ #
98
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_authorities_from_database
99
+ #
100
+ # @return [Array<Strings>] List of authorities
101
+ def authorities
102
+ ptr = Api.proj_get_authorities_from_database(self.context)
103
+ Strings.new(ptr)
104
+ end
105
+
106
+ # Enumerate CRS infos from the database, taking into account various criteria.
107
+ #
108
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_crs_info_list_from_database
109
+ #
110
+ # @param auth_name [String] Authority name. Use nil to specify all authorities
111
+ # @param parameters [Parameters] Parameters to specify search criteria. May be nil
112
+ #
113
+ # @return [Array<CrsInfo>] Returned crs infos
114
+ def crs_info(auth_name = nil, parameters = nil)
115
+ out_result_count = FFI::MemoryPointer.new(:int)
116
+ ptr = Api.proj_get_crs_info_list_from_database(self.context, auth_name, parameters, out_result_count)
117
+
118
+ result = out_result_count.read_int.times.map do |index|
119
+ index_ptr = ptr + (index * FFI::Pointer::SIZE)
120
+ struct = Api::PROJ_CRS_INFO.new(index_ptr.read_pointer)
121
+ CrsInfo.from_proj_crs_info(struct)
122
+ end
123
+
124
+ Api.proj_crs_info_list_destroy(ptr)
125
+ result
126
+ end
127
+
128
+ # Returns information about a Grid from the database
129
+ #
130
+ # @see https://proj.org/development/reference/functions.html#c.proj_grid_get_info_from_database
131
+ #
132
+ # @param name [String] The name of the grid
133
+ #
134
+ # @return [Grid]
135
+ def grid(name)
136
+ out_full_name = FFI::MemoryPointer.new(:string)
137
+ out_package_name = FFI::MemoryPointer.new(:string)
138
+ out_url = FFI::MemoryPointer.new(:string)
139
+ out_downloadable = FFI::MemoryPointer.new(:int)
140
+ out_open_license = FFI::MemoryPointer.new(:int)
141
+ out_available = FFI::MemoryPointer.new(:int)
142
+
143
+ result = Api.proj_grid_get_info_from_database(self.context, name,
144
+ out_full_name, out_package_name, out_url,
145
+ out_downloadable, out_open_license, out_available)
146
+
147
+ if result == 1
148
+ full_name_ptr = out_full_name.read_pointer
149
+ package_name_ptr = out_package_name.read_pointer
150
+ url_ptr = out_url.read_pointer
151
+
152
+ downloadable_ptr = out_downloadable
153
+ open_license_ptr = out_open_license
154
+ available_ptr = out_available
155
+
156
+ full_name = full_name_ptr.read_string_to_null
157
+ package_name = package_name_ptr.read_string_to_null
158
+ url = url_ptr.read_string_to_null
159
+
160
+ downloadable = downloadable_ptr.read_int == 1 ? true : false
161
+ open_license = open_license_ptr.read_int == 1 ? true : false
162
+ available = available_ptr.read_int == 1 ? true : false
163
+
164
+ Grid.new(name, self.context,
165
+ full_name: full_name, package_name: package_name,
166
+ url: url ? URI(url) : nil,
167
+ downloadable: downloadable, open_license: open_license, available: available)
168
+ else
169
+ Error.check_context(self.context)
170
+ end
171
+ end
172
+
173
+ # Returns a list of geoid models available
174
+ #
175
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_geoid_models_from_database
176
+ #
177
+ # @param authority [String] Authority name into which the object will be inserted. Must not be nil
178
+ # @param code [Integer] Code with which the object will be inserted.Must not be nil
179
+ #
180
+ # @return [Strings] List of insert statements
181
+ def geoid_models(authority, code)
182
+ ptr = Api.proj_get_geoid_models_from_database(self.context, authority, code, nil)
183
+ Strings.new(ptr)
184
+ end
185
+
186
+ # Returns a list of celestial bodies from the database
187
+ #
188
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_celestial_body_list_from_database
189
+ #
190
+ # @param authority [String] Authority name, used to restrict the search. Set to nil for all authorities.
191
+ #
192
+ # @return [Array<CelestialBody>] List of insert statements
193
+ def celestial_bodies(authority = nil)
194
+ out_result_count = FFI::MemoryPointer.new(:int)
195
+ ptr = Api.proj_get_celestial_body_list_from_database(self.context, authority, out_result_count)
196
+
197
+ body_ptrs = ptr.read_array_of_pointer(out_result_count.read_int)
198
+ result = body_ptrs.map do |body_ptr|
199
+ # First read the pointer to a structure
200
+ struct = Api::ProjCelestialBodyInfo.new(body_ptr)
201
+
202
+ # Now map this to a Ruby Struct
203
+ CelestialBody.new(struct[:auth_name], struct[:name])
204
+ end
205
+
206
+ Api.proj_celestial_body_list_destroy(ptr)
207
+
208
+ result
209
+ end
210
+
211
+ # Return the name of the celestial body of the specified object.
212
+ #
213
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_celestial_body_name
214
+ #
215
+ # @param object [PjObject] Object of type CRS, Datum or Ellipsoid. Must not be nil.
216
+ #
217
+ # @return [String] The name of the celestial body or nil
218
+ def celestial_body_name(object)
219
+ Api.proj_get_celestial_body_name(self.context, object)
220
+ end
221
+
222
+ # Suggests a database code for the specified object.
223
+ #
224
+ # @see https://proj.org/development/reference/functions.html#c.proj_suggests_code_for
225
+ #
226
+ # @param object [PjObject] Object for which to suggest a code.
227
+ # @param authority [String] Authority name into which the object will be inserted.
228
+ # @param numeric_code [Boolean] Whether the code should be numeric, or derived from the object name.
229
+ #
230
+ # @return [String] The suggested code
231
+ def suggest_code_for(object, authority, numeric_code)
232
+ ptr = Api.proj_suggests_code_for(self.context, object, authority, numeric_code ? 1 : 0, nil)
233
+ result = ptr.read_string_to_null
234
+ Api.proj_string_destroy(ptr)
235
+ result
236
+ end
237
+
238
+ # Returns a list of units from the database
239
+ #
240
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_units_from_database
241
+ #
242
+ # @param auth_name [String] Authority name, used to restrict the search. Or nil for all authorities.
243
+ # @param category [String] Filter by category, if this parameter is not nil. Category is one of "linear", "linear_per_time", "angular", "angular_per_time", "scale", "scale_per_time" or "time
244
+ # @param allow_deprecated [Boolean] Whether deprecated units should also be returned. Default false.
245
+ #
246
+ # @return [Array<Unit>] Array of units
247
+ def units(auth_name: nil, category: nil, allow_deprecated: false)
248
+ # Create pointer to read the count output parameter
249
+ out_result_count = FFI::MemoryPointer.new(:int)
250
+
251
+ # Result is an array of pointers to structures
252
+ pp_units = Api.proj_get_units_from_database(Context.current, auth_name, category, allow_deprecated ? 1 : 0, out_result_count)
253
+ count = out_result_count.read(:int)
254
+ array_p_units = pp_units.read_array_of_pointer(count)
255
+
256
+ result = Array.new(count)
257
+ count.times do |i|
258
+ unit_info = Api::PROJ_UNIT_INFO.new(array_p_units[i])
259
+
260
+ result[i] = Unit.new(unit_info[:auth_name],
261
+ unit_info[:code],
262
+ unit_info[:name],
263
+ unit_info[:category],
264
+ unit_info[:conv_factor],
265
+ unit_info[:proj_short_name],
266
+ unit_info[:deprecated])
267
+ end
268
+
269
+ Api.proj_unit_list_destroy(pp_units)
270
+
271
+ result
272
+ end
273
+
274
+ # Returns information for a unit of measure from a database lookup
275
+ #
276
+ # @see https://proj.org/development/reference/functions.html#c.proj_uom_get_info_from_database
277
+ #
278
+ # @param auth_name [String] Authority name
279
+ # @param code [String] Unit of measure code
280
+ #
281
+ # @return [Unit] Unit
282
+ def unit(auth_name, code)
283
+ out_name = FFI::MemoryPointer.new(:string)
284
+ out_conv_factor = FFI::MemoryPointer.new(:double)
285
+ out_category = FFI::MemoryPointer.new(:string)
286
+
287
+ result = Api.proj_uom_get_info_from_database(self.context, auth_name, code,
288
+ out_name, out_conv_factor , out_category)
289
+
290
+ if result == 1
291
+ name_ptr = out_name.read_pointer
292
+ conv_factor_ptr = out_conv_factor
293
+ category_ptr = out_category.read_pointer
294
+
295
+ name = name_ptr.read_string_to_null
296
+ conv_factor = conv_factor_ptr.read_double
297
+ category = category_ptr.read_string_to_null
298
+
299
+ Unit.new(auth_name, code, name, category, conv_factor, nil, false)
300
+ else
301
+ Error.check_context(self.context)
302
+ end
303
+ end
304
+ end
305
+ end
data/lib/proj/datum.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Proj
2
+ class Datum < PjObject
3
+ # Returns the frame reference epoch of a dynamic geodetic or vertical reference frame
4
+ #
5
+ # @see https://proj.org/development/reference/functions.html#c.proj_dynamic_datum_get_frame_reference_epoch
6
+ #
7
+ # @return [Double] The frame reference epoch as decimal year, or -1 in case of error.
8
+ def frame_reference_epoch
9
+ Api.proj_dynamic_datum_get_frame_reference_epoch(self.context, self)
10
+ end
11
+
12
+ # Return the ellipsoid
13
+ #
14
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_ellipsoid
15
+ #
16
+ # @return [PjObject]
17
+ def ellipsoid
18
+ ptr = Api.proj_get_ellipsoid(self.context, self)
19
+ self.class.create_object(ptr, self.context)
20
+ end
21
+
22
+ # Returns the prime meridian
23
+ #
24
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_prime_meridian
25
+ #
26
+ # @return [PjObject]
27
+ def prime_meridian
28
+ ptr = Api.proj_get_prime_meridian(self.context, self)
29
+ self.class.create_object(ptr, self.context)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ module Proj
2
+ class DatumEnsemble < PjObject
3
+
4
+ # Returns the number of members of a datum ensemble
5
+ #
6
+ # @see https://proj.org/development/reference/functions.html#c.proj_datum_ensemble_get_member_count
7
+ #
8
+ # @return [Integer]
9
+ def count
10
+ Api.proj_datum_ensemble_get_member_count(self.context, self)
11
+ end
12
+
13
+ # Returns a member from a datum ensemble.
14
+ #
15
+ # @see https://proj.org/development/reference/functions.html#c.proj_datum_ensemble_get_member
16
+ #
17
+ # @param index [Integer] Index of the datum member to extract. Should be between 0 and DatumEnsembel#count - 1.
18
+ #
19
+ # @return [Integer]
20
+ def [](index)
21
+ ptr = Api.proj_datum_ensemble_get_member(self.context, self, index)
22
+ self.class.create_object(ptr, self.context)
23
+ end
24
+
25
+ # Returns the positional accuracy of the datum ensemble
26
+ #
27
+ # @see https://proj.org/development/reference/functions.html#c.proj_datum_ensemble_get_accuracy
28
+ #
29
+ # @return [Float] The data ensemble accuracy or -1 in case of error
30
+ def accuracy
31
+ Api.proj_datum_ensemble_get_accuracy(self.context, self)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,78 @@
1
+ module Proj
2
+ class Ellipsoid < PjObject
3
+ # Returns a list of ellipsoids 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_ELLPS, Api.proj_list_ellps)
7
+
8
+ result = Array.new
9
+ 0.step do |i|
10
+ pj_ellps = Api::PJ_ELLPS.new(pointer_to_array[i])
11
+ break result if pj_ellps[:id].nil?
12
+ result << pj_ellps
13
+ end
14
+ result
15
+ end
16
+
17
+ # Returns ellipsoid parameters
18
+ #
19
+ # @see https://proj.org/development/reference/functions.html#c.proj_ellipsoid_get_parameters
20
+ #
21
+ # @return [Hash] Hash of ellipsoid parameters. Axes are in meters
22
+ def parameters
23
+ @parameters ||= begin
24
+ out_semi_major_metre = FFI::MemoryPointer.new(:double)
25
+ out_semi_minor_metre = FFI::MemoryPointer.new(:double)
26
+ out_is_semi_minor_computed = FFI::MemoryPointer.new(:int)
27
+ out_inv_flattening = FFI::MemoryPointer.new(:double)
28
+
29
+ result = Api.proj_ellipsoid_get_parameters(self.context, self, out_semi_major_metre, out_semi_minor_metre, out_is_semi_minor_computed, out_inv_flattening)
30
+
31
+ if result != 1
32
+ Error.check_object(self)
33
+ end
34
+
35
+ {semi_major_axis: out_semi_major_metre.read_double,
36
+ semi_minor_axis: out_semi_minor_metre.read_double,
37
+ semi_minor_axis_computed: out_is_semi_minor_computed.read_int == 1 ? true : false,
38
+ inverse_flattening: out_inv_flattening.null? ? nil : out_inv_flattening.read_double}
39
+ end
40
+ end
41
+
42
+ # Returns the semi-major axis in meters
43
+ #
44
+ # @see https://proj.org/development/reference/functions.html#c.proj_ellipsoid_get_parameters
45
+ #
46
+ # @return [Double]
47
+ def semi_major_axis
48
+ self.parameters[:semi_major_axis]
49
+ end
50
+
51
+ # Returns the semi-minor axis in meters
52
+ #
53
+ # @see https://proj.org/development/reference/functions.html#c.proj_ellipsoid_get_parameters
54
+ #
55
+ # @return [Double]
56
+ def semi_minor_axis
57
+ self.parameters[:semi_minor_axis]
58
+ end
59
+
60
+ # Returns whether the semi-minor axis is computed
61
+ #
62
+ # @see https://proj.org/development/reference/functions.html#c.proj_ellipsoid_get_parameters
63
+ #
64
+ # @return [Boolean]
65
+ def semi_minor_axis_computed
66
+ self.parameters[:semi_minor_axis_computed]
67
+ end
68
+
69
+ # Returns the inverse flattening value
70
+ #
71
+ # @see https://proj.org/development/reference/functions.html#c.proj_ellipsoid_get_parameters
72
+ #
73
+ # @return [Double]
74
+ def inverse_flattening
75
+ self.parameters[:inverse_flattening]
76
+ end
77
+ end
78
+ end
data/lib/proj/error.rb ADDED
@@ -0,0 +1,71 @@
1
+ module Proj
2
+ # Represents error thrown by Proj
3
+ #
4
+ # @see https://proj.org/development/errorhandling.html
5
+ class Error < StandardError
6
+ # Error codes typically related to coordinate operation initialization
7
+ PROJ_ERR_INVALID_OP = 1024 # Other/unspecified error related to coordinate operation initialization
8
+ PROJ_ERR_INVALID_OP_WRONG_SYNTAX = PROJ_ERR_INVALID_OP + 1 # Invalid pipeline structure, missing +proj argument, etc
9
+ PROJ_ERR_INVALID_OP_MISSING_ARG = PROJ_ERR_INVALID_OP + 2 # Missing required operation parameter
10
+ PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE = PROJ_ERR_INVALID_OP + 3 # One of the operation parameter has an illegal value
11
+ PROJ_ERR_INVALID_OP_MUTUALLY_EXCLUSIVE_ARGS = PROJ_ERR_INVALID_OP + 4 # Mutually exclusive arguments
12
+ PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID = PROJ_ERR_INVALID_OP + 5 # File not found (particular case of PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE)
13
+
14
+ # Error codes related to transformation on a specific coordinate
15
+ PROJ_ERR_COORD_TRANSFM = 2048 # Other error related to coordinate transformation
16
+ PROJ_ERR_COORD_TRANSFM_INVALID_COORD = PROJ_ERR_COORD_TRANSFM + 1 # For e.g lat > 90deg
17
+ PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN = PROJ_ERR_COORD_TRANSFM + 2 # Coordinate is outside of the projection domain. e.g approximate mercator with |longitude - lon_0| > 90deg, or iterative convergence method failed
18
+ PROJ_ERR_COORD_TRANSFM_NO_OPERATION = PROJ_ERR_COORD_TRANSFM + 3 # No operation found, e.g if no match the required accuracy, or if ballpark transformations were asked to not be used and they would be only such candidate
19
+ PROJ_ERR_COORD_TRANSFM_OUTSIDE_GRID = PROJ_ERR_COORD_TRANSFM + 4 # Point to transform falls outside grid or subgrid
20
+ PROJ_ERR_COORD_TRANSFM_GRID_AT_NODATA = PROJ_ERR_COORD_TRANSFM + 5 # Point to transform falls in a grid cell that evaluates to nodata
21
+
22
+ # Other type of errors
23
+ PROJ_ERR_OTHER = 4096
24
+ PROJ_ERR_OTHER_API_MISUSE = PROJ_ERR_OTHER + 1 # Error related to a misuse of PROJ API
25
+ PROJ_ERR_OTHER_NO_INVERSE_OP = PROJ_ERR_OTHER + 2 # No inverse method available
26
+ PROJ_ERR_OTHER_NETWORK_ERROR = PROJ_ERR_OTHER + 3 # Failure when accessing a network resource
27
+
28
+ # Check the context to see if an error occurred. If an error has happened will
29
+ # raise an exception.
30
+ def self.check_context(context)
31
+ unless context.errno == 0
32
+ # raise(self, "#{self.category(context.errno)}: #{self.message(context)}")
33
+ raise(self, self.message(context, context.errno))
34
+ end
35
+ end
36
+
37
+ def self.check_object(pj_object)
38
+ # It would be nice if Proj exposed the proj_context_errno_set method so
39
+ # we don't need a pj_object
40
+ context = pj_object.context
41
+ unless context.errno == 0
42
+ message = self.message(context, context.errno)
43
+ Api.proj_errno_reset(pj_object)
44
+ raise(self, message)
45
+ end
46
+ end
47
+
48
+ # Returns the current error-state of the context. An non-zero error codes indicates an error.
49
+ #
50
+ # See https://proj.org/development/reference/functions.html#c.proj_errno_string proj_errno_string
51
+ #
52
+ # @param context [Context] The context the error occurred in
53
+ # @param errno [Integer] The error number
54
+ #
55
+ # return [String]
56
+ def self.message(context, errno)
57
+ if Api.method_defined?(:proj_context_errno_string)
58
+ Api.proj_context_errno_string(context, errno)
59
+ elsif Api.method_defined?(:proj_errno_string)
60
+ Api.proj_errno_string(errno)
61
+ end
62
+ end
63
+
64
+ # Converts an errno to a error category
65
+ def self.category(errno)
66
+ self.constants.find do |constant|
67
+ self.const_get(constant) == errno
68
+ end
69
+ end
70
+ end
71
+ end