como sobrepor shapefile e raster?


17

Eu tenho um shapefile com polígonos. E eu tenho um arquivo raster global. Quero sobrepor os polígonos do shapefile na grade de varredura e calcular o valor médio da varredura para cada polígono.

Como posso fazer isso usando GDAL, escrevendo os resultados no shapefile?


4
GDAL é a única ferramenta que você gostaria de usar?
Simbamangu 18/03/12

@Simbamangu não, basicamente qualquer coisa é bom, e seria ótimo se fosse em Python
andreash

Respostas:


9

Em R você pode fazer

library(raster)
library(rgdal)
r <- raster('raster_filename')
p <- readOGR('shp_path', 'shp_file')
e <- extract(r, p, fun=mean)

e é um vetor com a média dos valores das células rasterizadas para cada polígono.


Este não é R python, conforme solicitado na pergunta
GM

6

Seguindo os conselhos que recebi da lista de discussão gdal-dev, usei o StarSpan :

starspan --vector V --raster R1 R2 ... --stats mystats.csv avg mode

Os resultados são salvos no formato CSV. Naquele momento, isso já era suficiente para mim, mas deveria ser possível, de alguma forma, forjar um Shapefile a partir dessa informação.


O StarSpan parece ter se mudado para o GitHub. Obtenha aqui .
Richard

4

Carregue seu shapefile e seu raster no PostGIS 2.0 e faça:

SELECT (ST_SummaryStats(ST_Clip(rast, geom))).*
FROM rastertable, geomtable

4

Não acho que o GDAL seja a melhor ferramenta para isso, mas você pode usar gdal_rasterize para "limpar" todos os valores fora do polígono.

Algo como:

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

O programa gdal_rasterize modifica o arquivo, então fazemos uma cópia para trabalhar. Também marcamos algum valor específico (zero neste caso) como nodata. O "-burn 0 -b 1" significa gravar um valor zero na banda 1 do arquivo de destino (work.tif). O "-i" significa rasterização invertida, para que gravemos valores fora do polígono, e não dentro dele. O comando gdalinfo com -stats informa sobre estatísticas da banda. Eu acredito que ele excluirá o valor nodata (que marcamos anteriormente com -a_nodata).


4

O script a seguir permite executar a tarefa com o 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)

2

Transforme o arquivo de forma em varredura por gdal_rasterize e use o código em http://www.spatial-ecology.net/dokuwiki/doku.php?id=wiki:geo_tools para calcular a estatística zonal para cada polígono. Você pode executar http://km.fao.org/OFwiki/index.php/Oft-reclass se desejar obter um tif com sua estatística de rasters. Aproveite o código Ciao Giuseppe


Você tem uma cópia do código a que se refere? Infelizmente, o link para o arquivo Python está morto.
ustroetz

1

Isso não é possível usando o GDAL. Você pode usar outras ferramentas gratuitas, por exemplo, saga gis:

saga_cmd shapes_grid "Grid Values to Shapes" -GRIDS=grid.sgrd -POLYGONS=in.shp -SHAPES=out.shp-NODATA -TYPE=1

Eu segui essa abordagem, embora o nome da função seja realmente "Grid Statistics for Polygons".
Bananafish

1

Você também pode usar o rasterstats, que é um módulo Python projetado para esta finalidade:

from rasterstats import zonal_stats
listofzones = zonal_stats("polygons.shp", "elevation.tif",
            stats="mean")

insira a descrição da imagem aqui

Então você pode acessar o atributo da primeira zona usando:

mean_of_zone1 = listofzones[0]['mean']

-2

você pode usar a ferramenta de cálculo de estatísticas de pontos no arc gis e essa ferramenta pode ser baixada em http://ianbroad.com/arcgis-toolbox-calculate-point-statistics-polygon-arcpy/


2
"A ferramenta Calcular estatística de pontos pega uma classe de recurso de polígono e ponto de entrada e usa um campo selecionado para encontrar o mínimo, o máximo e a média dos pontos e adiciona os resultados ao recurso de polígono." mas essa pergunta é sobre uma classe de recurso Polígono e um Raster, portanto, parece improvável que seja adequado.
PolyGeo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.