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
data/lib/proj/database.rb CHANGED
@@ -1,305 +1,310 @@
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 pj_type [PJ_TYPE] Proj 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, pj_type, allow_deprecated = false)
92
- ptr = Api.proj_get_codes_from_database(self.context, auth_name, pj_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
1
+ require 'uri'
2
+
3
+ module Proj
4
+ CelestialBody = Struct.new(:auth_name, :name)
5
+
6
+ # This class provides access the Proj SQLite database called proj.db. The database
7
+ # stores transformation information that must be accessible for the library to work properly.
8
+ #
9
+ # @see https://proj.org/resource_files.html#proj-db
10
+ class Database
11
+ attr_reader :context
12
+
13
+ # Create a new database instance to query the Proj database
14
+ #
15
+ # @param context [Context] A proj Context
16
+ #
17
+ # @return [Database]
18
+ def initialize(context)
19
+ Error.validate_context!(context)
20
+ @context = context
21
+ end
22
+
23
+ # Returns the path the Proj database
24
+ #
25
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_path
26
+ #
27
+ # return [String]
28
+ def path
29
+ if Api.method_defined?(:proj_context_get_database_path)
30
+ Api.proj_context_get_database_path(self.context)
31
+ end
32
+ end
33
+
34
+ # Sets the path to the Proj database
35
+ #
36
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_set_database_path
37
+ #
38
+ # @param value [String] Path to the proj database
39
+ #
40
+ # @return [Database] Returns reference to the current database instance
41
+ def path=(value)
42
+ result = Api.proj_context_set_database_path(self.context, value, nil, nil)
43
+ unless result == 1
44
+ Error.check_context(self.context)
45
+ end
46
+ self
47
+ end
48
+
49
+ # Returns SQL statements to run to initiate a new valid auxiliary empty database.
50
+ #
51
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_structure
52
+ #
53
+ # @return [Array<Strings>] List of sql statements
54
+ def structure
55
+ ptr = Api.proj_context_get_database_structure(self.context, nil)
56
+ Strings.new(ptr)
57
+ end
58
+
59
+ # Return a metadata from the database.
60
+ #
61
+ # @see https://proj.org/development/reference/functions.html#c.proj_context_get_database_metadata
62
+ #
63
+ # @param key [String] The name of the metadata item. Must not be nil
64
+ # Available keys:
65
+ # DATABASE.LAYOUT.VERSION.MAJOR
66
+ # DATABASE.LAYOUT.VERSION.MINOR
67
+ # EPSG.VERSION
68
+ # EPSG.DATE
69
+ # ESRI.VERSION
70
+ # ESRI.DATE
71
+ # IGNF.SOURCE
72
+ # IGNF.VERSION
73
+ # IGNF.DATE
74
+ # NKG.SOURCE
75
+ # NKG.VERSION
76
+ # NKG.DATE
77
+ # PROJ.VERSION
78
+ # PROJ_DATA.VERSION
79
+ #
80
+ # @return [String] Returned metadata
81
+ def metadata(key)
82
+ Api.proj_context_get_database_metadata(self.context, key)
83
+ end
84
+
85
+ # Returns the set of authority codes of the given object type.
86
+ #
87
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_codes_from_database
88
+ #
89
+ # @param auth_name [String] Authority name. Must not be nil.
90
+ # @param pj_type [PjType] Proj Object type.
91
+ # @param allow_deprecated [Boolean] Specifies if deprecated objects should be returned. Default is false.
92
+ #
93
+ # @return [Strings] Returned authority codes
94
+ def codes(auth_name, pj_type, allow_deprecated = false)
95
+ ptr = Api.proj_get_codes_from_database(self.context, auth_name, pj_type, allow_deprecated ? 1 : 0)
96
+ Strings.new(ptr)
97
+ end
98
+
99
+ # Return a list of authorities used in the database
100
+ #
101
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_authorities_from_database
102
+ #
103
+ # @return [Array<Strings>] List of authorities
104
+ def authorities
105
+ ptr = Api.proj_get_authorities_from_database(self.context)
106
+ Strings.new(ptr)
107
+ end
108
+
109
+ # Enumerate CRS infos from the database, taking into account various criteria.
110
+ #
111
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_crs_info_list_from_database
112
+ #
113
+ # @param auth_name [String] Authority name. Use nil to specify all authorities
114
+ # @param parameters [Parameters] Parameters to specify search criteria. May be nil
115
+ #
116
+ # @return [Array<CrsInfo>] Returned crs infos
117
+ def crs_info(auth_name = nil, parameters = nil)
118
+ out_result_count = FFI::MemoryPointer.new(:int)
119
+ params = parameters.is_a?(Parameters) ? parameters.instance_variable_get(:@params) : parameters
120
+ ptr = Api.proj_get_crs_info_list_from_database(self.context, auth_name, params, out_result_count)
121
+
122
+ result = out_result_count.read_int.times.map do |index|
123
+ index_ptr = ptr + (index * FFI::Pointer::SIZE)
124
+ struct = Api::ProjCrsInfo.new(index_ptr.read_pointer)
125
+ CrsInfo.from_proj_crs_info(struct)
126
+ end
127
+
128
+ Api.proj_crs_info_list_destroy(ptr)
129
+ result
130
+ end
131
+
132
+ # Returns information about a Grid from the database
133
+ #
134
+ # @see https://proj.org/development/reference/functions.html#c.proj_grid_get_info_from_database
135
+ #
136
+ # @param name [String] The name of the grid
137
+ #
138
+ # @return [Grid]
139
+ def grid(name)
140
+ out_full_name = FFI::MemoryPointer.new(:string)
141
+ out_package_name = FFI::MemoryPointer.new(:string)
142
+ out_url = FFI::MemoryPointer.new(:string)
143
+ out_downloadable = FFI::MemoryPointer.new(:int)
144
+ out_open_license = FFI::MemoryPointer.new(:int)
145
+ out_available = FFI::MemoryPointer.new(:int)
146
+
147
+ result = Api.proj_grid_get_info_from_database(self.context, name,
148
+ out_full_name, out_package_name, out_url,
149
+ out_downloadable, out_open_license, out_available)
150
+
151
+ if result == 1
152
+ full_name_ptr = out_full_name.read_pointer
153
+ package_name_ptr = out_package_name.read_pointer
154
+ url_ptr = out_url.read_pointer
155
+
156
+ downloadable_ptr = out_downloadable
157
+ open_license_ptr = out_open_license
158
+ available_ptr = out_available
159
+
160
+ full_name = full_name_ptr.read_string_to_null
161
+ package_name = package_name_ptr.read_string_to_null
162
+ url = url_ptr.read_string_to_null
163
+
164
+ downloadable = downloadable_ptr.read_int == 1 ? true : false
165
+ open_license = open_license_ptr.read_int == 1 ? true : false
166
+ available = available_ptr.read_int == 1 ? true : false
167
+
168
+ Grid.new(name, self.context,
169
+ full_name: full_name, package_name: package_name,
170
+ url: url ? URI(url) : nil,
171
+ downloadable: downloadable, open_license: open_license, available: available)
172
+ else
173
+ Error.check_context(self.context)
174
+ end
175
+ end
176
+
177
+ # Returns a list of geoid models available
178
+ #
179
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_geoid_models_from_database
180
+ #
181
+ # @param authority [String] Authority name into which the object will be inserted. Must not be nil
182
+ # @param code [Integer] Code with which the object will be inserted.Must not be nil
183
+ #
184
+ # @return [Strings] List of insert statements
185
+ def geoid_models(authority, code)
186
+ ptr = Api.proj_get_geoid_models_from_database(self.context, authority, code, nil)
187
+ Strings.new(ptr)
188
+ end
189
+
190
+ # Returns a list of celestial bodies from the database
191
+ #
192
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_celestial_body_list_from_database
193
+ #
194
+ # @param authority [String] Authority name, used to restrict the search. Set to nil for all authorities.
195
+ #
196
+ # @return [Array<CelestialBody>] List of insert statements
197
+ def celestial_bodies(authority = nil)
198
+ out_result_count = FFI::MemoryPointer.new(:int)
199
+ ptr = Api.proj_get_celestial_body_list_from_database(self.context, authority, out_result_count)
200
+
201
+ body_ptrs = ptr.read_array_of_pointer(out_result_count.read_int)
202
+ result = body_ptrs.map do |body_ptr|
203
+ # First read the pointer to a structure
204
+ struct = Api::ProjCelestialBodyInfo.new(body_ptr)
205
+
206
+ # Now map this to a Ruby Struct
207
+ CelestialBody.new(struct[:auth_name].read_string_to_null, struct[:name].read_string_to_null)
208
+ end
209
+
210
+ Api.proj_celestial_body_list_destroy(ptr)
211
+
212
+ result
213
+ end
214
+
215
+ # Return the name of the celestial body of the specified object.
216
+ #
217
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_celestial_body_name
218
+ #
219
+ # @param object [PjObject] Object of type CRS, Datum or Ellipsoid. Must not be nil.
220
+ #
221
+ # @return [String] The name of the celestial body or nil
222
+ def celestial_body_name(object)
223
+ Api.proj_get_celestial_body_name(self.context, object)
224
+ end
225
+
226
+ # Suggests a database code for the specified object.
227
+ #
228
+ # @see https://proj.org/development/reference/functions.html#c.proj_suggests_code_for
229
+ #
230
+ # @param object [PjObject] Object for which to suggest a code.
231
+ # @param authority [String] Authority name into which the object will be inserted.
232
+ # @param numeric_code [Boolean] Whether the code should be numeric, or derived from the object name.
233
+ #
234
+ # @return [String] The suggested code
235
+ def suggest_code_for(object, authority, numeric_code)
236
+ ptr = Api.proj_suggests_code_for(self.context, object, authority, numeric_code ? 1 : 0, nil)
237
+ return nil if ptr.null?
238
+ result = ptr.read_string_to_null
239
+ Api.proj_string_destroy(ptr)
240
+ result
241
+ end
242
+
243
+ # Returns a list of units from the database
244
+ #
245
+ # @see https://proj.org/development/reference/functions.html#c.proj_get_units_from_database
246
+ #
247
+ # @param auth_name [String] Authority name, used to restrict the search. Or nil for all authorities.
248
+ # @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
249
+ # @param allow_deprecated [Boolean] Whether deprecated units should also be returned. Default false.
250
+ #
251
+ # @return [Array<Unit>] Array of units
252
+ def units(auth_name: nil, category: nil, allow_deprecated: false)
253
+ # Create pointer to read the count output parameter
254
+ out_result_count = FFI::MemoryPointer.new(:int)
255
+
256
+ # Result is an array of pointers to structures
257
+ pp_units = Api.proj_get_units_from_database(self.context, auth_name, category, allow_deprecated ? 1 : 0, out_result_count)
258
+ count = out_result_count.read(:int)
259
+ array_p_units = pp_units.read_array_of_pointer(count)
260
+
261
+ result = Array.new(count)
262
+ count.times do |i|
263
+ unit_info = Api::ProjUnitInfo.new(array_p_units[i])
264
+
265
+ result[i] = Unit.new(unit_info[:auth_name].read_string_to_null,
266
+ unit_info[:code].read_string_to_null,
267
+ unit_info[:name].read_string_to_null,
268
+ unit_info[:category].read_string_to_null,
269
+ unit_info[:conv_factor],
270
+ unit_info[:proj_short_name].null? ? nil : unit_info[:proj_short_name].read_string_to_null,
271
+ unit_info[:deprecated])
272
+ end
273
+
274
+ Api.proj_unit_list_destroy(pp_units)
275
+
276
+ result
277
+ end
278
+
279
+ # Returns information for a unit of measure from a database lookup
280
+ #
281
+ # @see https://proj.org/development/reference/functions.html#c.proj_uom_get_info_from_database
282
+ #
283
+ # @param auth_name [String] Authority name
284
+ # @param code [String] Unit of measure code
285
+ #
286
+ # @return [Unit] Unit
287
+ def unit(auth_name, code)
288
+ out_name = FFI::MemoryPointer.new(:string)
289
+ out_conv_factor = FFI::MemoryPointer.new(:double)
290
+ out_category = FFI::MemoryPointer.new(:string)
291
+
292
+ result = Api.proj_uom_get_info_from_database(self.context, auth_name, code,
293
+ out_name, out_conv_factor , out_category)
294
+
295
+ if result == 1
296
+ name_ptr = out_name.read_pointer
297
+ conv_factor_ptr = out_conv_factor
298
+ category_ptr = out_category.read_pointer
299
+
300
+ name = name_ptr.read_string_to_null
301
+ conv_factor = conv_factor_ptr.read_double
302
+ category = category_ptr.read_string_to_null
303
+
304
+ Unit.new(auth_name, code, name, category, conv_factor, nil, false)
305
+ else
306
+ Error.check_context(self.context)
307
+ end
308
+ end
309
+ end
310
+ end