GDAL RasterizeLayer не записывает все полигоны в растр?

12

Я пытаюсь записать шейп-файл в растр, используя RasterizeLayer из GDAL. Я предварительно создаю растр области интереса из другого шейп-файла, учитывая определенный размер пикселя. Этот AOI затем служит базой для всех последующих растеризаций (одинаковое количество столбцов и строк, одинаковая проекция и геотрансформация).

Проблема возникает, однако, когда я иду, чтобы записать формы в их собственный растр, основываясь на том же размере пикселей и проекций. Ссылка ниже (не хватает представителя, чтобы опубликовать изображение), показывает оригинальный шейп-файл в tan и темно-розовый, где RasterizeLayer записал данные. Светло-розовый - это значения узлов для темно-розовых растровых данных. Серый цвет - это AOI, на основе которого был завершен процесс записи шейп-файла.

Учитывая размеры полигонов шейп-файлов, я ожидаю увидеть значения записи в двух нижних углах, а также в двух пикселях под данными, которые отображаются. Очевидно, однако, это не тот случай.

Изображение для Problem- Finished Raster Burns

Ниже приведен код, который я использовал для их создания. Все фигуры были созданы с использованием QGIS, и все они были созданы в одной проекции. (Следует отметить, что сетка на показанном рисунке была просто для того, чтобы дать представление о размере пикселя, который я использовал.)

from osgeo import ogr
from osgeo import gdal

aoi_uri = 'AOI_Raster.tif'
aoi_raster = gdal.Open(aoi_uri)

def new_raster_from_base(base, outputURI, format, nodata, datatype):

    cols = base.RasterXSize
    rows = base.RasterYSize
    projection = base.GetProjection()
    geotransform = base.GetGeoTransform()
    bands = base.RasterCount

    driver = gdal.GetDriverByName(format)

    new_raster = driver.Create(str(outputURI), cols, rows, bands, datatype)
    new_raster.SetProjection(projection)
    new_raster.SetGeoTransform(geotransform)

    for i in range(bands):
        new_raster.GetRasterBand(i + 1).SetNoDataValue(nodata)
        new_raster.GetRasterBand(i + 1).Fill(nodata)

    return new_raster

shape_uri = 'activity_3.shp'
shape_datasource = ogr.Open(shape_uri)
shape_layer = shape_datasource.GetLayer()

raster_out = 'new_raster.tif'

raster_dataset = new_raster_from_base(aoi_raster, raster_out, 'GTiff',
                                -1, gdal.GDT_Int32)
band = raster_dataset.GetRasterBand(1)
nodata = band.GetNoDataValue()

band.Fill(nodata)

gdal.RasterizeLayer(raster_dataset, [1], shape_layer, burn_values=[1])

Это ошибка в GDAL или RasterizeLayer записывает данные на основе чего-то другого, кроме наличия или отсутствия многоугольника в пределах определенной области пикселей?

Файлы, которые я использовал, можно найти здесь .

жаворонок
источник
Можете ли вы предоставить ссылку на «activity_3.shp» и «AOI_Raster.tif»? Я хочу посмотреть, смогу ли я воссоздать свой конец.
Богатая

Ответы:

10

Я играл с GDALRasterizeLayers на этой неделе и довольно хорошо представляю, что он делает. По умолчанию он растеризует пиксель, если центр пикселя находится внутри многоугольника. Если в центре ничего нет, оно не будет растеризовано, даже если в пределах пикселя есть части многоугольника. Чтобы растеризация работала так, как вы хотите, попробуйте опцию «ALL_TOUCHED»:

gdal.RasterizeLayer(raster_dataset, [1], shape_layer, None, None, [1], ['ALL_TOUCHED=TRUE'])
Майк Т
источник
ДА! По-видимому ['ALL_TOUCHED=TRUE'], хотя, к сожалению, это только фиксированные полигональные слои. Слои моего точечного шейп-файла все еще супер-шаткие, и отображаются на один пиксель от того места, где они размещены.
Lark
Он заканчивает тем, как это . Он находится в той же проекции, что и другие, и я надеялся, что это тоже каким-то волшебным образом исправит это, но кажется, что он упрямо сжигает один пиксель от того, где он на самом деле находится.
Lark
Это, безусловно, выглядит достойно ошибок, когда точка записи смещена на dx / 2 и dy / 2. Интересно, если эта ошибка все еще сохраняется с последним стволом.
Майк Т
Это не! Работает в 1.9.0. Спасибо!
Lark
1
Здесь также есть неплохой рецепт: gis.stackexchange.com/a/16916/9942
j08lue