ffi-gdal 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/History.md +13 -0
- data/lib/ffi-gdal/dataset.rb +22 -14
- data/lib/ffi-gdal/raster_band.rb +60 -49
- data/lib/ffi/gdal/version.rb +1 -1
- data/spec/ffi-gdal/integration/raster_band_info_spec.rb +240 -234
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5be516e43cc426c9f1fe2f0f0b701b971597d8e6
|
4
|
+
data.tar.gz: 53d5d44e1450f3e3f4de809eb025723f1e2945d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 434c97cb29adc90a5f3daee4e5ac47a9560b7cb4959301b342988deb9976d4f579b0bc3a117d596f522e31725ecc2aa5f1519cf2d3bfb338677bee2fe8b447fc
|
7
|
+
data.tar.gz: 186963aecb3376291c75694f2628393a36b3c31603bd79897610a0796c7dabcbbb1f5f2e6332bd269c4f5b143200e405ae3a5453f1cb558f0c7a8b1e1d0723e7
|
data/History.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
### 0.0.3 / 2014-09-26
|
2
|
+
|
3
|
+
* Improvements
|
4
|
+
* The `approx_ok` param for `RasterBand#histogram` should default to
|
5
|
+
`false` (prefering data exactness over performance).
|
6
|
+
* Bug fixes
|
7
|
+
* Fixed URL silliness introduced in 0.0.2.
|
8
|
+
* `Dataset#*_band` methods should return `nil` if the band with that color
|
9
|
+
isn't found.
|
10
|
+
* `RasterBand#default_histogram` died if the band didn't have any values.
|
11
|
+
* `RasterBand#histogram` wasn't returning totals.
|
12
|
+
|
13
|
+
|
1
14
|
### 0.0.2 / 2014-09-26
|
2
15
|
|
3
16
|
* New things
|
data/lib/ffi-gdal/dataset.rb
CHANGED
@@ -27,7 +27,7 @@ module GDAL
|
|
27
27
|
# @param access_flag [String] 'r' or 'w'.
|
28
28
|
def self.open(path, access_flag)
|
29
29
|
uri = URI.parse(path)
|
30
|
-
file_path =
|
30
|
+
file_path = uri.scheme.nil? ? ::File.expand_path(path) : path
|
31
31
|
|
32
32
|
pointer = FFI::GDAL.GDALOpen(file_path, ACCESS_FLAGS[access_flag])
|
33
33
|
raise OpenFailure.new(file_path) if pointer.null?
|
@@ -53,7 +53,7 @@ module GDAL
|
|
53
53
|
fail RequiredBandNotFound, 'Near-infrared'
|
54
54
|
end
|
55
55
|
|
56
|
-
the_array =
|
56
|
+
the_array = calculate_ndvi(red.to_a, nir.to_a)
|
57
57
|
|
58
58
|
ndvi_band = ndvi_dataset.raster_band(1)
|
59
59
|
ndvi_band.write_array(the_array)
|
@@ -71,7 +71,7 @@ module GDAL
|
|
71
71
|
fail RequiredBandNotFound, 'Near-infrared'
|
72
72
|
end
|
73
73
|
|
74
|
-
the_array =
|
74
|
+
the_array = calculate_ndvi(green.to_a, nir.to_a)
|
75
75
|
|
76
76
|
gndvi_band = gndvi_dataset.raster_band(1)
|
77
77
|
gndvi_band.write_array(the_array)
|
@@ -114,6 +114,13 @@ module GDAL
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
+
# @param red_band_array [NArray]
|
118
|
+
# @param nir_band_array [NArray]
|
119
|
+
# @return [NArray]
|
120
|
+
def self.calculate_ndvi(red_band_array, nir_band_array)
|
121
|
+
(nir_band_array - red_band_array) / (nir_band_array + red_band_array)
|
122
|
+
end
|
123
|
+
|
117
124
|
def self.extract_8bit(source, destination, driver_name)
|
118
125
|
dataset = open(source, 'r')
|
119
126
|
geo_transform = dataset.geo_transform
|
@@ -313,39 +320,40 @@ module GDAL
|
|
313
320
|
end
|
314
321
|
end
|
315
322
|
|
316
|
-
# @param red_band_array [NArray]
|
317
|
-
# @param nir_band_array [NArray]
|
318
|
-
# @return [NArray]
|
319
|
-
def calculate_ndvi(red_band_array, nir_band_array)
|
320
|
-
(nir_band_array - red_band_array) / (nir_band_array + red_band_array)
|
321
|
-
end
|
322
|
-
|
323
323
|
# @return [GDAL::RasterBand]
|
324
324
|
def red_band
|
325
|
-
find_band do |band|
|
325
|
+
band = find_band do |band|
|
326
326
|
band.color_interpretation == :GCI_RedBand
|
327
327
|
end
|
328
|
+
|
329
|
+
band.is_a?(GDAL::RasterBand) ? band : nil
|
328
330
|
end
|
329
331
|
|
330
332
|
# @return [GDAL::RasterBand]
|
331
333
|
def green_band
|
332
|
-
find_band do |band|
|
334
|
+
band = find_band do |band|
|
333
335
|
band.color_interpretation == :GCI_GreenBand
|
334
336
|
end
|
337
|
+
|
338
|
+
band.is_a?(GDAL::RasterBand) ? band : nil
|
335
339
|
end
|
336
340
|
|
337
341
|
# @return [GDAL::RasterBand]
|
338
342
|
def blue_band
|
339
|
-
find_band do |band|
|
343
|
+
band = find_band do |band|
|
340
344
|
band.color_interpretation == :GCI_BlueBand
|
341
345
|
end
|
346
|
+
|
347
|
+
band.is_a?(GDAL::RasterBand) ? band : nil
|
342
348
|
end
|
343
349
|
|
344
350
|
# @return [GDAL::RasterBand]
|
345
351
|
def undefined_band
|
346
|
-
find_band do |band|
|
352
|
+
band = find_band do |band|
|
347
353
|
band.color_interpretation == :GCI_Undefined
|
348
354
|
end
|
355
|
+
|
356
|
+
band.is_a?(GDAL::RasterBand) ? band : nil
|
349
357
|
end
|
350
358
|
end
|
351
359
|
end
|
data/lib/ffi-gdal/raster_band.rb
CHANGED
@@ -16,10 +16,10 @@ module GDAL
|
|
16
16
|
# @param raster_band_pointer [FFI::Pointer] Requried if not passing in
|
17
17
|
# +band_id+.
|
18
18
|
def initialize(dataset, band_id: nil, raster_band_pointer: nil)
|
19
|
-
if dataset.is_a? GDAL::Dataset
|
20
|
-
|
19
|
+
@dataset = if dataset.is_a? GDAL::Dataset
|
20
|
+
dataset.c_pointer
|
21
21
|
else
|
22
|
-
|
22
|
+
dataset
|
23
23
|
end
|
24
24
|
|
25
25
|
@gdal_raster_band = if raster_band_pointer
|
@@ -303,6 +303,15 @@ module GDAL
|
|
303
303
|
GDALSetRasterUnitType(@gdal_raster_band, new_unit_type)
|
304
304
|
end
|
305
305
|
|
306
|
+
# @return [GDAL::RasterAttributeTable]
|
307
|
+
def default_raster_attribute_table
|
308
|
+
rat_pointer = GDALGetDefaultRAT(c_pointer)
|
309
|
+
return nil if rat_pointer.null?
|
310
|
+
|
311
|
+
GDAL::RasterAttributeTable.new(c_pointer,
|
312
|
+
raster_attribute_table_pointer: rat_pointer)
|
313
|
+
end
|
314
|
+
|
306
315
|
# Gets the default raster histogram. Results are returned as a Hash so some
|
307
316
|
# metadata about the histogram can be returned. Example:
|
308
317
|
#
|
@@ -330,25 +339,26 @@ module GDAL
|
|
330
339
|
# ]
|
331
340
|
# }
|
332
341
|
#
|
342
|
+
# Also, you can pass a block to get status on the processing. Conforms to
|
343
|
+
# FFI::GDAL::GDALProgressFunc.
|
344
|
+
#
|
333
345
|
# @param force [Boolean] Forces the computation of the histogram. If
|
334
346
|
# +false+ and the default histogram isn't available, this returns nil.
|
335
347
|
# @param block [Proc] No required, but can be used to output progess info
|
336
348
|
# during processing.
|
349
|
+
#
|
337
350
|
# @yieldparam completion [Float] The ration completed as a decimal.
|
338
351
|
# @yieldparam message [String] Message string to display.
|
352
|
+
#
|
339
353
|
# @return [Hash{minimum => Float, maximum => Float, buckets => Fixnum,
|
340
|
-
# totals => Array<Fixnum>}]
|
354
|
+
# totals => Array<Fixnum>}] Returns +nil+ if no default histogram is
|
355
|
+
# available.
|
341
356
|
def default_histogram(force=false, &block)
|
342
357
|
min_pointer = FFI::MemoryPointer.new(:double)
|
343
358
|
max_pointer = FFI::MemoryPointer.new(:double)
|
344
359
|
buckets_pointer = FFI::MemoryPointer.new(:int)
|
345
360
|
histogram_pointer = FFI::MemoryPointer.new(:pointer)
|
346
|
-
|
347
|
-
progress_proc = block || Proc.new do |completion, message, progress_arg|
|
348
|
-
puts "completion: #{completion * 100}"
|
349
|
-
puts "message: #{message}"
|
350
|
-
true
|
351
|
-
end
|
361
|
+
progress_proc = block || nil
|
352
362
|
|
353
363
|
cpl_err = GDALGetDefaultHistogram(@gdal_raster_band,
|
354
364
|
min_pointer,
|
@@ -363,28 +373,14 @@ module GDAL
|
|
363
373
|
min = min_pointer.read_double
|
364
374
|
max = max_pointer.read_double
|
365
375
|
buckets = buckets_pointer.read_int
|
366
|
-
totals = histogram_pointer.get_pointer(0).read_array_of_int(buckets)
|
367
376
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
maximum: max,
|
373
|
-
buckets: buckets,
|
374
|
-
totals: totals
|
375
|
-
}
|
376
|
-
when :warning then return nil
|
377
|
-
when :failure, :fatal then raise CPLError
|
377
|
+
totals = if buckets.zero?
|
378
|
+
[]
|
379
|
+
else
|
380
|
+
histogram_pointer.get_pointer(0).read_array_of_int(buckets)
|
378
381
|
end
|
379
|
-
end
|
380
382
|
|
381
|
-
|
382
|
-
def default_raster_attribute_table
|
383
|
-
rat_pointer = GDALGetDefaultRAT(c_pointer)
|
384
|
-
return nil if rat_pointer.null?
|
385
|
-
|
386
|
-
GDAL::RasterAttributeTable.new(c_pointer,
|
387
|
-
raster_attribute_table_pointer: rat_pointer)
|
383
|
+
formated_buckets(cpl_err, min, max, buckets, totals)
|
388
384
|
end
|
389
385
|
|
390
386
|
# Computes a histogram using the given inputs. If you just want the default
|
@@ -397,18 +393,18 @@ module GDAL
|
|
397
393
|
# @param approx_ok [Boolean]
|
398
394
|
# @param block [Proc] No required, but can be used to output progess info
|
399
395
|
# during processing.
|
396
|
+
#
|
400
397
|
# @yieldparam completion [Float] The ration completed as a decimal.
|
401
398
|
# @yieldparam message [String] Message string to display.
|
399
|
+
#
|
402
400
|
# @return [Hash{minimum => Float, maximum => Float, buckets => Fixnum,
|
403
401
|
# totals => Array<Fixnum>}]
|
402
|
+
#
|
403
|
+
# @see #default_histogram for more info.
|
404
404
|
def histogram(min, max, buckets, include_out_of_range: false,
|
405
|
-
approx_ok:
|
406
|
-
histogram_pointer = FFI::MemoryPointer.new(:
|
407
|
-
|
408
|
-
progress_proc = block || Proc.new do |completion, message, progress_arg|
|
409
|
-
puts "progress: #{completion * 100}"
|
410
|
-
true
|
411
|
-
end
|
405
|
+
approx_ok: false, &block)
|
406
|
+
histogram_pointer = FFI::MemoryPointer.new(:pointer, buckets)
|
407
|
+
progress_proc = block || nil
|
412
408
|
|
413
409
|
cpl_err = GDALGetRasterHistogram(@gdal_raster_band,
|
414
410
|
min.to_f,
|
@@ -418,21 +414,15 @@ module GDAL
|
|
418
414
|
include_out_of_range,
|
419
415
|
approx_ok,
|
420
416
|
progress_proc,
|
421
|
-
'doing things'
|
422
|
-
)
|
423
|
-
totals = histogram_pointer.read_array_of_int(0)
|
417
|
+
'doing things')
|
424
418
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
maximum: max,
|
430
|
-
buckets: buckets,
|
431
|
-
totals: totals
|
432
|
-
}
|
433
|
-
when :warning then return nil
|
434
|
-
when :failure then raise CPLError
|
419
|
+
totals = if buckets.zero?
|
420
|
+
[]
|
421
|
+
else
|
422
|
+
histogram_pointer.read_array_of_int(buckets)
|
435
423
|
end
|
424
|
+
|
425
|
+
formated_buckets(cpl_err, min, max, buckets, totals)
|
436
426
|
end
|
437
427
|
|
438
428
|
# TODO: Something about the pointer allocation smells here...
|
@@ -567,5 +557,26 @@ module GDAL
|
|
567
557
|
|
568
558
|
NArray.to_na(lines)
|
569
559
|
end
|
560
|
+
|
561
|
+
#---------------------------------------------------------------------------
|
562
|
+
# Privates
|
563
|
+
#---------------------------------------------------------------------------
|
564
|
+
|
565
|
+
private
|
566
|
+
|
567
|
+
def formated_buckets(cpl_err, min, max, buckets, totals)
|
568
|
+
case cpl_err.to_ruby
|
569
|
+
when :none
|
570
|
+
{
|
571
|
+
minimum: min,
|
572
|
+
maximum: max,
|
573
|
+
buckets: buckets,
|
574
|
+
totals: totals
|
575
|
+
}
|
576
|
+
when :warning then return nil
|
577
|
+
when :failure then raise CPLError
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
570
581
|
end
|
571
582
|
end
|
data/lib/ffi/gdal/version.rb
CHANGED
@@ -4,329 +4,335 @@ require 'ffi-gdal'
|
|
4
4
|
|
5
5
|
|
6
6
|
TIF_FILES.each do |file|
|
7
|
-
dataset =
|
7
|
+
dataset = GDAL::Dataset.open(file, 'r')
|
8
|
+
dataset.each_band do |band_under_test|
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
describe "Raster Band Info" do
|
11
|
+
after :suite do
|
12
|
+
dataset.close
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
# TODO: Test against each raster band
|
16
|
+
subject do
|
17
|
+
GDAL::RasterBand.new(dataset.c_pointer, raster_band_pointer: band_under_test.c_pointer)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
+
it_behaves_like 'a major object'
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
describe '#x_size' do
|
23
|
+
it 'is a non-zero Integer' do
|
24
|
+
expect(subject.x_size).to be_a Fixnum
|
25
|
+
expect(subject.x_size).to be > 0
|
26
|
+
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
describe '#y_size' do
|
30
|
+
it 'is a non-zero Integer' do
|
31
|
+
expect(subject.y_size).to be_a Fixnum
|
32
|
+
expect(subject.y_size).to be > 0
|
33
|
+
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
describe '#access_flag' do
|
37
|
+
specify { expect(subject.access_flag).to eq :GA_ReadOnly }
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
describe '#band_number' do
|
41
|
+
it 'is a non-zero Integer' do
|
42
|
+
expect(subject.band_number).to be_a Fixnum
|
43
|
+
expect(subject.band_number).to be > 0
|
44
|
+
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
describe '#color_interpretation' do
|
48
|
+
it 'is a Symbol; one of FFI::GDAL::GDALColorInterp' do
|
49
|
+
expect(subject.color_interpretation).to be_a Symbol
|
50
|
+
expect(FFI::GDAL::GDALColorInterp.symbols).to include subject.color_interpretation
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
describe '#color_table' do
|
55
|
+
it 'is a GDAL::ColorTable' do
|
56
|
+
if subject.color_table
|
57
|
+
expect(subject.color_table).to be_a GDAL::ColorTable
|
58
|
+
end
|
57
59
|
end
|
58
60
|
end
|
59
|
-
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
describe '#data_type' do
|
63
|
+
it 'is a Symbol; one of FFI::GDAL::GDALDataType' do
|
64
|
+
expect(subject.data_type).to be_a Symbol
|
65
|
+
expect(FFI::GDAL::GDALDataType.symbols).to include subject.data_type
|
66
|
+
end
|
65
67
|
end
|
66
|
-
end
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
describe '#block_size' do
|
70
|
+
it 'is a Hash with x and y keys that are >= 1' do
|
71
|
+
expect(subject.block_size).to be_a Hash
|
72
|
+
expect(subject.block_size[:x]).to be >= 1
|
73
|
+
expect(subject.block_size[:y]).to be >= 1
|
74
|
+
end
|
73
75
|
end
|
74
|
-
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
describe '#category_names' do
|
78
|
+
it 'is an Array of Strings' do
|
79
|
+
expect(subject.category_names).to be_an Array
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
subject.category_names.each do |category_name|
|
82
|
+
expect(category_name).to be_a String
|
83
|
+
expect(category_name).to_not be_empty
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
85
|
-
end
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
describe '#category_names=' do
|
89
|
+
around do |example|
|
90
|
+
category_names = subject.category_names
|
91
|
+
example.run
|
92
|
+
subject.category_names = category_names
|
93
|
+
end
|
93
94
|
|
94
|
-
|
95
|
-
|
95
|
+
it 'sets the category names' do
|
96
|
+
expect(subject.category_names).to be_empty
|
96
97
|
|
97
|
-
|
98
|
+
subject.category_names = %w[one two three]
|
98
99
|
|
99
|
-
|
100
|
+
expect(subject.category_names).to eq %w[one two three]
|
101
|
+
end
|
100
102
|
end
|
101
|
-
end
|
102
103
|
|
103
|
-
|
104
|
-
|
105
|
-
|
104
|
+
describe '#no_data_value' do
|
105
|
+
it 'is a Hash with :value and :is_associated keys' do
|
106
|
+
expect(subject.no_data_value).to be_an Hash
|
106
107
|
|
107
|
-
|
108
|
-
|
108
|
+
expect(subject.no_data_value[:value]).to be_a Float
|
109
|
+
expect(subject.no_data_value[:is_associated]).to_not be_nil
|
110
|
+
end
|
109
111
|
end
|
110
|
-
end
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
|
113
|
+
describe '#overview_count' do
|
114
|
+
it 'is a Fixnum' do
|
115
|
+
expect(subject.overview_count).to be_a Fixnum
|
116
|
+
end
|
115
117
|
end
|
116
|
-
end
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
119
|
+
describe '#arbitrary_overviews?' do
|
120
|
+
it 'is true or false' do
|
121
|
+
expect([true, false]).to include subject.arbitrary_overviews?
|
122
|
+
end
|
121
123
|
end
|
122
|
-
end
|
123
124
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
describe '#overview' do
|
126
|
+
it 'returns a GDAL::RasterBand if the overview exists' do
|
127
|
+
overview = subject.overview(0)
|
128
|
+
expect(overview).to be_a GDAL::RasterBand if overview
|
129
|
+
end
|
128
130
|
end
|
129
|
-
end
|
130
131
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
describe '#raster_sample_overview' do
|
133
|
+
it 'returns a GDAL::RasterBand if the overview exists' do
|
134
|
+
overview = subject.raster_sample_overview
|
135
|
+
expect(overview).to be_a GDAL::RasterBand
|
136
|
+
end
|
135
137
|
end
|
136
|
-
end
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
describe '#mask_band' do
|
140
|
+
it 'returns a GDAL::RasterBand if the mask_band exists' do
|
141
|
+
overview = subject.mask_band
|
142
|
+
expect(overview).to be_a GDAL::RasterBand
|
143
|
+
end
|
142
144
|
end
|
143
|
-
end
|
144
145
|
|
145
|
-
|
146
|
-
|
147
|
-
|
146
|
+
describe '#mask_flags' do
|
147
|
+
it 'returns an Array of Symbols' do
|
148
|
+
expect(subject.mask_flags).to eq [:GMF_ALL_VALID]
|
149
|
+
end
|
148
150
|
end
|
149
|
-
end
|
150
151
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
152
|
+
describe '#statistics' do
|
153
|
+
it 'returns a Hash with populated values' do
|
154
|
+
expect(subject.statistics).to be_a Hash
|
155
|
+
expect(%i[minimum maximum mean standard_deviation]).
|
156
|
+
to eq subject.statistics.keys
|
157
|
+
end
|
157
158
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
159
|
+
it 'has a :minimum that ranges between 0.0/-32768.0 and 255.0' do
|
160
|
+
min = subject.statistics[:minimum]
|
161
|
+
unless min == -32768.0
|
162
|
+
expect(subject.statistics[:minimum]).to((be >= 0.0) || (eq -32768.0))
|
163
|
+
expect(subject.statistics[:minimum]).to be <= 255.0
|
164
|
+
end
|
163
165
|
end
|
164
166
|
end
|
165
|
-
end
|
166
167
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
describe '#scale' do
|
169
|
+
it 'returns a Hash with populated values' do
|
170
|
+
expect(subject.statistics).to be_a Hash
|
171
|
+
expect(%i[value is_meaningful]).to eq subject.scale.keys
|
172
|
+
end
|
172
173
|
|
173
|
-
|
174
|
-
|
175
|
-
|
174
|
+
it 'has a :value that is a Float' do
|
175
|
+
expect(subject.scale[:value]).to be_a Float
|
176
|
+
end
|
176
177
|
|
177
|
-
|
178
|
-
|
178
|
+
it 'has a :is_meaningful that is false (since the examples are geotiffs)' do
|
179
|
+
expect(subject.scale[:is_meaningful]).to eq false
|
180
|
+
end
|
179
181
|
end
|
180
|
-
end
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
183
|
+
describe '#scale=' do
|
184
|
+
around do |example|
|
185
|
+
scale = subject.scale[:value]
|
186
|
+
example.run
|
187
|
+
subject.scale = scale
|
188
|
+
end
|
188
189
|
|
189
|
-
|
190
|
-
|
191
|
-
|
190
|
+
it 'does nothing (because the file formats dont support it)' do
|
191
|
+
subject.scale = 0.1
|
192
|
+
expect(subject.scale[:value]).to eq 0.1
|
193
|
+
end
|
192
194
|
end
|
193
|
-
end
|
194
195
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
196
|
+
describe '#offset' do
|
197
|
+
it 'returns a Hash with populated values' do
|
198
|
+
expect(subject.offset).to be_a Hash
|
199
|
+
expect(%i[value is_meaningful]).to eq subject.offset.keys
|
200
|
+
end
|
200
201
|
|
201
|
-
|
202
|
-
|
203
|
-
|
202
|
+
it 'has a :value that is a Float' do
|
203
|
+
expect(subject.offset[:value]).to be_a Float
|
204
|
+
end
|
204
205
|
|
205
|
-
|
206
|
-
|
206
|
+
it 'has a :is_meaningful that is false (since the examples are geotiffs)' do
|
207
|
+
expect(subject.offset[:is_meaningful]).to eq false
|
208
|
+
end
|
207
209
|
end
|
208
|
-
end
|
209
210
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
211
|
+
describe '#offset=' do
|
212
|
+
around do |example|
|
213
|
+
offset = subject.offset[:value]
|
214
|
+
example.run
|
215
|
+
subject.offset = offset
|
216
|
+
end
|
216
217
|
|
217
|
-
|
218
|
-
|
219
|
-
|
218
|
+
it 'does nothing (because the file formats dont support it)' do
|
219
|
+
subject.offset = 0.1
|
220
|
+
expect(subject.offset[:value]).to eq 0.1
|
221
|
+
end
|
220
222
|
end
|
221
|
-
end
|
222
223
|
|
223
|
-
|
224
|
-
|
225
|
-
|
224
|
+
describe '#unit_type' do
|
225
|
+
it 'returns a String' do
|
226
|
+
expect(subject.unit_type).to be_a String
|
227
|
+
end
|
226
228
|
end
|
227
|
-
end
|
228
229
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
230
|
+
describe '#unit_type=' do
|
231
|
+
around do |example|
|
232
|
+
unit_type = subject.unit_type
|
233
|
+
example.run
|
234
|
+
subject.unit_type = unit_type
|
235
|
+
end
|
235
236
|
|
236
|
-
|
237
|
-
|
238
|
-
|
237
|
+
it 'does nothing (because the file formats dont support it)' do
|
238
|
+
subject.unit_type = 'ft'
|
239
|
+
expect(subject.unit_type).to eq 'ft'
|
240
|
+
end
|
239
241
|
end
|
240
|
-
end
|
241
242
|
|
242
|
-
|
243
|
-
|
243
|
+
describe '#default_histogram' do
|
244
|
+
let!(:histogram) { subject.default_histogram }
|
244
245
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
246
|
+
it 'returns a Hash with :mininum, :maximum, :buckets, and :totals' do
|
247
|
+
if histogram
|
248
|
+
expect(histogram).to be_a Hash
|
249
|
+
expect(histogram.keys).to eq %i[minimum maximum buckets totals]
|
250
|
+
end
|
251
|
+
end
|
249
252
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
+
it 'has :mimimum as a Float' do
|
254
|
+
expect(histogram[:minimum]).to be_a Float if histogram
|
255
|
+
end
|
253
256
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
+
it 'has :maximum as a Float' do
|
258
|
+
expect(histogram[:maximum]).to be_a Float if histogram
|
259
|
+
end
|
257
260
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
+
it 'has :buckets as a Fixnum' do
|
262
|
+
expect(histogram[:buckets]).to be_a Fixnum if histogram
|
263
|
+
end
|
261
264
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
265
|
+
it 'has :totals as an Array of 256 Fixnums' do
|
266
|
+
if histogram
|
267
|
+
expect(histogram[:totals]).to be_an Array
|
268
|
+
expect(histogram[:totals].size).to eq 256
|
269
|
+
expect(histogram[:totals].all? { |t| t.class == Fixnum}).to eq true
|
270
|
+
end
|
271
|
+
end
|
266
272
|
end
|
267
|
-
end
|
268
273
|
|
269
|
-
|
270
|
-
|
271
|
-
|
274
|
+
describe '#default_raster_attribute_table' do
|
275
|
+
it 'returns a GDAL::RasterAttributeTable' do
|
276
|
+
rat = subject.default_raster_attribute_table
|
272
277
|
|
273
|
-
|
274
|
-
|
278
|
+
if rat
|
279
|
+
expect(rat).to be_a GDAL::RasterAttributeTable
|
280
|
+
end
|
275
281
|
end
|
276
282
|
end
|
277
|
-
end
|
278
283
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
284
|
+
describe '#compute_min_max' do
|
285
|
+
it 'returns a 2-element Array of Floats' do
|
286
|
+
expect(subject.compute_min_max).to be_a Array
|
287
|
+
expect(subject.compute_min_max.size).to eq 2
|
288
|
+
expect(subject.compute_min_max.first).to be_a Float
|
289
|
+
expect(subject.compute_min_max.last).to be_a Float
|
290
|
+
end
|
286
291
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
292
|
+
it 'has a min that is < its max' do
|
293
|
+
min, max = subject.compute_min_max
|
294
|
+
expect(min).to be < max
|
295
|
+
end
|
291
296
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
297
|
+
it 'has a min that == statistics[:minimum]' do
|
298
|
+
min, _ = subject.compute_min_max
|
299
|
+
expect(min).to eq subject.statistics[:minimum]
|
300
|
+
end
|
296
301
|
|
297
|
-
|
298
|
-
|
299
|
-
|
302
|
+
it 'has a min that == minimum_value[:value]' do
|
303
|
+
min, _ = subject.compute_min_max
|
304
|
+
expect(min).to eq subject.minimum_value[:value]
|
305
|
+
end
|
300
306
|
end
|
301
|
-
end
|
302
307
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
+
describe '#minimum_value' do
|
309
|
+
it 'returns a Hash with populated values' do
|
310
|
+
expect(subject.minimum_value).to be_a Hash
|
311
|
+
expect(%i[value is_tight]).to eq subject.minimum_value.keys
|
312
|
+
end
|
308
313
|
|
309
|
-
|
310
|
-
|
311
|
-
|
314
|
+
it 'has a :value that is a Float' do
|
315
|
+
expect(subject.minimum_value[:value]).to be_a Float
|
316
|
+
end
|
312
317
|
|
313
|
-
|
314
|
-
|
318
|
+
it 'has a :is_tight that is nil (since the examples are geotiffs)' do
|
319
|
+
#expect(subject.minimum_value[:is_tight]).to eq nil
|
320
|
+
end
|
315
321
|
end
|
316
|
-
end
|
317
322
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
+
describe '#maximum_value' do
|
324
|
+
it 'returns a Hash with populated values' do
|
325
|
+
expect(subject.maximum_value).to be_a Hash
|
326
|
+
expect(%i[value is_tight]).to eq subject.maximum_value.keys
|
327
|
+
end
|
323
328
|
|
324
|
-
|
325
|
-
|
326
|
-
|
329
|
+
it 'has a :value that is a Float' do
|
330
|
+
expect(subject.maximum_value[:value]).to be_a Float
|
331
|
+
end
|
327
332
|
|
328
|
-
|
329
|
-
|
333
|
+
it 'has a :is_tight that is nil (since the examples are geotiffs)' do
|
334
|
+
#expect(subject.maximum_value[:is_tight]).to eq nil
|
335
|
+
end
|
330
336
|
end
|
331
337
|
end
|
332
338
|
end
|