ฉันมีไฟล์รูปร่างที่มีรูปหลายเหลี่ยม และฉันมีไฟล์แรสเตอร์ระดับโลก ฉันต้องการซ้อนรูปหลายเหลี่ยมของ shapefile ลงบนตารางแรสเตอร์และคำนวณค่าเฉลี่ย raster สำหรับรูปหลายเหลี่ยมแต่ละรูป
ฉันจะทำสิ่งนี้โดยใช้ GDAL เขียนผลลัพธ์ไปยังรูปร่างไฟล์ได้อย่างไร
ฉันมีไฟล์รูปร่างที่มีรูปหลายเหลี่ยม และฉันมีไฟล์แรสเตอร์ระดับโลก ฉันต้องการซ้อนรูปหลายเหลี่ยมของ shapefile ลงบนตารางแรสเตอร์และคำนวณค่าเฉลี่ย raster สำหรับรูปหลายเหลี่ยมแต่ละรูป
ฉันจะทำสิ่งนี้โดยใช้ GDAL เขียนผลลัพธ์ไปยังรูปร่างไฟล์ได้อย่างไร
คำตอบ:
ใน R คุณสามารถทำได้
library(raster)
library(rgdal)
r <- raster('raster_filename')
p <- readOGR('shp_path', 'shp_file')
e <- extract(r, p, fun=mean)e เป็นเวกเตอร์ที่มีค่าเฉลี่ยของค่าเซลล์แรสเตอร์สำหรับแต่ละรูปหลายเหลี่ยม
โหลด shapefile และแรสเตอร์ของคุณใน PostGIS 2.0 และทำ:
SELECT (ST_SummaryStats(ST_Clip(rast, geom))).*
FROM rastertable, geomtableฉันไม่คิดว่า GDAL เป็นเครื่องมือที่ดีที่สุดสำหรับสิ่งนี้ แต่คุณสามารถใช้ gdal_rasterize เพื่อ "ล้าง" ค่าทั้งหมดนอกรูปหลายเหลี่ยม
สิ่งที่ต้องการ:
gdal_translate -a_nodata 0 original.tif work.tif
gdal_rasterize -burn 0 -b 1 -i work.tif yourpolygon.shp -l yourpolygon
gdalinfo -stats work.tif
rm work.tifโปรแกรม gdal_rasterize แก้ไขไฟล์ดังนั้นเราจึงทำสำเนาเพื่อทำงาน นอกจากนี้เรายังทำเครื่องหมายเฉพาะบางค่า (ศูนย์ในกรณีนี้) ให้เป็น nodata "-burn 0 -b 1" หมายถึงเบิร์นค่าเป็นศูนย์ลงในแบนด์ 1 ของไฟล์เป้าหมาย (work.tif) "-i" หมายถึงการแปลงกลับเป็นแรสเตอร์ดังนั้นเราจึงเขียนค่านอกรูปหลายเหลี่ยมแทนที่จะเป็นด้านใน คำสั่ง gdalinfo พร้อมกับ -stats รายงานเกี่ยวกับสถิติแบนด์ ฉันเชื่อว่ามันจะไม่รวมค่า nodata (ซึ่งเราทำเครื่องหมายไว้ก่อนหน้านี้ด้วย -a_nodata)
สคริปต์ต่อไปนี้อนุญาตให้คุณทำงานกับ GDAL: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#calculate-zonal-statistics
# Calculates statistics (mean) on values of a raster within the zones of an polygon shapefile
import gdal, ogr, osr, numpy
def zonal_stats(input_value_raster, input_zone_polygon):
    # Open data
    raster = gdal.Open(input_value_raster)
    driver = ogr.GetDriverByName('ESRI Shapefile')
    shp = driver.Open(input_zone_polygon)
    lyr = shp.GetLayer()
    # get raster georeference info
    transform = raster.GetGeoTransform()
    xOrigin = transform[0]
    yOrigin = transform[3]
    pixelWidth = transform[1]
    pixelHeight = transform[5]
    # reproject geometry to same projection as raster
    sourceSR = lyr.GetSpatialRef()
    targetSR = osr.SpatialReference()
    targetSR.ImportFromWkt(raster.GetProjectionRef())
    coordTrans = osr.CoordinateTransformation(sourceSR,targetSR)
    feat = lyr.GetNextFeature()
    geom = feat.GetGeometryRef()
    geom.Transform(coordTrans)
    # Get extent of geometry
    ring = geom.GetGeometryRef(0)
    numpoints = ring.GetPointCount()
    pointsX = []; pointsY = []
    for p in range(numpoints):
            lon, lat, z = ring.GetPoint(p)
            pointsX.append(lon)
            pointsY.append(lat)
    xmin = min(pointsX)
    xmax = max(pointsX)
    ymin = min(pointsY)
    ymax = max(pointsY)
    # Specify offset and rows and columns to read
    xoff = int((xmin - xOrigin)/pixelWidth)
    yoff = int((yOrigin - ymax)/pixelWidth)
    xcount = int((xmax - xmin)/pixelWidth)+1
    ycount = int((ymax - ymin)/pixelWidth)+1
    # create memory target raster
    target_ds = gdal.GetDriverByName('MEM').Create('', xcount, ycount, gdal.GDT_Byte)
    target_ds.SetGeoTransform((
        xmin, pixelWidth, 0,
        ymax, 0, pixelHeight,
    ))
    # create for target raster the same projection as for the value raster
    raster_srs = osr.SpatialReference()
    raster_srs.ImportFromWkt(raster.GetProjectionRef())
    target_ds.SetProjection(raster_srs.ExportToWkt())
    # rasterize zone polygon to raster
    gdal.RasterizeLayer(target_ds, [1], lyr, burn_values=[1])
    # read raster as arrays
    banddataraster = raster.GetRasterBand(1)
    dataraster = banddataraster.ReadAsArray(xoff, yoff, xcount, ycount).astype(numpy.float)
    bandmask = target_ds.GetRasterBand(1)
    datamask = bandmask.ReadAsArray(0, 0, xcount, ycount).astype(numpy.float)
    # mask zone of raster
    zoneraster = numpy.ma.masked_array(dataraster,  numpy.logical_not(datamask))
    # calculate mean of zonal raster
    return numpy.mean(zoneraster)แปลงไฟล์รูปร่างในแรสเตอร์โดย gdal_rasterize และการใช้รหัสในhttp://www.spatial-ecology.net/dokuwiki/doku.php?id=wiki:geo_toolsการคำนวณสถิติเป็นวง ๆ สำหรับแต่ละรูปหลายเหลี่ยม คุณสามารถเรียกใช้http://km.fao.org/OFwiki/index.php/Oft-reclassหากคุณต้องการได้รับ tif ด้วยสถิติ rasters ของคุณ เพลิดเพลินกับรหัส Ciao Giuseppe
ไม่สามารถใช้ GDAL ได้ คุณสามารถใช้เครื่องมือฟรีอื่น ๆ ได้อย่างไรก็ตามเช่น saga gis:
saga_cmd shapes_grid "Grid Values to Shapes" -GRIDS=grid.sgrd -POLYGONS=in.shp -SHAPES=out.shp-NODATA -TYPE=1คุณยังสามารถใช้ rasterstats thas เป็นโมดูล Python ที่ออกแบบมาเพื่อจุดประสงค์นี้:
from rasterstats import zonal_stats
listofzones = zonal_stats("polygons.shp", "elevation.tif",
            stats="mean")จากนั้นคุณสามารถเข้าถึงคุณลักษณะของโซนแรกโดยใช้:
mean_of_zone1 = listofzones[0]['mean']คุณสามารถใช้เครื่องมือคำนวณสถิติจุดใน arc gis และเครื่องมือนี้สามารถดาวน์โหลดได้จากhttp://ianbroad.com/arcgis-toolbox-calculate-point-statistics-polygon-arcpy/