şekil dosyası ve raster nasıl kaplanır?


18

Çokgenler içeren bir şekil dosyam var. Ve global bir tarama dosyam var. Şekil dosyasının çokgenlerini raster ızgarasına yerleştirmek ve her çokgen için ortalama raster değerini hesaplamak istiyorum.

Sonuçları şekil dosyasına yazarak GDAL kullanarak bunu nasıl yapabilirim?


4
GDAL kullanmak istediğiniz tek araç mı?
Mart'ta Simbamangu

@Simbamangu hayır, temelde her şey
yolunda

Yanıtlar:


9

R de yapabilirsiniz

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

e, her çokgen için raster hücre değerlerinin ortalaması olan bir vektördür.


Bu soruda sorulduğu gibi R değil python
GM

6

Aşağıdaki tavsiye ben gdal-dev posta listesinde var, kullanılan StarSpan :

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

Sonuçlar CSV formatına kaydedilir. O zaman, bu benim için zaten yeterliydi, ama bir şekilde bu bilgilerden bir Shapefile oluşturmak mümkün olmalı.


StarSpan GitHub'a taşınmış gibi görünüyor. İndirin burada .
Richard

5

Aşağıdaki komut dosyası, GDAL ile görev yapmanıza olanak tanır: 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)

4

Şekil dosyanızı ve rasterinizi PostGIS 2.0'a yükleyin ve şunları yapın:

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

4

Ben GDAL bunun için en iyi araç olduğunu sanmıyorum, ama çokgen dışında tüm değerleri "temizlemek" için gdal_rasterize kullanabilirsiniz.

Gibi bir şey:

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 programı dosyayı değiştirir, böylece üzerinde çalışmak için bir kopya oluştururuz. Ayrıca belirli bir değeri (bu durumda sıfır) nodata olarak işaretleriz. "-Burn 0 -b 1", hedef dosyanın (work.tif) bant 1'ine sıfır değerini yazmak anlamına gelir. "-İ", rasterleştirme işlemini tersine çevirmek anlamına gelir; böylece değerleri , poligonun içinde değil, dışında yakarız. Bant istatistikleriyle ilgili -stats raporları içeren gdalinfo komutu. (Daha önce -a_nodata ile işaretlediğimiz) nodata değerini hariç tutacağına inanıyorum.


2

Rasterdeki şekil dosyasını gdal_rasterize ile dönüştürün ve her çokgen için bölgesel istatistik hesaplamak için http://www.spatial-ecology.net/dokuwiki/doku.php?id=wiki:geo_tools kodunu kullanın . Rasters istatistiği ile bir tif almak istiyorsanız http://km.fao.org/OFwiki/index.php/Oft-reclass çalıştırabilirsiniz . Kodun tadını çıkar Ciao Giuseppe


Başvurduğunuz kodun bir kopyasına sahip misiniz? Maalesef Python dosyasının bağlantısı öldü.
ustroetz

1

GDAL kullanarak bu mümkün değildir. Ancak diğer ücretsiz araçları kullanabilirsiniz, örneğin: saga gis:

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

İşlev adı aslında "Çokgenler için Izgara İstatistikleri" olmasına rağmen bu yaklaşıma gittim.
muzlu balık

1

Ayrıca bu amaç için tasarlanmış bir Python modülü olan rasterstats'ı da kullanabilirsiniz :

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

resim açıklamasını buraya girin

Ardından ilk bölgenin özelliğine aşağıdakileri kullanarak erişebilirsiniz:

mean_of_zone1 = listofzones[0]['mean']

-2

arc gis'te hesaplama noktası istatistikleri aracını kullanabilirsiniz ve bu araç http://ianbroad.com/arcgis-toolbox-calculate-point-statistics-polygon-arcpy/ adresinden indirilebilir.


2
"Nokta İstatistiklerini Hesapla aracı bir giriş Çokgen ve Nokta özellik sınıfı alır ve noktaların minimum, maksimum ve ortalamasını bulmak için seçilen bir alanı kullanır ve sonuçları çokgen özelliğine ekler." ancak bu soru bir Polygon özellik sınıfı ve bir Raster ile ilgilidir, bu yüzden uygun olması muhtemel görünmez.
PolyGeo
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.