GDAL RasterizeLayer Tüm Çokgenleri Raster'e Yakmıyor mu?


12

GDAL RasterizeLayer kullanarak bir raster için bir şekil dosyası yakmaya çalışıyorum. Belirli bir piksel boyutu göz önüne alındığında, farklı bir şekil dosyasından bir ilgi alanı raster oluşturuyorum. Bu AOI daha sonra aşağıdaki tüm rasterleştirmeler için bir temel görevi görür (aynı sayıda sütun ve satır, aynı projeksiyon ve jeotransform).

Ancak, aynı piksel boyutuna ve projeksiyonlara dayalı olarak şekilleri kendi rasterlerine yazdığımda sorun ortaya çıkıyor. Aşağıdaki bağlantı (görüntüyü yüklemek için yeterli destek yok), orijinal şekil dosyasını bronz renkte ve RasterizeLayer'ın veri yazdığı koyu pembe renkte gösterir. Açık pembe, koyu pembe raster verileri için nodata değerleridir. Gri, şekil dosyası yanmasının tamamlandığı AOI'dir.

Şekil dosyası çokgenlerinin boyutları göz önüne alındığında, alt iki köşede yanma değerlerinin yanı sıra gösterilen verilerin altında iki piksel görmeyi beklerim. Ancak açıkçası, durum böyle değil.

Problem- Finished Raster Burns için resim

Bunları oluşturmak için kullandığım kod aşağıdaki gibidir. Tüm şekiller QGIS kullanılarak oluşturuldu ve hepsi aynı projeksiyonda oluşturuldu. (Gösterilen resimdeki ızgaralamanın sadece kullandığım piksel boyutu hakkında bir fikir vermek olduğuna dikkat edilmelidir.)

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])

Bu GDAL'de bir hata mı, yoksa RasterizeLayer verileri yalnızca belirli bir piksel alanında çokgen varlığından veya yokluğundan başka bir şeye dayanıyor mu?

Kullandığım dosyaları burada bulabilirsiniz .


'Activity_3.shp' ve 'AOI_Raster.tif' bağlantısı sağlayabilir misiniz? Sonunda yeniden yaratıp yaratamayacağımı görmek istiyorum.
Zengin

Yanıtlar:


10

Bu hafta GDALRasterizeLayers ile oynuyorum ve ne yaptığına dair oldukça iyi bir fikrim var. Varsayılan olarak, piksel merkezi çokgenin içindeyse bir piksel rasterleştirilir. Merkezde hiçbir şey yoksa, piksel sınırları içinde bir çokgenin parçaları olsa bile rasterleştirilmez. Rasterleştirmenin istediğiniz şekilde çalışmasına izin vermek için "ALL_TOUCHED" seçeneğini deneyin:

gdal.RasterizeLayer(raster_dataset, [1], shape_layer, None, None, [1], ['ALL_TOUCHED=TRUE'])

EVET! Görünüşe göre ['ALL_TOUCHED=TRUE']maalesef, sadece çokgen katmanları düzeltildi. Nokta şekil dosyası katmanlarım hala süper sakat ve yerleştirildikleri yerden bir piksel gösteriyor.
Lark

Bu gibi bakıyor biter bu . Diğerleriyle aynı projeksiyonda ve bunun da bir şekilde sihirli bir şekilde düzelteceğini umuyordum, ancak aslında bulunduğu yerden bir pikseli inatla yakıyor gibi görünüyor.
Lark

Bu kesinlikle hataya yakışır, yanma noktası dx / 2 ve dy / 2 ile dengelenir. Bu hatanın hala en son bagajda devam edip etmediğini merak ediyorum.
Mike T

O değil! 1.9.0 sürümünde çalışır. Çok teşekkürler!
Lark

1
Burada da oldukça iyi bir tarif var: gis.stackexchange.com/a/16916/9942
j08lue
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.