>>> from env_helper import info; info()
页面更新时间: 2023-06-23 10:04:25
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-9-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

3.6. 读取和写入栅格文件的“窗口”

从Rasterio 0.3开始,您可以读取和写入栅格文件的“窗口”。此功能允许您处理比计算机RAM大的栅格或并行处理大块的栅格。

Windows 窗口是栅格数据集矩形子集上的视图,在栅格中按列和行的偏移量、宽度和高度(以像素为单位)进行描述。这些可以是int或float。 窗口也可以由numpy数组索引元组或切片对象构造。在这些情况下,只允许使用int值。 如果将height和width关键字参数传递给 from_slices 可以使用相对切片和开放切片。

3.6.1. 读取

下面是读取Rasterio测试文件的256行x 512列子集的示例。

>>> from rasterio.windows import Window
>>> import rasterio
>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>     w = src.read(1, window=Window(0, 0, 512, 256))
/usr/lib/python3/dist-packages/rasterio/__init__.py:304: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
  dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
>>> print(w.shape)
(256, 500)

窗口转换

可以使用数据集的 window_transform 方法:

>>> import rasterio
>>> from rasterio.windows import Window
>>> win = Window(256, 256, 128, 128)
>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>      src_transform = src.transform;win_transform = src.window_transform(win)
>>>
>>> print(src_transform)
| 1.00, 0.00, 0.00|
| 0.00, 1.00, 0.00|
| 0.00, 0.00, 1.00|
>>> print(win_transform)
| 1.00, 0.00, 256.00|
| 0.00, 1.00, 256.00|
| 0.00, 0.00, 1.00|

窗口实用程序

基本的联合和交叉操作可用于Windows,以简化在动态创建的窗口中对一系列带区或数据集的操作,使其具有相同的完整范围。

>>> from rasterio import windows
>>> # Full window is ((0, 1000), (0, 500))
>>> window1 = Window(10, 100, 490, 400)
>>> window2 = Window(50, 10, 200, 140)
>>> windows.union(window1, window2)
Window(col_off=10, row_off=10, width=490, height=490)
>>> windows.intersection(window1, window2)
Window(col_off=50, row_off=100, width=200, height=50)

阻碍

栅格数据集通常由多个数据块组成,当窗口与数据集自身的块结构匹配时,窗口读写效率最高。打开文件进行读取时,任何带区的块形状都可以从Block_Shapes属性中获得。

>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>      for i, shape in enumerate(src.block_shapes, 1):
>>>             print((i, shape))
(1, (16, 500))
>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>      for ji, window in src.block_windows(1):
>>>             print((ji, window))
((0, 0), Window(col_off=0, row_off=0, width=500, height=16))
((1, 0), Window(col_off=0, row_off=16, width=500, height=16))
((2, 0), Window(col_off=0, row_off=32, width=500, height=16))
((3, 0), Window(col_off=0, row_off=48, width=500, height=16))
((4, 0), Window(col_off=0, row_off=64, width=500, height=16))
((5, 0), Window(col_off=0, row_off=80, width=500, height=16))
((6, 0), Window(col_off=0, row_off=96, width=500, height=16))
((7, 0), Window(col_off=0, row_off=112, width=500, height=16))
((8, 0), Window(col_off=0, row_off=128, width=500, height=16))
((9, 0), Window(col_off=0, row_off=144, width=500, height=16))
((10, 0), Window(col_off=0, row_off=160, width=500, height=16))
((11, 0), Window(col_off=0, row_off=176, width=500, height=16))
((12, 0), Window(col_off=0, row_off=192, width=500, height=16))
((13, 0), Window(col_off=0, row_off=208, width=500, height=16))
((14, 0), Window(col_off=0, row_off=224, width=500, height=16))
((15, 0), Window(col_off=0, row_off=240, width=500, height=16))
((16, 0), Window(col_off=0, row_off=256, width=500, height=16))
((17, 0), Window(col_off=0, row_off=272, width=500, height=16))
((18, 0), Window(col_off=0, row_off=288, width=500, height=12))

块窗口本身可以从块窗口功能中获得。 此函数返回一个迭代器,该迭代器生成一对值。第二个是一个窗口元组,可用于调用 read 或 write . 第一个是数据集所有块中该块的行索引和列索引对。

您可以像这样从一个文件块读取数据窗口。

>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>      for ji, window in src.block_windows(1):
>>>             r = src.read(1, window=window)
>>>             print(r.shape)
>>>             break
>>>
(16, 500)

培育良好的文件具有相同的阻塞带,但gdal允许使用其他方法,最好在代码中测试这种假设。

>>> with rasterio.open('/gdata/rasterio/RGB.byte.tiff') as src:
>>>     assert len(set(src.block_shapes)) == 1
>>>     for ji, window in src.block_windows(1):
>>>             b, g, r = (src.read(k, window=window) for k in (1, 1, 1))
>>>             print((ji, r.shape, g.shape, b.shape))
>>>             break
((0, 0), (16, 500), (16, 500), (16, 500))

Block_Shapes属性是块形状和 set(src.block_shapes) 为您提供一组独特的形状。断言集合中只有一个项实际上与断言所有带区都具有相同的块结构相同。如果有,您可以对每个窗口使用相同的窗口。

3.6.2. 读取数据集

数据集对象提供对栅格数据文件的读、写和写访问,并通过调用 rasterio.open() . 这个函数模仿了python的内置 open() 它返回的数据集对象是模仿python file 物体。

>>> import rasterio
>>> src = rasterio.open('/gdata/rasterio/444.tiff')
>>> src
<open DatasetReader name='/gdata/rasterio/444.tiff' mode='r'>
>>> src.name
'/gdata/rasterio/444.tiff'
>>> src.mode
'r'
>>> src.closed
False

数据集通常有一个或多个带(或层)。按照gdal约定,这些索引从数字1开始。文件的第一个波段可以这样读取:

>>> array = src.read(1)
>>> array.shape
(300, 500)

返回的对象是二维numpy ndarray。该数组在python提示下的表示是一个摘要;用于测试的rasterio geotiff文件在角中有0个值,但在其他地方有非零的值。

>>> from matplotlib import pyplot
>>> pyplot.imshow(array, cmap='pink')
>>>
>>> pyplot.show()
_images/sec07_window_27_0.png

输入数据集的所有带区都可以读取为三维数据数组,而不是读取单个带区。注意,3个轴的解释是 (bands, rows, columns) . 见 图像处理软件 有关如何转换为某些软件预期的顺序的详细信息。

>>> array = src.read()
>>> array.shape
(3, 300, 500)

要读取数据集较小的块,请参阅 开窗读写 .

数据集所有带区的索引、numpy数据类型和nodata值都可以从 indexes , dtypes 和 nodatavals 属性。

>>> for i, dtype, nodataval in zip(src.indexes, src.dtypes, src.nodatavals):
>>>      print(i, dtype, nodataval)
1 uint8 None
2 uint8 None
3 uint8 None

3.6.3. 阅读标签

标记属于命名空间。要从默认命名空间获取数据集标记的副本,请调用 tags() 没有参数。

>>> import rasterio
>>> src = rasterio.open("/gdata/rasterio/RGB.byte.tiff")
>>> src.tags()
/usr/lib/python3/dist-packages/rasterio/__init__.py:304: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
  dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
{}

数据集的带区也可能有标记。以下是第一个带区的默认命名空间中的标记,使用的位置带区索引参数访问 tags() .

>>> src.tags(ns='IMAGE_STRUCTURE')
{'INTERLEAVE': 'BAND'}