ffi-gdal 0.0.4 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +7 -1
- data/Rakefile +12 -1
- data/TODO.md +11 -0
- data/ffi-gdal.gemspec +2 -2
- data/lib/ext/error_symbols.rb +59 -0
- data/lib/ext/float_ext.rb +15 -0
- data/lib/ext/narray_ext.rb +16 -0
- data/lib/ext/to_bool.rb +2 -0
- data/lib/ffi-gdal.rb +139 -4
- data/lib/ffi/{gdal/cpl_conv.rb → cpl/conv_h.rb} +2 -3
- data/lib/ffi/{gdal/cpl_error.rb → cpl/error_h.rb} +1 -25
- data/lib/ffi/cpl/minixml_h.rb +14 -0
- data/lib/ffi/{gdal/cpl_string.rb → cpl/string_h.rb} +0 -25
- data/lib/ffi/{gdal/cpl_vsi.rb → cpl/vsi_h.rb} +0 -0
- data/lib/ffi/cpl/xml_node.rb +13 -0
- data/lib/ffi/gdal.rb +57 -593
- data/lib/ffi/gdal/alg_h.rb +127 -0
- data/lib/ffi/gdal/gdal_grid_data_metrics_options.rb +14 -0
- data/lib/ffi/gdal/gdal_grid_inverse_distance_to_a_power_options.rb +19 -0
- data/lib/ffi/gdal/gdal_grid_moving_average_options.rb +14 -0
- data/lib/ffi/gdal/gdal_grid_nearest_neighbor_options.rb +13 -0
- data/lib/ffi/gdal/gdal_h.rb +683 -0
- data/lib/ffi/gdal/gdal_rpc_info.rb +27 -0
- data/lib/ffi/gdal/gdal_transformer_info.rb +14 -0
- data/lib/ffi/gdal/gdal_warp_options.rb +43 -0
- data/lib/ffi/gdal/grid_h.rb +51 -0
- data/lib/ffi/gdal/version.rb +1 -1
- data/lib/ffi/gdal/warper_h.rb +48 -0
- data/lib/ffi/ogr.rb +12 -0
- data/lib/ffi/ogr/api_h.rb +553 -0
- data/lib/ffi/ogr/core_h.rb +148 -0
- data/lib/ffi/ogr/featurestyle_h.rb +22 -0
- data/lib/ffi/ogr/geocoding_h.rb +21 -0
- data/lib/ffi/ogr/ogr_contour_writer_info.rb +14 -0
- data/lib/ffi/ogr/ogr_envelope.rb +12 -0
- data/lib/ffi/ogr/ogr_envelope_3d.rb +14 -0
- data/lib/ffi/ogr/ogr_field.rb +50 -0
- data/lib/ffi/ogr/ogr_style_param.rb +12 -0
- data/lib/ffi/ogr/ogr_style_value.rb +13 -0
- data/lib/ffi/ogr/srs_api_h.rb +325 -0
- data/lib/gdal/color_entry.rb +47 -0
- data/lib/gdal/color_entry_extensions.rb +30 -0
- data/lib/gdal/color_interpretation.rb +15 -0
- data/lib/gdal/color_table.rb +146 -0
- data/lib/gdal/color_table_extensions.rb +47 -0
- data/lib/gdal/color_table_types/cmyk.rb +25 -0
- data/lib/gdal/color_table_types/gray.rb +9 -0
- data/lib/gdal/color_table_types/hls.rb +21 -0
- data/lib/gdal/color_table_types/rgb.rb +25 -0
- data/lib/gdal/data_type.rb +38 -0
- data/lib/gdal/dataset.rb +437 -0
- data/lib/gdal/dataset_extensions.rb +496 -0
- data/lib/gdal/driver.rb +244 -0
- data/lib/gdal/driver_extensions.rb +56 -0
- data/lib/gdal/environment_methods.rb +43 -0
- data/lib/{ffi-gdal → gdal}/exceptions.rb +4 -1
- data/lib/gdal/geo_transform.rb +188 -0
- data/lib/gdal/geo_transform_extensions.rb +90 -0
- data/lib/gdal/logger.rb +7 -0
- data/lib/{ffi-gdal → gdal}/major_object.rb +15 -14
- data/lib/gdal/options.rb +49 -0
- data/lib/gdal/raster_attribute_table.rb +185 -0
- data/lib/gdal/raster_attribute_table_extensions.rb +40 -0
- data/lib/{ffi-gdal → gdal}/raster_band.rb +227 -99
- data/lib/gdal/raster_band_extensions.rb +198 -0
- data/lib/{ffi-gdal → gdal}/version_info.rb +8 -0
- data/lib/gdal/warp_operation.rb +96 -0
- data/lib/ogr/coordinate_transformation.rb +108 -0
- data/lib/ogr/data_source.rb +172 -0
- data/lib/ogr/data_source_extensions.rb +32 -0
- data/lib/ogr/driver.rb +119 -0
- data/lib/ogr/envelope.rb +80 -0
- data/lib/ogr/envelope_extensions.rb +92 -0
- data/lib/ogr/exceptions.rb +35 -0
- data/lib/ogr/feature.rb +212 -0
- data/lib/ogr/feature_definition.rb +120 -0
- data/lib/ogr/feature_definition_extensions.rb +36 -0
- data/lib/ogr/feature_extensions.rb +31 -0
- data/lib/ogr/field.rb +91 -0
- data/lib/ogr/field_extensions.rb +23 -0
- data/lib/ogr/geocoding_session.rb +84 -0
- data/lib/ogr/geometry.rb +617 -0
- data/lib/ogr/geometry_extensions.rb +60 -0
- data/lib/ogr/geometry_types/collection.rb +45 -0
- data/lib/ogr/geometry_types/curve.rb +120 -0
- data/lib/ogr/geometry_types/surface.rb +20 -0
- data/lib/ogr/layer.rb +226 -0
- data/lib/ogr/layer_extensions.rb +55 -0
- data/lib/ogr/line_string.rb +7 -0
- data/lib/ogr/linear_ring.rb +6 -0
- data/lib/ogr/multi_line_string.rb +9 -0
- data/lib/ogr/multi_point.rb +7 -0
- data/lib/ogr/multi_polygon.rb +14 -0
- data/lib/ogr/point.rb +89 -0
- data/lib/ogr/polygon.rb +9 -0
- data/lib/ogr/spatial_reference.rb +723 -0
- data/lib/ogr/spatial_reference_extensions.rb +32 -0
- data/lib/ogr/style_table.rb +17 -0
- data/lib/ogr/style_table_extensions.rb +16 -0
- data/spec/{ffi-gdal/integration → integration}/color_table_info_spec.rb +1 -1
- data/spec/{ffi-gdal/integration → integration}/dataset_info_spec.rb +0 -0
- data/spec/{ffi-gdal/integration → integration}/driver_info_spec.rb +1 -1
- data/spec/{ffi-gdal/integration → integration}/geo_transform_info_spec.rb +0 -0
- data/spec/{ffi-gdal/integration → integration}/raster_attribute_table_info_spec.rb +1 -1
- data/spec/{ffi-gdal/integration → integration}/raster_band_info_spec.rb +5 -5
- data/spec/spec_helper.rb +4 -1
- data/spec/support/shapefiles/states_21basic/states.prj +1 -0
- data/spec/support/shapefiles/states_21basic/states.sbn +0 -0
- data/spec/support/shapefiles/states_21basic/states.sbx +0 -0
- data/spec/support/shapefiles/states_21basic/states.shp +0 -0
- data/spec/support/worldfiles/SR_50M/SR_50M.VERSION.txt +1 -0
- data/spec/support/worldfiles/SR_50M/SR_50M.prj +1 -0
- data/spec/support/worldfiles/SR_50M/SR_50M.tfw +6 -0
- data/spec/{ext/cpl_error_symbols_spec.rb → unit/ext/error_symbols_spec.rb} +1 -1
- data/spec/unit/gdal/color_table_spec.rb +146 -0
- data/spec/unit/ogr/layer_spec.rb +97 -0
- data/spec/unit/ogr/linear_ring_spec.rb +111 -0
- data/spec/unit/ogr/point_spec.rb +321 -0
- data/spec/{ffi-gdal/unit → unit}/version_info_spec.rb +1 -1
- data/testing_gdal.rb +168 -0
- data/testing_gdalwarp.rb +91 -0
- data/testing_layer_to_layer.rb +35 -0
- data/testing_ndvi.rb +76 -0
- data/testing_nir.rb +77 -0
- data/testing_ogr.rb +63 -0
- metadata +167 -59
- data/lib/ext/cpl_error_symbols.rb +0 -37
- data/lib/ffi-gdal/color_table.rb +0 -59
- data/lib/ffi-gdal/dataset.rb +0 -359
- data/lib/ffi-gdal/driver.rb +0 -151
- data/lib/ffi-gdal/geo_transform.rb +0 -137
- data/lib/ffi-gdal/raster_attribute_table.rb +0 -78
- data/lib/ffi/gdal/ogr_api.rb +0 -21
- data/lib/ffi/gdal/ogr_core.rb +0 -195
- data/lib/ffi/gdal/ogr_srs_api.rb +0 -44
- data/meow.rb +0 -144
- data/rubby.rb +0 -224
@@ -1,4 +1,6 @@
|
|
1
1
|
require_relative '../ffi/gdal'
|
2
|
+
require_relative '../ffi/ogr/api_h'
|
3
|
+
require_relative 'raster_band_extensions'
|
2
4
|
require_relative 'color_table'
|
3
5
|
require_relative 'major_object'
|
4
6
|
require_relative 'raster_attribute_table'
|
@@ -6,33 +8,29 @@ require 'narray'
|
|
6
8
|
|
7
9
|
module GDAL
|
8
10
|
class RasterBand
|
9
|
-
include FFI::GDAL
|
10
11
|
include MajorObject
|
12
|
+
include GDAL::Logger
|
13
|
+
include RasterBandExtensions
|
11
14
|
|
12
|
-
|
15
|
+
ALL_VALID = 0x01
|
16
|
+
PER_DATASET = 0x02
|
17
|
+
ALPHA = 0x04
|
18
|
+
NODATA = 0x08
|
13
19
|
|
14
|
-
# @param
|
15
|
-
|
16
|
-
|
17
|
-
# +band_id+.
|
18
|
-
def initialize(dataset, band_id: nil, raster_band_pointer: nil)
|
19
|
-
@dataset = if dataset.is_a? GDAL::Dataset
|
20
|
-
dataset.c_pointer
|
21
|
-
else
|
22
|
-
dataset
|
23
|
-
end
|
24
|
-
|
25
|
-
@gdal_raster_band = if raster_band_pointer
|
26
|
-
raster_band_pointer
|
27
|
-
elsif band_id
|
28
|
-
GDALGetRasterBand(@dataset, band_id)
|
29
|
-
else
|
30
|
-
raise 'Must pass in band_id or the raster_band_pointer.'
|
31
|
-
end
|
20
|
+
# @param raster_band [GDAL::RasterBand, FFI::Pointer]
|
21
|
+
def initialize(raster_band=nil)
|
22
|
+
@raster_band_pointer = GDAL._pointer(GDAL::RasterBand, raster_band)
|
32
23
|
end
|
33
24
|
|
34
25
|
def c_pointer
|
35
|
-
@
|
26
|
+
@raster_band_pointer
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Boolean]
|
30
|
+
def flush_cache
|
31
|
+
cpl_err = FFI::GDAL.GDALFlushRasterCache(@raster_band_pointer)
|
32
|
+
|
33
|
+
cpl_err.to_bool
|
36
34
|
end
|
37
35
|
|
38
36
|
# The raster width in pixels.
|
@@ -41,7 +39,7 @@ module GDAL
|
|
41
39
|
def x_size
|
42
40
|
return nil if null?
|
43
41
|
|
44
|
-
GDALGetRasterBandXSize(@
|
42
|
+
FFI::GDAL.GDALGetRasterBandXSize(@raster_band_pointer)
|
45
43
|
end
|
46
44
|
|
47
45
|
# The raster height in pixels.
|
@@ -50,7 +48,7 @@ module GDAL
|
|
50
48
|
def y_size
|
51
49
|
return nil if null?
|
52
50
|
|
53
|
-
GDALGetRasterBandYSize(@
|
51
|
+
FFI::GDAL.GDALGetRasterBandYSize(@raster_band_pointer)
|
54
52
|
end
|
55
53
|
|
56
54
|
# The type of access to the raster band this object currently has.
|
@@ -59,38 +57,66 @@ module GDAL
|
|
59
57
|
def access_flag
|
60
58
|
return nil if null?
|
61
59
|
|
62
|
-
GDALGetRasterAccess(@
|
60
|
+
FFI::GDAL.GDALGetRasterAccess(@raster_band_pointer)
|
63
61
|
end
|
64
62
|
|
65
63
|
# The number of band within the associated dataset that this band
|
66
64
|
# represents.
|
67
65
|
#
|
68
66
|
# @return [Fixnum]
|
69
|
-
def
|
67
|
+
def number
|
70
68
|
return nil if null?
|
71
69
|
|
72
|
-
GDALGetBandNumber(@
|
70
|
+
FFI::GDAL.GDALGetBandNumber(@raster_band_pointer)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [GDAL::Dataset, nil]
|
74
|
+
def dataset
|
75
|
+
return @dataset if @dataset
|
76
|
+
|
77
|
+
dataset_ptr = FFI::GDAL.GDALGetBandDataset(@raster_band_pointer)
|
78
|
+
return nil if dataset_ptr.null?
|
79
|
+
|
80
|
+
@dataset = GDAL::Dataset.new(dataset_ptr)
|
73
81
|
end
|
74
82
|
|
75
83
|
# @return [Symbol] One of FFI::GDAL::GDALColorInterp.
|
76
84
|
def color_interpretation
|
77
|
-
GDALGetRasterColorInterpretation(@
|
85
|
+
FFI::GDAL.GDALGetRasterColorInterpretation(@raster_band_pointer)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Boolean]
|
89
|
+
def color_interpretation=(new_color_interp)
|
90
|
+
cpl_err = FFI::GDAL.GDALSetRasterColorInterpretation(@raster_band_pointer,
|
91
|
+
new_color_interp)
|
92
|
+
|
93
|
+
cpl_err.to_bool
|
78
94
|
end
|
79
95
|
|
80
96
|
# @return [GDAL::ColorTable]
|
81
97
|
def color_table
|
82
|
-
|
98
|
+
return @color_table if @color_table
|
99
|
+
|
100
|
+
gdal_color_table = FFI::GDAL.GDALGetRasterColorTable(@raster_band_pointer)
|
83
101
|
return nil if gdal_color_table.null?
|
84
102
|
|
85
|
-
@color_table
|
86
|
-
|
103
|
+
@color_table = ColorTable.new(gdal_color_table)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @param new_color_table [GDAL::ColorTable]
|
107
|
+
def color_table=(new_color_table)
|
108
|
+
color_table_pointer = GDAL._pointer(GDAL::ColorTable, new_color_table)
|
109
|
+
cpl_err = FFI::GDAL.GDALSetRasterColorTable(@raster_band_pointer, color_table_pointer)
|
110
|
+
@color_table = ColorTable.new(color_table_pointer)
|
111
|
+
|
112
|
+
cpl_err.to_bool
|
87
113
|
end
|
88
114
|
|
89
115
|
# The pixel data type for this band.
|
90
116
|
#
|
91
117
|
# @return [Symbol] One of FFI::GDAL::GDALDataType.
|
92
118
|
def data_type
|
93
|
-
GDALGetRasterDataType(@
|
119
|
+
FFI::GDAL.GDALGetRasterDataType(@raster_band_pointer)
|
94
120
|
end
|
95
121
|
|
96
122
|
# The natural block size is the block size that is most efficient for
|
@@ -101,14 +127,14 @@ module GDAL
|
|
101
127
|
def block_size
|
102
128
|
x_pointer = FFI::MemoryPointer.new(:int)
|
103
129
|
y_pointer = FFI::MemoryPointer.new(:int)
|
104
|
-
GDALGetBlockSize(@
|
130
|
+
FFI::GDAL.GDALGetBlockSize(@raster_band_pointer, x_pointer, y_pointer)
|
105
131
|
|
106
132
|
{ x: x_pointer.read_int, y: y_pointer.read_int }
|
107
133
|
end
|
108
134
|
|
109
135
|
# @return [Array<String>]
|
110
136
|
def category_names
|
111
|
-
names = GDALGetRasterCategoryNames(@
|
137
|
+
names = FFI::GDAL.GDALGetRasterCategoryNames(@raster_band_pointer)
|
112
138
|
return [] if names.null?
|
113
139
|
|
114
140
|
names.get_array_of_string(0)
|
@@ -128,7 +154,7 @@ module GDAL
|
|
128
154
|
names_pointer[i].put_pointer(0, ptr)
|
129
155
|
end
|
130
156
|
|
131
|
-
cpl_err = GDALSetRasterCategoryNames(@
|
157
|
+
cpl_err = FFI::GDAL.GDALSetRasterCategoryNames(@raster_band_pointer, names_pointer)
|
132
158
|
|
133
159
|
cpl_err.to_ruby(warning: [])
|
134
160
|
end
|
@@ -140,19 +166,29 @@ module GDAL
|
|
140
166
|
# @return [Hash{value => Float, is_associated => Boolean}]
|
141
167
|
def no_data_value
|
142
168
|
associated = FFI::MemoryPointer.new(:bool)
|
143
|
-
value = GDALGetRasterNoDataValue(@
|
169
|
+
value = FFI::GDAL.GDALGetRasterNoDataValue(@raster_band_pointer, associated)
|
144
170
|
|
145
171
|
{ value: value, is_associated: associated.read_bytes(1).to_bool }
|
146
172
|
end
|
147
173
|
|
174
|
+
# Sets the no data value for this band.
|
175
|
+
#
|
176
|
+
# @param value [Float]
|
177
|
+
# @return [Boolean]
|
178
|
+
def no_data_value=(value)
|
179
|
+
cpl_err = FFI::GDAL.GDALSetRasterNoDataValue(@raster_band_pointer, value)
|
180
|
+
|
181
|
+
cpl_err.to_bool
|
182
|
+
end
|
183
|
+
|
148
184
|
# @return [Fixnum]
|
149
185
|
def overview_count
|
150
|
-
GDALGetOverviewCount(@
|
186
|
+
FFI::GDAL.GDALGetOverviewCount(@raster_band_pointer)
|
151
187
|
end
|
152
188
|
|
153
189
|
# @return [Boolean]
|
154
190
|
def arbitrary_overviews?
|
155
|
-
GDALHasArbitraryOverviews(@
|
191
|
+
FFI::GDAL.GDALHasArbitraryOverviews(@raster_band_pointer).zero? ? false : true
|
156
192
|
end
|
157
193
|
|
158
194
|
# @param index [Fixnum] Must be between 0 and (#overview_count - 1).
|
@@ -160,10 +196,10 @@ module GDAL
|
|
160
196
|
def overview(index)
|
161
197
|
return nil if overview_count.zero?
|
162
198
|
|
163
|
-
overview_pointer = GDALGetOverview(@
|
199
|
+
overview_pointer = FFI::GDAL.GDALGetOverview(@raster_band_pointer, index)
|
164
200
|
return nil if overview_pointer.null?
|
165
201
|
|
166
|
-
self.class.new(
|
202
|
+
self.class.new(overview_pointer)
|
167
203
|
end
|
168
204
|
|
169
205
|
# @param desired_samples [Fixnum] The returned band will have at least this
|
@@ -171,23 +207,23 @@ module GDAL
|
|
171
207
|
# @return [GDAL::RasterBand] An optimal overview or the same raster band if
|
172
208
|
# the raster band has no overviews.
|
173
209
|
def raster_sample_overview(desired_samples=0)
|
174
|
-
band_pointer = GDALGetRasterSampleOverview(@
|
210
|
+
band_pointer = FFI::GDAL.GDALGetRasterSampleOverview(@raster_band_pointer, desired_samples)
|
175
211
|
return nil if band_pointer.null?
|
176
212
|
|
177
|
-
self.class.new(
|
213
|
+
self.class.new(band_pointer)
|
178
214
|
end
|
179
215
|
|
180
216
|
# @return [GDAL::RasterBand]
|
181
217
|
def mask_band
|
182
|
-
band_pointer = GDALGetMaskBand(@
|
218
|
+
band_pointer = FFI::GDAL.GDALGetMaskBand(@raster_band_pointer)
|
183
219
|
return nil if band_pointer.null?
|
184
220
|
|
185
|
-
self.class.new(
|
221
|
+
self.class.new(band_pointer)
|
186
222
|
end
|
187
223
|
|
188
224
|
# @return [Array<Symbol>]
|
189
225
|
def mask_flags
|
190
|
-
flag_list = GDALGetMaskFlags(@
|
226
|
+
flag_list = FFI::GDAL.GDALGetMaskFlags(@raster_band_pointer).to_s(2).scan(/\d/)
|
191
227
|
flags = []
|
192
228
|
|
193
229
|
flag_list.reverse.each_with_index do |flag, i|
|
@@ -205,6 +241,24 @@ module GDAL
|
|
205
241
|
flags
|
206
242
|
end
|
207
243
|
|
244
|
+
# @return [Boolean]
|
245
|
+
def create_mask_band(flags)
|
246
|
+
cpl_err = FFI::GDAL.GDALCreateMaskBand(@raster_band_pointer, flags)
|
247
|
+
|
248
|
+
cpl_err.to_bool
|
249
|
+
end
|
250
|
+
|
251
|
+
# Fill this band with constant value. Useful for clearing a band and
|
252
|
+
# setting to a default value.
|
253
|
+
#
|
254
|
+
# @param real_value [Float]
|
255
|
+
# @param imaginary_value [Float]
|
256
|
+
def fill(real_value, imaginary_value=0)
|
257
|
+
cpl_err = FFI::GDAL.GDALFillRaster(@raster_band_pointer, real_value, imaginary_value)
|
258
|
+
|
259
|
+
cpl_err.to_bool
|
260
|
+
end
|
261
|
+
|
208
262
|
# Returns minimum, maximum, mean, and standard deviation of all pixel values
|
209
263
|
# in this band.
|
210
264
|
#
|
@@ -212,7 +266,7 @@ module GDAL
|
|
212
266
|
# overviews or a subset of all tiles.
|
213
267
|
# @param force [Boolean] If +false+, stats will only be returned if the
|
214
268
|
# calculating can be done without rescanning the image.
|
215
|
-
# @return [Hash{
|
269
|
+
# @return [Hash{minimum: Float, maximum: Float, mean: Float,
|
216
270
|
# standard_deviation: Float}]
|
217
271
|
def statistics(approx_ok=true, force=true)
|
218
272
|
min = FFI::MemoryPointer.new(:double)
|
@@ -220,7 +274,7 @@ module GDAL
|
|
220
274
|
mean = FFI::MemoryPointer.new(:double)
|
221
275
|
standard_deviation = FFI::MemoryPointer.new(:double)
|
222
276
|
|
223
|
-
cpl_err = GDALGetRasterStatistics(@
|
277
|
+
cpl_err = FFI::GDAL.GDALGetRasterStatistics(@raster_band_pointer,
|
224
278
|
approx_ok,
|
225
279
|
force,
|
226
280
|
min,
|
@@ -228,8 +282,6 @@ module GDAL
|
|
228
282
|
mean,
|
229
283
|
standard_deviation)
|
230
284
|
|
231
|
-
minimum = min.null? ? 0.0 : min.read_double
|
232
|
-
|
233
285
|
case cpl_err.to_ruby
|
234
286
|
when :none, :debug
|
235
287
|
{
|
@@ -240,6 +292,7 @@ module GDAL
|
|
240
292
|
}
|
241
293
|
when :warning then {}
|
242
294
|
when :failure, :fatal then raise CPLErrFailure
|
295
|
+
else raise CPLErrFailure
|
243
296
|
end
|
244
297
|
end
|
245
298
|
|
@@ -256,15 +309,17 @@ module GDAL
|
|
256
309
|
# @return [Hash{value => Float, is_meaningful => Boolean}]
|
257
310
|
def scale
|
258
311
|
meaningful = FFI::MemoryPointer.new(:bool)
|
259
|
-
result = GDALGetRasterScale(@
|
312
|
+
result = FFI::GDAL.GDALGetRasterScale(@raster_band_pointer, meaningful)
|
260
313
|
|
261
314
|
{ value: result, is_meaningful: meaningful.read_bytes(1).to_bool }
|
262
315
|
end
|
263
316
|
|
264
317
|
# @param new_scale [Float]
|
265
|
-
# @return [
|
318
|
+
# @return [Boolean]
|
266
319
|
def scale=(new_scale)
|
267
|
-
GDALSetRasterScale(@
|
320
|
+
cpl_err = FFI::GDAL.GDALSetRasterScale(@raster_band_pointer, new_scale.to_f)
|
321
|
+
|
322
|
+
cpl_err.to_bool
|
268
323
|
end
|
269
324
|
|
270
325
|
# This value (in combination with the GetScale() value) is used to
|
@@ -280,28 +335,32 @@ module GDAL
|
|
280
335
|
# @return [Hash{value => Float, is_meaningful => Boolean}]
|
281
336
|
def offset
|
282
337
|
meaningful = FFI::MemoryPointer.new(:bool)
|
283
|
-
result = GDALGetRasterOffset(@
|
338
|
+
result = FFI::GDAL.GDALGetRasterOffset(@raster_band_pointer, meaningful)
|
284
339
|
|
285
340
|
{ value: result, is_meaningful: meaningful.read_bytes(1).to_bool }
|
286
341
|
end
|
287
342
|
|
288
343
|
# @param new_offset [Float]
|
289
|
-
# @return [
|
344
|
+
# @return [Boolean]
|
290
345
|
def offset=(new_offset)
|
291
|
-
GDALSetRasterOffset(@
|
346
|
+
cpl_err = FFI::GDAL.GDALSetRasterOffset(@raster_band_pointer, new_offset)
|
347
|
+
|
348
|
+
cpl_err.to_bool
|
292
349
|
end
|
293
350
|
|
294
351
|
# @return [String]
|
295
352
|
def unit_type
|
296
|
-
GDALGetRasterUnitType(@
|
353
|
+
FFI::GDAL.GDALGetRasterUnitType(@raster_band_pointer)
|
297
354
|
end
|
298
355
|
|
299
356
|
# @param new_unit_type [String] "" indicates unknown, "m" is meters, "ft"
|
300
357
|
# is feet; other non-standard values are allowed.
|
301
|
-
# @return [
|
358
|
+
# @return [Boolean]
|
302
359
|
def unit_type=(new_unit_type)
|
303
360
|
if defined? FFI::GDAL::GDALSetRasterUnitType
|
304
|
-
GDALSetRasterUnitType(@
|
361
|
+
cpl_err = FFI::GDAL.GDALSetRasterUnitType(@raster_band_pointer, new_unit_type)
|
362
|
+
|
363
|
+
cpl_err.to_bool
|
305
364
|
else
|
306
365
|
warn "GDALSetRasterUnitType is not defined. Can't call RasterBand#unit_type="
|
307
366
|
end
|
@@ -309,11 +368,21 @@ module GDAL
|
|
309
368
|
|
310
369
|
# @return [GDAL::RasterAttributeTable]
|
311
370
|
def default_raster_attribute_table
|
312
|
-
|
371
|
+
return @default_raster_attribute_table if @default_raster_attribute_table
|
372
|
+
|
373
|
+
rat_pointer = FFI::GDAL.GDALGetDefaultRAT(@raster_band_pointer)
|
313
374
|
return nil if rat_pointer.null?
|
314
375
|
|
315
|
-
GDAL::RasterAttributeTable.new(
|
316
|
-
|
376
|
+
@default_raster_attribute_table = GDAL::RasterAttributeTable.new(rat_pointer)
|
377
|
+
end
|
378
|
+
|
379
|
+
# @return [GDAL::RasterAttributeTable]
|
380
|
+
def default_raster_attribute_table=(rat_table)
|
381
|
+
rat_table_ptr = GDAL._pointer(GDAL::RasterAttributeTable, rat_table)
|
382
|
+
cpl_err = FFI::GDAL.GDALSetDefaultRAT(@raster_band_pointer, rat_table_ptr)
|
383
|
+
@default_raster_attribute_table = GDAL::RasterAttributeTable.new(rat_table_pointer)
|
384
|
+
|
385
|
+
cpl_err.to_bool
|
317
386
|
end
|
318
387
|
|
319
388
|
# Gets the default raster histogram. Results are returned as a Hash so some
|
@@ -364,7 +433,7 @@ module GDAL
|
|
364
433
|
histogram_pointer = FFI::MemoryPointer.new(:pointer)
|
365
434
|
progress_proc = block || nil
|
366
435
|
|
367
|
-
cpl_err = GDALGetDefaultHistogram(@
|
436
|
+
cpl_err = FFI::GDAL.GDALGetDefaultHistogram(@raster_band_pointer,
|
368
437
|
min_pointer,
|
369
438
|
max_pointer,
|
370
439
|
buckets_pointer,
|
@@ -374,6 +443,7 @@ module GDAL
|
|
374
443
|
nil
|
375
444
|
)
|
376
445
|
|
446
|
+
cpl_err.to_bool
|
377
447
|
min = min_pointer.read_double
|
378
448
|
max = max_pointer.read_double
|
379
449
|
buckets = buckets_pointer.read_int
|
@@ -384,7 +454,7 @@ module GDAL
|
|
384
454
|
histogram_pointer.get_pointer(0).read_array_of_int(buckets)
|
385
455
|
end
|
386
456
|
|
387
|
-
|
457
|
+
formatted_buckets(cpl_err, min, max, buckets, totals)
|
388
458
|
end
|
389
459
|
|
390
460
|
# Computes a histogram using the given inputs. If you just want the default
|
@@ -395,7 +465,7 @@ module GDAL
|
|
395
465
|
# @param buckets [Fixnum]
|
396
466
|
# @param include_out_of_range [Boolean]
|
397
467
|
# @param approx_ok [Boolean]
|
398
|
-
# @param block [Proc] No required, but can be used to output
|
468
|
+
# @param block [Proc] No required, but can be used to output progress info
|
399
469
|
# during processing.
|
400
470
|
#
|
401
471
|
# @yieldparam completion [Float] The ration completed as a decimal.
|
@@ -410,7 +480,7 @@ module GDAL
|
|
410
480
|
histogram_pointer = FFI::MemoryPointer.new(:pointer, buckets)
|
411
481
|
progress_proc = block || nil
|
412
482
|
|
413
|
-
cpl_err = GDALGetRasterHistogram(@
|
483
|
+
cpl_err = FFI::GDAL.GDALGetRasterHistogram(@raster_band_pointer,
|
414
484
|
min.to_f,
|
415
485
|
max.to_f,
|
416
486
|
buckets,
|
@@ -420,26 +490,57 @@ module GDAL
|
|
420
490
|
progress_proc,
|
421
491
|
'doing things')
|
422
492
|
|
493
|
+
cpl_err.to_bool
|
494
|
+
|
423
495
|
totals = if buckets.zero?
|
424
496
|
[]
|
425
497
|
else
|
426
498
|
histogram_pointer.read_array_of_int(buckets)
|
427
499
|
end
|
428
500
|
|
429
|
-
|
501
|
+
formatted_buckets(cpl_err, min, max, buckets, totals)
|
502
|
+
end
|
503
|
+
|
504
|
+
# Copies the contents of one raster to another similarly configure band.
|
505
|
+
# The two bands must have the same width and height but do not have to be
|
506
|
+
# the same data type.
|
507
|
+
#
|
508
|
+
# Options:
|
509
|
+
# * :compressed
|
510
|
+
# * 'YES': forces alignment on the destination_band to acheive the best
|
511
|
+
# compression.
|
512
|
+
#
|
513
|
+
# @param destination_band [GDAL::RasterBand]
|
514
|
+
# @param options [Hash]
|
515
|
+
# @option options compress [String] Only 'YES' is supported.
|
516
|
+
# @return [Boolean]
|
517
|
+
def copy_whole_raster(destination_band, **options, &progress)
|
518
|
+
destination_pointer = GDAL._pointer(GDAL::RasterBand, destination_band)
|
519
|
+
options_ptr = GDAL::Options.pointer(options)
|
520
|
+
cpl_err = FFI::GDAL.GDALRasterBandCopyWholeRaster(@raster_band_pointer,
|
521
|
+
destination_pointer,
|
522
|
+
options_ptr,
|
523
|
+
progress,
|
524
|
+
nil)
|
525
|
+
|
526
|
+
cpl_err.to_bool
|
430
527
|
end
|
431
528
|
|
432
|
-
#
|
433
|
-
#
|
434
|
-
|
529
|
+
# Reads the raster line-by-line and returns as an NArray. Will yield each
|
530
|
+
# line and the line number if a block is given.
|
531
|
+
#
|
532
|
+
# @yieldparam pixel_line [Array]
|
533
|
+
# @yieldparam line_number [Fixnum]
|
534
|
+
# @return [NArray]
|
535
|
+
def readlines(data_type: :GDT_Byte)
|
435
536
|
x_offset = 0
|
436
537
|
line_size = 1
|
437
538
|
pixel_space = 0
|
438
539
|
line_space = 0
|
439
|
-
scan_line =
|
540
|
+
scan_line = GDAL._pointer_from_data_type(data_type, x_size)
|
440
541
|
|
441
|
-
0.upto(y_size - 1) do |y|
|
442
|
-
GDALRasterIO(@
|
542
|
+
the_array = 0.upto(y_size - 1).map do |y|
|
543
|
+
FFI::GDAL.GDALRasterIO(@raster_band_pointer,
|
443
544
|
:GF_Read,
|
444
545
|
x_offset,
|
445
546
|
y,
|
@@ -453,8 +554,18 @@ module GDAL
|
|
453
554
|
line_space
|
454
555
|
)
|
455
556
|
|
456
|
-
|
557
|
+
line_array = if data_type == :GDT_Byte
|
558
|
+
scan_line.read_array_of_uint8(x_size)
|
559
|
+
else
|
560
|
+
scan_line.read_array_of_float(x_size)
|
561
|
+
end
|
562
|
+
|
563
|
+
yield(line_array, y) if block_given?
|
564
|
+
|
565
|
+
line_array
|
457
566
|
end
|
567
|
+
|
568
|
+
NArray.to_na(the_array)
|
458
569
|
end
|
459
570
|
|
460
571
|
# @param pixel_array [NArray] The NArray of pixels.
|
@@ -474,13 +585,15 @@ module GDAL
|
|
474
585
|
|
475
586
|
columns_to_write = x_size - x_offset
|
476
587
|
lines_to_write = y_size - y_offset
|
477
|
-
scan_line =
|
588
|
+
scan_line = GDAL._pointer_from_data_type(data_type, columns_to_write)
|
478
589
|
|
479
590
|
(y_offset).upto(lines_to_write - 1) do |y|
|
480
591
|
pixels = pixel_array[true, y]
|
481
|
-
|
592
|
+
ffi_type = GDAL._gdal_data_type_to_ffi(data_type)
|
593
|
+
meth = "write_array_of_#{ffi_type}".to_sym
|
594
|
+
scan_line.send(meth, pixels.to_a)
|
482
595
|
|
483
|
-
GDALRasterIO(@
|
596
|
+
FFI::GDAL.GDALRasterIO(@raster_band_pointer,
|
484
597
|
:GF_Write,
|
485
598
|
x_offset, # nXOff
|
486
599
|
y,
|
@@ -495,7 +608,7 @@ module GDAL
|
|
495
608
|
)
|
496
609
|
end
|
497
610
|
|
498
|
-
|
611
|
+
flush_cache
|
499
612
|
end
|
500
613
|
|
501
614
|
# Read a block of image data, more efficiently than #read. Doesn't
|
@@ -507,25 +620,19 @@ module GDAL
|
|
507
620
|
# top-most block, 1 the next block, etc.
|
508
621
|
def read_block(x_offset, y_offset, image_buffer=nil)
|
509
622
|
image_buffer ||= FFI::MemoryPointer.new(:void)
|
510
|
-
|
511
|
-
#puts "y offset: #{y_offset}"
|
623
|
+
result = FFI::GDAL.GDALReadBlock(@raster_band_pointer, x_offset, y_offset, image_buffer)
|
512
624
|
|
513
|
-
result
|
514
|
-
|
515
|
-
if result == :none
|
516
|
-
elsif result == :failure
|
517
|
-
|
518
|
-
end
|
625
|
+
result.to_bool
|
519
626
|
end
|
520
627
|
|
521
628
|
# The minimum and maximum values for this band.
|
522
629
|
#
|
523
630
|
# @return [Array{min => Float, max => Float}]
|
524
|
-
def
|
631
|
+
def min_max
|
525
632
|
@min_max = if minimum_value[:value] && maximum_value[:value]
|
526
633
|
min_max = FFI::MemoryPointer.new(:double, 2)
|
527
634
|
min_max.put_array_of_double 0, [minimum_value[:value], maximum_value[:value]]
|
528
|
-
GDALComputeRasterMinMax(@
|
635
|
+
FFI::GDAL.GDALComputeRasterMinMax(@raster_band_pointer, 1, min_max)
|
529
636
|
|
530
637
|
[min_max[0].read_double, min_max[1].read_double]
|
531
638
|
else
|
@@ -536,7 +643,7 @@ module GDAL
|
|
536
643
|
# @return [Hash{value => Float, it_tight => Boolean}]
|
537
644
|
def minimum_value
|
538
645
|
is_tight = FFI::MemoryPointer.new(:bool)
|
539
|
-
value = GDALGetRasterMinimum(@
|
646
|
+
value = FFI::GDAL.GDALGetRasterMinimum(@raster_band_pointer, is_tight)
|
540
647
|
|
541
648
|
{ value: value, is_tight: is_tight.read_bytes(1).to_bool }
|
542
649
|
end
|
@@ -544,22 +651,43 @@ module GDAL
|
|
544
651
|
# @return [Hash{value => Float, it_tight => Boolean}]
|
545
652
|
def maximum_value
|
546
653
|
is_tight = FFI::MemoryPointer.new(:double)
|
547
|
-
value = GDALGetRasterMaximum(@
|
654
|
+
value = FFI::GDAL.GDALGetRasterMaximum(@raster_band_pointer, is_tight)
|
548
655
|
|
549
656
|
{ value: value, is_tight: is_tight.read_bytes(1).to_bool }
|
550
657
|
end
|
551
658
|
|
552
|
-
#
|
659
|
+
# Creates vector polygons for all connected regions of pixels in the raster
|
660
|
+
# that share a common pixel value.
|
553
661
|
#
|
554
|
-
# @
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
662
|
+
# @param layer [OGR::Layer, FFI::Pointer] The layer to write the polygons
|
663
|
+
# to.
|
664
|
+
# @param mask_band [GDAL::RasterBand, FFI::Pointer] Optional band, where all
|
665
|
+
# pixels in the mask with a value other than zero will be considered
|
666
|
+
# suitable for collection as polygons.
|
667
|
+
# @param pixel_value_field [Fixnum] Index of the feature attribute into
|
668
|
+
# which the pixel value of the polygon should be written.
|
669
|
+
# @param options [Hash]
|
670
|
+
# @param progress [Proc]
|
671
|
+
# @return [OGR::Layer]
|
672
|
+
def polygonize(layer, mask_band: nil, pixel_value_field: -1, **options, &progress)
|
673
|
+
mask_band_ptr = GDAL._pointer(GDAL::RasterBand, mask_band, false)
|
674
|
+
|
675
|
+
layer_ptr = GDAL._pointer(OGR::Layer, layer)
|
676
|
+
raise "Invalid layer: #{layer.inspect}" if layer_ptr.null?
|
677
|
+
|
678
|
+
options_ptr = GDAL::Options.pointer(options)
|
679
|
+
|
680
|
+
cpl_err = FFI::GDAL.GDALFPolygonize(@raster_band_pointer, # hSrcBand
|
681
|
+
mask_band_ptr, # hMaskBand
|
682
|
+
layer_ptr, # hOutLayer
|
683
|
+
pixel_value_field, # iPixValField
|
684
|
+
options_ptr, # papszOptions
|
685
|
+
progress, # pfnProgress
|
686
|
+
nil # pProgressArg
|
687
|
+
)
|
688
|
+
cpl_err.to_ruby
|
561
689
|
|
562
|
-
|
690
|
+
OGR::Layer.new(layer_ptr)
|
563
691
|
end
|
564
692
|
|
565
693
|
#---------------------------------------------------------------------------
|
@@ -568,7 +696,7 @@ module GDAL
|
|
568
696
|
|
569
697
|
private
|
570
698
|
|
571
|
-
def
|
699
|
+
def formatted_buckets(cpl_err, min, max, buckets, totals)
|
572
700
|
case cpl_err.to_ruby
|
573
701
|
when :none
|
574
702
|
{
|
@@ -579,8 +707,8 @@ module GDAL
|
|
579
707
|
}
|
580
708
|
when :warning then return nil
|
581
709
|
when :failure then raise CPLError
|
710
|
+
else raise CPLError
|
582
711
|
end
|
583
712
|
end
|
584
|
-
|
585
713
|
end
|
586
714
|
end
|