Saya menggunakan metode ReadalArray GDAL untuk bekerja dengan data raster menggunakan numpy (khusus klasifikasi ulang). Karena raster saya besar, saya memproses array dalam blok, iterasi setiap blok dan pemrosesan dengan metode yang mirip dengan contoh GeoExamples .
Saya sekarang mencari cara terbaik untuk mengatur ukuran blok ini untuk mengoptimalkan waktu yang dibutuhkan untuk memproses seluruh raster. Menyadari keterbatasan dengan ukuran array numpy, dan penggunaan GDAL GetBlockSize untuk menggunakan ukuran blok "natural" dari sebuah raster, saya telah menguji menggunakan beberapa ukuran blok yang berbeda, terdiri dari beberapa ukuran "natural", dengan contoh kode di bawah ini:
import timeit
try:
import gdal
except:
from osgeo import gdal
# Function to read the raster as arrays for the chosen block size.
def read_raster(x_block_size, y_block_size):
raster = "path to large raster"
ds = gdal.Open(raster)
band = ds.GetRasterBand(1)
xsize = band.XSize
ysize = band.YSize
blocks = 0
for y in xrange(0, ysize, y_block_size):
if y + y_block_size < ysize:
rows = y_block_size
else:
rows = ysize - y
for x in xrange(0, xsize, x_block_size):
if x + x_block_size < xsize:
cols = x_block_size
else:
cols = xsize - x
array = band.ReadAsArray(x, y, cols, rows)
del array
blocks += 1
band = None
ds = None
print "{0} blocks size {1} x {2}:".format(blocks, x_block_size, y_block_size)
# Function to run the test and print the time taken to complete.
def timer(x_block_size, y_block_size):
t = timeit.Timer("read_raster({0}, {1})".format(x_block_size, y_block_size),
setup="from __main__ import read_raster")
print "\t{:.2f}s\n".format(t.timeit(1))
raster = "path to large raster"
ds = gdal.Open(raster)
band = ds.GetRasterBand(1)
# Get "natural" block size, and total raster XY size.
block_sizes = band.GetBlockSize()
x_block_size = block_sizes[0]
y_block_size = block_sizes[1]
xsize = band.XSize
ysize = band.YSize
band = None
ds = None
# Tests with different block sizes.
timer(x_block_size, y_block_size)
timer(x_block_size*10, y_block_size*10)
timer(x_block_size*100, y_block_size*100)
timer(x_block_size*10, y_block_size)
timer(x_block_size*100, y_block_size)
timer(x_block_size, y_block_size*10)
timer(x_block_size, y_block_size*100)
timer(xsize, y_block_size)
timer(x_block_size, ysize)
timer(xsize, 1)
timer(1, ysize)
Yang menghasilkan semacam output berikut:
474452 blocks size 256 x 16:
9.12s
4930 blocks size 2560 x 160:
5.32s
58 blocks size 25600 x 1600:
5.72s
49181 blocks size 2560 x 16:
4.22s
5786 blocks size 25600 x 16:
5.67s
47560 blocks size 256 x 160:
4.21s
4756 blocks size 256 x 1600:
5.62s
2893 blocks size 41740 x 16:
5.85s
164 blocks size 256 x 46280:
5.97s
46280 blocks size 41740 x 1:
5.00s
41740 blocks size 1 x 46280:
800.24s
Saya telah mencoba menjalankan ini untuk beberapa raster yang berbeda, dengan ukuran dan tipe piksel yang berbeda, dan tampaknya mendapatkan tren yang sama, di mana peningkatan sepuluh kali lipat dalam dimensi x atau y (dalam beberapa kasus, keduanya) membagi dua waktu pemrosesan, yang walaupun tidak begitu penting dalam contoh di atas, bisa berarti beberapa menit untuk raster terbesar saya.
Jadi pertanyaan saya adalah, mengapa perilaku ini terjadi?
Saya memang berharap menggunakan blok lebih sedikit untuk meningkatkan waktu pemrosesan, tetapi tes menggunakan paling tidak bukan yang tercepat. Juga, mengapa ujian akhir memakan waktu lebih lama dari yang sebelumnya? Apakah ada semacam preferensi dengan raster untuk dibaca oleh baris atau kolom, atau dalam bentuk blok yang dibaca, ukuran total? Apa yang saya harapkan dari ini adalah informasi untuk mendapatkan algoritma dasar bersama yang akan dapat mengatur ukuran blok raster ke nilai optimal, tergantung pada ukuran input.
Perhatikan bahwa input saya adalah raster kisi ESRI ArcINFO, yang memiliki ukuran blok "alami" 256 x 16, dan ukuran total raster saya dalam contoh ini adalah 41740 x 46280.