ffi-gdal 0.0.1

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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +60 -0
  7. data/Rakefile +57 -0
  8. data/ffi-gdal.gemspec +28 -0
  9. data/lib/ext/cpl_error_symbols.rb +37 -0
  10. data/lib/ext/to_bool.rb +13 -0
  11. data/lib/ffi/gdal/cpl_conv.rb +151 -0
  12. data/lib/ffi/gdal/cpl_error.rb +91 -0
  13. data/lib/ffi/gdal/cpl_string.rb +113 -0
  14. data/lib/ffi/gdal/cpl_vsi.rb +119 -0
  15. data/lib/ffi/gdal/gdal_color_entry.rb +13 -0
  16. data/lib/ffi/gdal/gdal_gcp.rb +18 -0
  17. data/lib/ffi/gdal/ogr_api.rb +28 -0
  18. data/lib/ffi/gdal/ogr_core.rb +199 -0
  19. data/lib/ffi/gdal/ogr_srs_api.rb +48 -0
  20. data/lib/ffi/gdal/version.rb +5 -0
  21. data/lib/ffi/gdal.rb +607 -0
  22. data/lib/ffi-gdal/color_table.rb +59 -0
  23. data/lib/ffi-gdal/dataset.rb +347 -0
  24. data/lib/ffi-gdal/driver.rb +151 -0
  25. data/lib/ffi-gdal/exceptions.rb +17 -0
  26. data/lib/ffi-gdal/geo_transform.rb +137 -0
  27. data/lib/ffi-gdal/major_object.rb +71 -0
  28. data/lib/ffi-gdal/raster_attribute_table.rb +78 -0
  29. data/lib/ffi-gdal/raster_band.rb +571 -0
  30. data/lib/ffi-gdal/version_info.rb +48 -0
  31. data/lib/ffi-gdal.rb +12 -0
  32. data/linkies.rb +35 -0
  33. data/meow.rb +144 -0
  34. data/readie.rb +90 -0
  35. data/rubby.rb +224 -0
  36. data/spec/ext/cpl_error_symbols_spec.rb +79 -0
  37. data/spec/ffi-gdal/integration/color_table_info_spec.rb +60 -0
  38. data/spec/ffi-gdal/integration/dataset_info_spec.rb +95 -0
  39. data/spec/ffi-gdal/integration/driver_info_spec.rb +60 -0
  40. data/spec/ffi-gdal/integration/geo_transform_info_spec.rb +66 -0
  41. data/spec/ffi-gdal/integration/raster_attribute_table_info_spec.rb +23 -0
  42. data/spec/ffi-gdal/integration/raster_band_info_spec.rb +333 -0
  43. data/spec/ffi-gdal/unit/version_info_spec.rb +48 -0
  44. data/spec/ffi-gdal_spec.rb +6 -0
  45. data/spec/spec_helper.rb +13 -0
  46. data/spec/support/integration_help.rb +1 -0
  47. data/spec/support/shared_examples/major_object_examples.rb +68 -0
  48. data/things.rb +84 -0
  49. metadata +216 -0
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'support/integration_help'
3
+ require 'ffi-gdal'
4
+
5
+ TIF_FILES.each do |file|
6
+ describe 'Dataset Info' do
7
+ subject do
8
+ GDAL::Dataset.open(file, 'r')
9
+ end
10
+
11
+ it_behaves_like 'a major object'
12
+
13
+ describe '#open?' do
14
+ it { is_expected.to be_open }
15
+ end
16
+
17
+ describe '#driver' do
18
+ it 'is a GDAL::Driver' do
19
+ expect(subject.driver).to be_a GDAL::Driver
20
+ end
21
+ end
22
+
23
+ describe '#file_list' do
24
+ it 'is a non-empty Array' do
25
+ expect(subject.file_list).to be_an Array
26
+ end
27
+
28
+ it 'contains the file name' do
29
+ expect(subject.file_list).to include(File.expand_path(file))
30
+ end
31
+ end
32
+
33
+ describe '#raster_x_size' do
34
+ it 'is a Fixnum' do
35
+ expect(subject.raster_x_size).to be_a Fixnum
36
+ end
37
+ end
38
+
39
+ describe '#raster_y_size' do
40
+ it 'is a Fixnum' do
41
+ expect(subject.raster_y_size).to be_a Fixnum
42
+ end
43
+ end
44
+
45
+ describe '#raster_count' do
46
+ it 'is a Fixnum' do
47
+ expect(subject.raster_count).to be_a Fixnum
48
+ end
49
+ end
50
+
51
+ describe '#raster_band' do
52
+ it 'each band is a GDAL::RasterBand' do
53
+ 1.upto(subject.raster_count) do |i|
54
+ expect(subject.raster_band(i)).to be_a GDAL::RasterBand
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#projection' do
60
+ it 'is a String' do
61
+ expect(subject.projection).to be_a String
62
+ end
63
+ end
64
+
65
+ describe '#access_flag' do
66
+ it 'is GA_ReadOnly' do
67
+ expect(subject.access_flag).to be :GA_ReadOnly
68
+ end
69
+ end
70
+
71
+ describe '#geo_transform' do
72
+ it 'is a GDAL::GeoTransform' do
73
+ expect(subject.geo_transform).to be_a GDAL::GeoTransform
74
+ end
75
+ end
76
+
77
+ describe '#gcp_count' do
78
+ it 'is a Fixnum' do
79
+ expect(subject.gcp_count).to be_a Fixnum
80
+ end
81
+ end
82
+
83
+ describe '#gcp_projection' do
84
+ it 'is a String' do
85
+ expect(subject.gcp_projection).to be_a String
86
+ end
87
+ end
88
+
89
+ describe '#gcps' do
90
+ it 'is a GDALGCP' do
91
+ expect(subject.gcps).to be_a FFI::GDAL::GDALGCP
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'support/integration_help'
3
+ require 'ffi-gdal'
4
+
5
+ TIF_FILES.each do |file|
6
+ describe 'Driver Info' do
7
+ subject do
8
+ GDAL::Driver.new(file_path: file)
9
+ end
10
+
11
+ it_behaves_like 'a major object'
12
+
13
+ describe '.driver_count' do
14
+ it 'is a non-zero Integer' do
15
+ expect(GDAL::Driver.driver_count).to be_a Fixnum
16
+ expect(GDAL::Driver.driver_count).to be > 0
17
+ end
18
+ end
19
+
20
+ describe '#c_pointer' do
21
+ it 'is a FFI::Pointer to the actual C driver' do
22
+ expect(subject.c_pointer).to be_a FFI::Pointer
23
+ expect(subject.c_pointer).to_not be_null
24
+ end
25
+ end
26
+
27
+ describe '#short_name' do
28
+ it 'is GTiff' do
29
+ expect(subject.short_name).to eq 'GTiff'
30
+ end
31
+ end
32
+
33
+ describe '#long_name' do
34
+ it 'is GeoTiff' do
35
+ expect(subject.long_name).to eq 'GeoTIFF'
36
+ end
37
+ end
38
+
39
+ describe '#help_topic' do
40
+ it 'is http://gdal.org/frmt_gtiff.html' do
41
+ expect(subject.help_topic).to eq 'http://gdal.org/frmt_gtiff.html'
42
+ end
43
+ end
44
+
45
+ describe '#creation_option_list' do
46
+ it 'is an Array of Hashes' do
47
+ expect(subject.creation_option_list).to be_an Array
48
+ expect(subject.creation_option_list.first).to be_a Hash
49
+ end
50
+ end
51
+
52
+ describe '#copy_dataset_files' do
53
+ pending
54
+ end
55
+
56
+ describe '#create_dataset' do
57
+ pending
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'support/integration_help'
3
+ require 'ffi-gdal'
4
+
5
+
6
+ TIF_FILES.each do |file|
7
+ dataset = GDAL::Dataset.open(file, 'r')
8
+
9
+ describe 'GeoTransform Info' do
10
+ after :all do
11
+ dataset.close
12
+ end
13
+
14
+ subject do
15
+ dataset.geo_transform
16
+ end
17
+
18
+ describe '#x_origin' do
19
+ it 'is a Float' do
20
+ expect(subject.x_origin).to be_a Float
21
+ end
22
+ end
23
+
24
+ describe '#y_origin' do
25
+ it 'is a Float' do
26
+ expect(subject.y_origin).to be_a Float
27
+ end
28
+ end
29
+
30
+ describe '#pixel_width' do
31
+ it 'is a Float' do
32
+ expect(subject.pixel_width).to be_a Float
33
+ end
34
+ end
35
+
36
+ describe '#x_rotation' do
37
+ it 'is a Float' do
38
+ expect(subject.x_rotation).to be_a Float
39
+ end
40
+ end
41
+
42
+ describe '#y_rotation' do
43
+ it 'is a Float' do
44
+ expect(subject.y_rotation).to be_a Float
45
+ end
46
+ end
47
+
48
+ describe '#pixel_height' do
49
+ it 'is a Float' do
50
+ expect(subject.pixel_height).to be_a Float
51
+ end
52
+ end
53
+
54
+ describe '#x_projection' do
55
+ it 'is a Float' do
56
+ expect(subject.x_projection(0, 0)).to be_a Float
57
+ end
58
+ end
59
+
60
+ describe '#y_projection' do
61
+ it 'is a Float' do
62
+ expect(subject.y_projection(0, 0)).to be_a Float
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'support/integration_help'
3
+ require 'ffi-gdal'
4
+
5
+
6
+ TIF_FILES.each do |file|
7
+ dataset = GDAL::Dataset.open(file, 'r')
8
+
9
+ describe 'Raster Band Info' do
10
+ after :all do
11
+ dataset.close
12
+ end
13
+
14
+ subject do
15
+ band = GDAL::RasterBand.new(dataset.c_pointer, band_id: 1)
16
+ band.default_raster_attribute_table
17
+ end
18
+
19
+ describe '#column_count' do
20
+ pending 'Test files with RATs'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,333 @@
1
+ require 'spec_helper'
2
+ require 'support/integration_help'
3
+ require 'ffi-gdal'
4
+
5
+
6
+ TIF_FILES.each do |file|
7
+ dataset = GDAL::Dataset.open(file, 'r')
8
+
9
+ describe 'Raster Band Info' do
10
+ after :all do
11
+ dataset.close
12
+ end
13
+
14
+ # TODO: Test against each raster band
15
+ subject do
16
+ GDAL::RasterBand.new(dataset.c_pointer, band_id: 1)
17
+ end
18
+
19
+ it_behaves_like 'a major object'
20
+
21
+ describe '#x_size' do
22
+ it 'is a non-zero Integer' do
23
+ expect(subject.x_size).to be_a Fixnum
24
+ expect(subject.x_size).to be > 0
25
+ end
26
+ end
27
+
28
+ describe '#y_size' do
29
+ it 'is a non-zero Integer' do
30
+ expect(subject.y_size).to be_a Fixnum
31
+ expect(subject.y_size).to be > 0
32
+ end
33
+ end
34
+
35
+ describe '#access_flag' do
36
+ specify { expect(subject.access_flag).to eq :GA_ReadOnly }
37
+ end
38
+
39
+ describe '#band_number' do
40
+ it 'is a non-zero Integer' do
41
+ expect(subject.band_number).to be_a Fixnum
42
+ expect(subject.band_number).to be > 0
43
+ end
44
+ end
45
+
46
+ describe '#color_interpretation' do
47
+ it 'is a Symbol; one of FFI::GDAL::GDALColorInterp' do
48
+ expect(subject.color_interpretation).to be_a Symbol
49
+ expect(FFI::GDAL::GDALColorInterp.symbols).to include subject.color_interpretation
50
+ end
51
+ end
52
+
53
+ describe '#color_table' do
54
+ it 'is a GDAL::ColorTable' do
55
+ if subject.color_table
56
+ expect(subject.color_table).to be_a GDAL::ColorTable
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#data_type' do
62
+ it 'is a Symbol; one of FFI::GDAL::GDALDataType' do
63
+ expect(subject.data_type).to be_a Symbol
64
+ expect(FFI::GDAL::GDALDataType.symbols).to include subject.data_type
65
+ end
66
+ end
67
+
68
+ describe '#block_size' do
69
+ it 'is a Hash with x and y keys that are >= 1' do
70
+ expect(subject.block_size).to be_a Hash
71
+ expect(subject.block_size[:x]).to be >= 1
72
+ expect(subject.block_size[:y]).to be >= 1
73
+ end
74
+ end
75
+
76
+ describe '#category_names' do
77
+ it 'is an Array of Strings' do
78
+ expect(subject.category_names).to be_an Array
79
+
80
+ subject.category_names.each do |category_name|
81
+ expect(category_name).to be_a String
82
+ expect(category_name).to_not be_empty
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#category_names=' do
88
+ around do |example|
89
+ category_names = subject.category_names
90
+ example.run
91
+ subject.category_names = category_names
92
+ end
93
+
94
+ it 'sets the category names' do
95
+ expect(subject.category_names).to be_empty
96
+
97
+ subject.category_names = %w[one two three]
98
+
99
+ expect(subject.category_names).to eq %w[one two three]
100
+ end
101
+ end
102
+
103
+ describe '#no_data_value' do
104
+ it 'is a Hash with :value and :is_associated keys' do
105
+ expect(subject.no_data_value).to be_an Hash
106
+
107
+ expect(subject.no_data_value[:value]).to be_a Float
108
+ expect(subject.no_data_value[:is_associated]).to_not be_nil
109
+ end
110
+ end
111
+
112
+ describe '#overview_count' do
113
+ it 'is a Fixnum' do
114
+ expect(subject.overview_count).to be_a Fixnum
115
+ end
116
+ end
117
+
118
+ describe '#arbitrary_overviews?' do
119
+ it 'is true or false' do
120
+ expect([true, false]).to include subject.arbitrary_overviews?
121
+ end
122
+ end
123
+
124
+ describe '#overview' do
125
+ it 'returns a GDAL::RasterBand if the overview exists' do
126
+ overview = subject.overview(0)
127
+ expect(overview).to be_a GDAL::RasterBand if overview
128
+ end
129
+ end
130
+
131
+ describe '#raster_sample_overview' do
132
+ it 'returns a GDAL::RasterBand if the overview exists' do
133
+ overview = subject.raster_sample_overview
134
+ expect(overview).to be_a GDAL::RasterBand
135
+ end
136
+ end
137
+
138
+ describe '#mask_band' do
139
+ it 'returns a GDAL::RasterBand if the mask_band exists' do
140
+ overview = subject.mask_band
141
+ expect(overview).to be_a GDAL::RasterBand
142
+ end
143
+ end
144
+
145
+ describe '#mask_flags' do
146
+ it 'returns an Array of Symbols' do
147
+ expect(subject.mask_flags).to eq [:GMF_ALL_VALID]
148
+ end
149
+ end
150
+
151
+ describe '#statistics' do
152
+ it 'returns a Hash with populated values' do
153
+ expect(subject.statistics).to be_a Hash
154
+ expect(%i[minimum maximum mean standard_deviation]).
155
+ to eq subject.statistics.keys
156
+ end
157
+
158
+ it 'has a :minimum that ranges between 0.0/-32768.0 and 255.0' do
159
+ min = subject.statistics[:minimum]
160
+ unless min == -32768.0
161
+ expect(subject.statistics[:minimum]).to((be >= 0.0) || (eq -32768.0))
162
+ expect(subject.statistics[:minimum]).to be <= 255.0
163
+ end
164
+ end
165
+ end
166
+
167
+ describe '#scale' do
168
+ it 'returns a Hash with populated values' do
169
+ expect(subject.statistics).to be_a Hash
170
+ expect(%i[value is_meaningful]).to eq subject.scale.keys
171
+ end
172
+
173
+ it 'has a :value that is a Float' do
174
+ expect(subject.scale[:value]).to be_a Float
175
+ end
176
+
177
+ it 'has a :is_meaningful that is false (since the examples are geotiffs)' do
178
+ expect(subject.scale[:is_meaningful]).to eq false
179
+ end
180
+ end
181
+
182
+ describe '#scale=' do
183
+ around do |example|
184
+ scale = subject.scale[:value]
185
+ example.run
186
+ subject.scale = scale
187
+ end
188
+
189
+ it 'does nothing (because the file formats dont support it)' do
190
+ subject.scale = 0.1
191
+ expect(subject.scale[:value]).to eq 0.1
192
+ end
193
+ end
194
+
195
+ describe '#offset' do
196
+ it 'returns a Hash with populated values' do
197
+ expect(subject.offset).to be_a Hash
198
+ expect(%i[value is_meaningful]).to eq subject.offset.keys
199
+ end
200
+
201
+ it 'has a :value that is a Float' do
202
+ expect(subject.offset[:value]).to be_a Float
203
+ end
204
+
205
+ it 'has a :is_meaningful that is false (since the examples are geotiffs)' do
206
+ expect(subject.offset[:is_meaningful]).to eq false
207
+ end
208
+ end
209
+
210
+ describe '#offset=' do
211
+ around do |example|
212
+ offset = subject.offset[:value]
213
+ example.run
214
+ subject.offset = offset
215
+ end
216
+
217
+ it 'does nothing (because the file formats dont support it)' do
218
+ subject.offset = 0.1
219
+ expect(subject.offset[:value]).to eq 0.1
220
+ end
221
+ end
222
+
223
+ describe '#unit_type' do
224
+ it 'returns a String' do
225
+ expect(subject.unit_type).to be_a String
226
+ end
227
+ end
228
+
229
+ describe '#unit_type=' do
230
+ around do |example|
231
+ unit_type = subject.unit_type
232
+ example.run
233
+ subject.unit_type = unit_type
234
+ end
235
+
236
+ it 'does nothing (because the file formats dont support it)' do
237
+ subject.unit_type = 'ft'
238
+ expect(subject.unit_type).to eq 'ft'
239
+ end
240
+ end
241
+
242
+ describe '#default_histogram' do
243
+ let!(:histogram) { subject.default_histogram }
244
+
245
+ it 'returns a Hash with :mininum, :maximum, :buckets, and :totals' do
246
+ expect(histogram).to be_a Hash
247
+ expect(histogram.keys).to eq %i[minimum maximum buckets totals]
248
+ end
249
+
250
+ it 'has :mimimum as a Float' do
251
+ expect(histogram[:minimum]).to be_a Float
252
+ end
253
+
254
+ it 'has :maximum as a Float' do
255
+ expect(histogram[:maximum]).to be_a Float
256
+ end
257
+
258
+ it 'has :buckets as a Fixnum' do
259
+ expect(histogram[:buckets]).to be_a Fixnum
260
+ end
261
+
262
+ it 'has :totals as an Array of 256 Fixnums' do
263
+ expect(histogram[:totals]).to be_an Array
264
+ expect(histogram[:totals].size).to eq 256
265
+ expect(histogram[:totals].all? { |t| t.class == Fixnum}).to eq true
266
+ end
267
+ end
268
+
269
+ describe '#default_raster_attribute_table' do
270
+ it 'returns a GDAL::RasterAttributeTable' do
271
+ rat = subject.default_raster_attribute_table
272
+
273
+ if rat
274
+ expect(rat).to be_a GDAL::RasterAttributeTable
275
+ end
276
+ end
277
+ end
278
+
279
+ describe '#compute_min_max' do
280
+ it 'returns a 2-element Array of Floats' do
281
+ expect(subject.compute_min_max).to be_a Array
282
+ expect(subject.compute_min_max.size).to eq 2
283
+ expect(subject.compute_min_max.first).to be_a Float
284
+ expect(subject.compute_min_max.last).to be_a Float
285
+ end
286
+
287
+ it 'has a min that is < its max' do
288
+ min, max = subject.compute_min_max
289
+ expect(min).to be < max
290
+ end
291
+
292
+ it 'has a min that == statistics[:minimum]' do
293
+ min, _ = subject.compute_min_max
294
+ expect(min).to eq subject.statistics[:minimum]
295
+ end
296
+
297
+ it 'has a min that == minimum_value[:value]' do
298
+ min, _ = subject.compute_min_max
299
+ expect(min).to eq subject.minimum_value[:value]
300
+ end
301
+ end
302
+
303
+ describe '#minimum_value' do
304
+ it 'returns a Hash with populated values' do
305
+ expect(subject.minimum_value).to be_a Hash
306
+ expect(%i[value is_tight]).to eq subject.minimum_value.keys
307
+ end
308
+
309
+ it 'has a :value that is a Float' do
310
+ expect(subject.minimum_value[:value]).to be_a Float
311
+ end
312
+
313
+ it 'has a :is_tight that is nil (since the examples are geotiffs)' do
314
+ #expect(subject.minimum_value[:is_tight]).to eq nil
315
+ end
316
+ end
317
+
318
+ describe '#maximum_value' do
319
+ it 'returns a Hash with populated values' do
320
+ expect(subject.maximum_value).to be_a Hash
321
+ expect(%i[value is_tight]).to eq subject.maximum_value.keys
322
+ end
323
+
324
+ it 'has a :value that is a Float' do
325
+ expect(subject.maximum_value[:value]).to be_a Float
326
+ end
327
+
328
+ it 'has a :is_tight that is nil (since the examples are geotiffs)' do
329
+ #expect(subject.maximum_value[:is_tight]).to eq nil
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'ffi-gdal/version_info'
3
+
4
+ describe GDAL::VersionInfo do
5
+ subject do
6
+ Object.new.extend(described_class)
7
+ end
8
+
9
+ describe '#version_num' do
10
+ it 'returns a non-empty String' do
11
+ expect(subject.version_num).to be_a String
12
+ expect(subject.version_num).to_not be_empty
13
+ end
14
+ end
15
+
16
+ describe '#release_date' do
17
+ it 'returns a Date' do
18
+ expect(subject.release_date).to be_a Date
19
+ end
20
+ end
21
+
22
+ describe '#release_name' do
23
+ it 'returns a non-empty String' do
24
+ expect(subject.release_name).to be_a String
25
+ expect(subject.release_name).to_not be_empty
26
+ end
27
+ end
28
+
29
+ describe '#license' do
30
+ it 'returns a non-empty String' do
31
+ expect(subject.license).to be_a String
32
+ expect(subject.license).to_not be_empty
33
+ end
34
+ end
35
+
36
+ describe '#build_info' do
37
+ it 'returns a Hash of info' do
38
+ expect(subject.build_info).to be_a Hash
39
+ end
40
+ end
41
+
42
+ describe '#long_version' do
43
+ it 'returns a non-empty String' do
44
+ expect(subject.long_version).to be_a String
45
+ expect(subject.long_version).to_not be_empty
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'ffi-gdal'
3
+
4
+
5
+ describe GDAL do
6
+ end
@@ -0,0 +1,13 @@
1
+ $:.unshift File.expand_path('../lib', __FILE__)
2
+ $:.unshift File.expand_path('../spec', __FILE__)
3
+
4
+ Dir['./spec/support/shared_examples/**/*.rb'].sort.each { |f| require f}
5
+
6
+ RSpec.configure do |config|
7
+
8
+ # Run specs in random order to surface order dependencies. If you find an
9
+ # order dependency and want to debug it, you can fix the order by providing
10
+ # the seed, which is printed after each run.
11
+ # --seed 1234
12
+ config.order = 'random'
13
+ end
@@ -0,0 +1 @@
1
+ TIF_FILES = Dir.glob('spec/support/images/osgeo/**/*.tif')