растерио: комбинируйте нисходящий и восходящий примеры

#python #raster #gdal #rasterio

Вопрос:

Мне нужно сначала выполнить понижающую выборку набора растровых данных с использованием average метода повторной выборки, а затем увеличить результат с помощью bilinear метода повторной выборки.

В идеале я бы хотел, чтобы это произошло за один раз — без записи каких-либо данных на диск.

Мое лучшее решение на данный момент-выполнить среднюю повторную выборку при первоначальном чтении, записать результат в a MemoryFile , а затем выполнить вторую повторную выборку при чтении из MemoryFile , прежде чем окончательно записать результат на диск.

Мне интересно, есть ли лучший способ сделать это?

Вот несколько воспроизводимых кодов:

 import numpy as np
import rasterio as rio
from rasterio.io import MemoryFile
from rasterio.enums import Resampling

src_profile = {
    "driver": "GTiff",
    "dtype": "uint8",
    "height": 1440,
    "width": 2880,
    "count":1,
    "nodata":255,
}

with rio.open('sample.tif', "w", **src_profile) as dataset:
    
    shape = (src_profile["height"], src_profile["width"])
    # random data
    arr = np.arange(np.prod(shape), dtype="uint8").reshape(shape)
    dataset.write(arr, 1)


with rio.open('sample.tif', "r") as dataset:
    
    rescale_factor = 0.25
    
    # avg resample on initial read
    data = dataset.read(
        out_shape=(
            dataset.count,
            int(dataset.height * rescale_factor),
            int(dataset.width * rescale_factor)
        ),
        resampling=Resampling.average
    )

    tmp_profile = src_profile.copy()
    tmp_profile.update({
        "width": data.shape[-1],
        "height": data.shape[-2],
    })
    
    rescale_factor = 10
    
# write to memfile
with MemoryFile() as memfile:
    with memfile.open(**tmp_profile) as tempds:
        tempds.write(data)

        # read back with resample
        data = tempds.read(
            out_shape=(
                dataset.count,
                int(tmp_profile["height"] * rescale_factor),
                int(tmp_profile["width"] * rescale_factor)
            ),
            resampling=Resampling.bilinear
        )

dst_profile = tmp_profile.copy()
dst_profile.update({
    "width": data.shape[-1],
    "height": data.shape[-2],
})

# write to disk
with rio.open('target.tif', "w", **dst_profile) as dataset:
    dataset.write(data)