як накласти форм-файл і растр?


18

У мене формуляр з багатокутниками. І у мене є глобальний растровий файл. Я хочу перекласти багатокутники формифільму на растрову сітку та обчислити середнє значення растру для кожного багатокутника.

Як я можу це зробити за допомогою GDAL, записуючи результати у файл форми?


4
Є GDAL єдиним інструментом, який ви хочете використовувати?
Сімбамангу

@Simbamangu ні, в основному все добре, і було б чудово, якби це було в Python
andreash

Відповіді:


9

У R ви можете зробити

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

e - вектор із середнім значенням растрових клітин у кожному багатокутнику.


Це R не python, як про це йдеться у запитанні
GM

6

Дотримуючись поради, яку я потрапив у список розсилки gdal-dev, я використав StarSpan :

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

Результати зберігаються у форматі CSV. На той момент цього мені вже було достатньо, але слід якось сформувати Shapefile із цієї інформації.


Здається, StarSpan перейшов на GitHub. Отримайте його тут .
Річард

5

Наступний сценарій дозволяє виконувати завдання з 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)

4

Завантажте своє форма форми та растр у PostGIS 2.0 та виконайте такі дії:

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

4

Я не думаю, що 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 модифікує файл, тому ми робимо копію для роботи. Ми також відзначаємо певне значення (нуль у даному випадку) як нодату. "-Burn 0 -b 1" означає записувати значення нуля в смугу 1 цільового файлу (work.tif). "-I" означає інвертну растерізацію, тому ми записуємо значення поза полігоном, а не всередині нього. Команда gdalinfo із -stats звітує про статистику діапазону. Я вважаю, що це виключить значення nodata (яке ми позначали раніше з -a_nodata).


2

Перетворіть файл форми в растр за допомогою gdal_rasterize та використовуйте код у http://www.spatial-ecology.net/dokuwiki/doku.php?id=wiki:geo_tools для обчислення зональної статистики для кожного багатокутника. Ви можете запустити http://km.fao.org/OFwiki/index.php/Oft-reclass, якщо ви хочете отримати тиф зі статистикою растру. Насолоджуйтесь кодом Ciao Giuseppe


Чи трапляється у вас копія коду, на який ви посилаєтесь? На жаль, посилання на файл Python мертве.
ustroetz

1

Це неможливо за допомогою GDAL. Однак ви можете використовувати інші безкоштовні інструменти, наприклад, saga gis:

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

Я пішов з таким підходом, хоча назва функції насправді "Grid Statistics for Polygons".
бананафіш

1

Ви також можете використовувати rasterstats thas - це модуль Python, призначений для цієї мети:

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

введіть тут опис зображення

Потім ви можете отримати доступ до атрибуту першої зони за допомогою:

mean_of_zone1 = listofzones[0]['mean']

-2

Ви можете використовувати інструмент обчислення точкової статистики в дугових системах, і цей інструмент можна завантажити з http://ianbroad.com/arcgis-toolbox-calculate-point-statistics-polygon-arcpy/


2
"Інструмент" Обчислити статистику точок "приймає вхідний клас функцій" Полігон та точка "і використовує вибране поле для пошуку мінімальних, максимальних та середніх точок та додає результати до функції багатокутника." але це питання стосується класу характеристик Polygon та Raster, тому він, мабуть, не підходить.
PolyGeo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.