GDAL RasterizeLayer ไม่ได้เผารูปหลายเหลี่ยมทั้งหมดเป็น Raster?


12

ฉันพยายามเบิร์นไฟล์ไปยังแรสเตอร์โดยใช้ RasterizeLayer ของ GDAL ฉันสร้างพื้นที่แรสเตอร์ที่น่าสนใจจากรูปร่างที่แตกต่างกันก่อนกำหนดขนาดพิกเซลที่เฉพาะเจาะจง AOI นี้ทำหน้าที่เป็นฐานสำหรับการแรสเตอร์ต่อไปนี้ทั้งหมด (จำนวน collumns และแถวเดียวกัน, การฉายภาพและ geotransform เดียวกัน)

ปัญหาเกิดขึ้น แต่เมื่อฉันไปเผารูปร่างเพื่อแรสเตอร์ของตัวเองตามขนาดพิกเซลและประมาณการเดียวกัน ลิงค์ด้านล่าง (มีตัวแทนไม่เพียงพอที่จะโพสต์ภาพ) แสดงไฟล์รูปร่างดั้งเดิมในผิวสีแทนและสีชมพูเข้มที่ RasterizeLayer เขียนข้อมูล สีชมพูอ่อนเป็นค่า nodata สำหรับข้อมูลแรสเตอร์สีชมพูเข้ม สีเทาคือ AOI ตามการเบิร์นไฟล์รูปร่างเสร็จสมบูรณ์

เมื่อพิจารณาถึงขอบเขตของรูปหลายเหลี่ยม shapefile ฉันคาดว่าจะเห็นค่าการเบิร์นที่มุมด้านล่างทั้งสองรวมทั้งพิกเซลสองพิกเซลที่อยู่ใต้ข้อมูลที่แสดง เห็นได้ชัดว่านี่ไม่ใช่กรณี

รูปภาพสำหรับปัญหา Raster Burns ที่เสร็จสิ้นแล้ว

ดังต่อไปนี้เป็นรหัสที่ฉันใช้ในการสร้างสิ่งเหล่านี้ รูปร่างทั้งหมดถูกสร้างขึ้นโดยใช้ QGIS และถูกสร้างขึ้นทั้งหมดในการฉายภาพเดียวกัน (ควรสังเกตว่าการ gridding ในภาพที่แสดงเป็นเพียงเพื่อให้ความคิดเกี่ยวกับขนาดพิกเซลที่ฉันใช้)

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ในสัปดาห์นี้และมีความคิดที่ดีเกี่ยวกับสิ่งที่กำลังทำอยู่ โดยค่าเริ่มต้นมันจะ rasterise พิกเซลถ้าศูนย์พิกเซลอยู่ภายในรูปหลายเหลี่ยม หากไม่มีสิ่งใดอยู่ตรงกลางมันจะไม่ได้รับการแรสเตอร์แม้ว่าจะมีบางส่วนของรูปหลายเหลี่ยมภายในขีด จำกัด พิกเซล หากต้องการอนุญาตให้ rasterising ทำงานตามที่คุณต้องการให้ลองใช้ตัวเลือก "ALL_TOUCHED":

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

ใช่! เห็นได้ชัด['ALL_TOUCHED=TRUE']ว่าโชคไม่ดีที่แก้ไขเลเยอร์รูปหลายเหลี่ยม เลเยอร์ไฟล์รูปร่างจุดของฉันยังคงมีความหรูหราและแสดงพิกเซลหนึ่งจุดจากตำแหน่งที่วาง
สนุกสนาน

มันจบลงด้วยการมองเช่นนี้ มันอยู่ในการฉายภาพเดียวกับที่คนอื่น ๆ และฉันก็หวังว่ามันจะแก้ไขได้อย่างน่าอัศจรรย์ แต่ก็ดูเหมือนว่าจะเผาไหม้หนึ่งพิกเซลอย่างดื้อรั้นจากที่ที่มันอยู่
สนุกสนาน

นั่นคือข้อผิดพลาดที่คุ้มค่าที่จุดเบิร์นถูกชดเชยด้วย dx / 2 และ dy / 2 ฉันสงสัยว่าข้อผิดพลาดนั้นยังคงอยู่กับลำตัวล่าสุดหรือไม่
Mike T

มันไม่ใช่! มันทำงานได้ใน 1.9.0 ขอบคุณมาก!
สนุกสนาน

1
นอกจากนี้ยังมีสูตรที่ค่อนข้างดีที่นี่: gis.stackexchange.com/a/16916/9942
j08lue
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.