Module: GDAL::RasterBand::IOExtensions

Included in:
GDAL::RasterBand
Defined in:
lib/gdal/extensions/raster_band/io_extensions.rb

Overview

Methods for reading & writing RasterBands that didn’t come from GDAL.

Instance Method Summary collapse

Instance Method Details

#block_buffer_sizeInteger

The buffer size to use for block-based IO, based on #block_size.

Returns:



97
98
99
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 97

def block_buffer_size
  block_size[:x] * block_size[:y]
end

#block_countHash{x => Integer, x_remainder => Integer, y => Integer, y_remainder => Integer}

Determines not only x and y block counts (how many blocks there are in the raster band when using GDAL’s suggested block size), but remainder x and y counts for when the total number of pixels and lines does not divide evenly using GDAL’s block count.

Returns:

See Also:



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 82

def block_count
  x_size_plus_block_size = x_size + block_size[:x]
  y_size_plus_block_size = y_size + block_size[:y]

  {
    x: ((x_size_plus_block_size - 1) / block_size[:x]).to_i,
    x_remainder: x_size_plus_block_size.modulo(block_size[:x]),
    y: ((y_size_plus_block_size - 1) / block_size[:y]).to_i,
    y_remainder: y_size_plus_block_size.modulo(block_size[:y])
  }
end

#pixel_value(x, y) ⇒ Number

Convenience method for directly getting a single pixel value.

Parameters:

  • x (Integer)

    Pixel number in the row to get.

  • y (Integer)

    Row number of the pixel to get.

Returns:

  • (Number)


68
69
70
71
72
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 68

def pixel_value(x, y)
  output = raster_io("r", x_size: 1, y_size: 1, x_offset: x, y_offset: y, buffer_x_size: 1, buffer_y_size: 1)

  GDAL._read_pointer(output, data_type)
end

#read_blocks_by_block {|pixels, x_block_size, y_block_size| ... } ⇒ Enumerator?

Reads through the raster block-by-block and yields all pixel values for the block.

Yield Parameters:

  • pixels (Array<Number>)

    An Array the same size as #block_buffer_size containing all pixel values in the current block.

  • x_block_size (Integer)

    Instead of using only #GDAL::RasterBand#block_size, it will tell you the size of each block–handy for when the last block is smaller than the rest.

  • y_block_size (Integer)

    Same as x_block_siz but for y.

Returns:

  • (Enumerator, nil)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 130

def read_blocks_by_block
  return enum_for(:read_blocks_by_block) unless block_given?

  data_pointer = FFI::MemoryPointer.new(:buffer_in, block_buffer_size)

  block_count[:y].times do |y_block_number|
    block_count[:x].times do |x_block_number|
      y_block_size = calculate_y_block_size(y_block_number)
      x_block_size = calculate_x_block_size(x_block_number)

      read_block(x_block_number, y_block_number, data_pointer)
      pixels = GDAL._read_pointer(data_pointer, data_type, block_buffer_size)

      yield(Array(pixels), x_block_size, y_block_size)
    end
  end
end

#read_lines_by_block {|row| ... } ⇒ Enumerator?

Reads through the raster, block-by-block then line-by-line and yields the pixel data that it gathered.

Yield Parameters:

  • row (Array<Number>)

    The Array of pixels for the current line.

Returns:

  • (Enumerator, nil)

    Returns an Enumerable if no block is given, allowing to chain with other Enumerable methods. Returns nil if a block is given.



109
110
111
112
113
114
115
116
117
118
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 109

def read_lines_by_block
  return enum_for(:read_lines_by_block) unless block_given?

  read_blocks_by_block do |pixels, x_block_size, y_block_size|
    pixels.each_slice(x_block_size).with_index do |row, block_row_number|
      yield row
      break if block_row_number == y_block_size - 1
    end
  end
end

#readlines {|pixel_line| ... } ⇒ Object

Reads the raster line-by-line and returns as an NArray. Will yield each line and the line number if a block is given.

Yield Parameters:

  • pixel_line (Array)


13
14
15
16
17
18
19
20
21
22
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 13

def readlines
  return enum_for(:readlines) unless block_given?

  y_size.times do |row_number|
    scan_line = raster_io("r", x_size: x_size, y_size: 1, y_offset: row_number)
    line_array = GDAL._read_pointer(scan_line, data_type, x_size)

    yield line_array
  end
end

#set_pixel_value(x, y, new_value) ⇒ Object

Convenience method for directly setting a single pixel value.

Parameters:

  • x (Integer)

    Pixel number in the row to set.

  • y (Integer)

    Row number of the pixel to set.

  • new_value (Number)

    The value to set the pixel to.



56
57
58
59
60
61
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 56

def set_pixel_value(x, y, new_value)
  data_pointer = GDAL._pointer_from_data_type(data_type)
  GDAL._write_pointer(data_pointer, data_type, new_value)

  raster_io("w", data_pointer, x_size: 1, y_size: 1, x_offset: x, y_offset: y, buffer_x_size: 1, buffer_y_size: 1)
end

#write_xy_narray(pixel_array) ⇒ Object

Writes a 2-dimensional NArray of (x, y) pixels to the raster band using GDAL::RasterBand#raster_io. It determines x_size and y_size for the GDAL::RasterBand#raster_io call using the dimensions of the array.

Parameters:

  • pixel_array (NArray)

    The 2d list of pixels.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/gdal/extensions/raster_band/io_extensions.rb', line 29

def write_xy_narray(pixel_array)
  data_pointer = FFI::MemoryPointer.new(:buffer_out, block_buffer_size)
  read_start = 0

  block_count[:y].times do |y_block_number|
    block_count[:x].times do |x_block_number|
      y_block_size = calculate_y_block_size(y_block_number)
      x_block_size = calculate_x_block_size(x_block_number)

      pixel_count_per_block = x_block_size * y_block_size
      read_range = (read_start...(read_start + pixel_count_per_block))
      pixels = pixel_array[read_range]
      GDAL._write_pointer(data_pointer, data_type, pixels.to_a)

      write_block(x_block_number, y_block_number, data_pointer)

      data_pointer.clear
      read_start = read_range.end
    end
  end
end