ffi-gdal 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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')