Получите растровые значения из наложения полигонов в ГИС-решениях Opensource

16

У меня есть два слоя. Слой в форме многоугольника со множеством плиток и растровый слой, содержащий земной покров CORINE 2006 со многими категориями в карте цветов. Я хочу получить для каждого многоугольника в слое формы сумму каждой категории растительного покрова растрового слоя.

Например, есть полигон с идентификатором '2', и я хочу использовать атрибуты, подобные этому, для этого полигона (в процентах или квадратных метрах):

  • Пахотная земля: 15%
  • Лес: 11%
  • Улицы: 2% (... и так одна)

Я пытался сделать это в траве, qgis (без функции), саге (просто суммирует все до общего значения) r (общая сумма), но я все еще не нашел решения. Большинство плагинов (зональная статистика в qgis) поддерживают только растровые слои 0-1. v.rast.stats тоже не помог. Я открыт для любого хорошего и умного решения! Может быть, я даже использовал неправильный подход или сделал ошибки.

В Arcgis эта задача довольно проста, если я правильно помню, но мне все еще не хватает хорошего решения для вашего обычного пользователя Linux.

Я использую систему Debian Linux, и поэтому я могу использовать только программы для этой ОС.


РЕДАКТИРОВАТЬ: Потому что этот вопрос по-прежнему имеет так много просмотров и посетителей: я написал плагин QGIS, который также способен рассчитать площадь растрового слоя. Я еще не закодировал наложение полигонов, но оно определенно запланировано. Найдите плагин здесь и сначала установите библиотеку Scipy.

кроншнеп
источник
Это определенно можно сделать в R, это просто вопрос определения, какие функции. Вам нужно наложить каждый полигон на растр, а затем использовать table (), чтобы получить сводную информацию о пикселях «cookie-cut». Пакеты raster, rgdal и rgeos могут быть полезны. Прочитайте «R Spatial Task View» (Google найдет его)
Spacedman
конечно, но как я могу получить такое резюме. Вы можете легко наложить слой многоугольника на растровый слой с помощью! Is.na (overlay (Poly, Raster)), но с помощью таких команд, как extract, я могу рассчитать только общую площадь в пикселе среза печенья, а не разные категории цветовой карты. , Я не знал rgeos, но я посмотрел через API и не нашел функции, чтобы сделать это.
Curlew
Проверьте р.унивар в GRASS, как видите Grasswiki.osgeo.org/wiki/Zonal_statistics
markusN
Здравствуй! Спасибо за создание плагина QGIS! Я просто хотел упомянуть, что плагин падает (> 13000 полигонов). Было бы здорово, если бы он разбил задачу, чтобы не вылетать. И было бы замечательно иметь возможность добавлять все классы одновременно (например, чтобы таблица атрибутов получила 2 новых поля LandcoverID и Landcover%, где оба содержат CSV-список со значениями) :)
Mfbaer
@Joran: Если вы считаете, что это ошибка, поднимите отчет об ошибке, а не пишите об этом в комментарии ( github.com/Martin-Jung/LecoS/issues ). Кроме того 1) это не работа плагинов для сериализации или пакетной обработки ваших задач. Запустите его на меньших подмножествах. 2) Конечно. Было бы много замечательных вещей, чтобы добавить. Код с открытым исходным кодом, не стесняйтесь кодировать его :)
Curlew

Ответы:

13

Используйте «extract» для наложения объектов многоугольника из SpatialPolygonsDataFrame (который можно прочитать из шейп-файла с помощью maptools: readShapeSpatial) на растре, а затем используйте «table» для суммирования. Пример:

> c=raster("cumbria.tif") # this is my CORINE land use raster
> summary(spd)
Object of class SpatialPolygonsDataFrame
[...]
> nrow(spd)  # how many polygons:
[1] 2
> ovR = extract(c,spd)
> str(ovR)
List of 2
 $ : num [1:542] 26 26 26 26 26 26 26 26 26 26 ...
 $ : num [1:958] 18 18 18 18 18 18 18 18 18 18 ...

Итак, мой первый полигон покрывает 542 пикселя, а мой второй - 958. Я могу суммировать каждый из них:

> lapply(ovR,table)
[[1]]

 26  27 
287 255 

[[2]]

  2  11  18 
 67  99 792 

Таким образом, мой первый многоугольник состоит из 287 пикселей класса 26 и 255 пикселей класса 27. Достаточно легко сложить, разделить и умножить на 100, чтобы получить проценты.

Spacedman
источник
Отлично, большое спасибо за усилия. Я попробую это и доложу :-)
Curlew
6

Я хотел доложить, и вот я здесь. Решение Spacedman работало отлично, и я смог экспортировать всю информацию для каждого многоугольника в моей форме. Просто на тот случай, если у кого-то возникнет такая же проблема, вот как я это сделал:

...
tab <- apply(ovR,table)
# Calculate percentage of landcover types for each polygon-field.
# landcover is a datastream with the names of every polygon
for(i in 1:length(tab)){
 s <- sum(tab[[i]])
 mat <- as.matrix(tab[[i]])
 landcover[i,paste("X",row.names(mat),sep="")] <- as.numeric(tab[[i]]/s)
}
кроншнеп
источник
3

если я правильно понимаю, что вы хотите, и при условии, что у вас есть векторный слой «mypolygonlayer» и растровый слой «corina» уже в вашей базе данных GRASS GIS:

Сначала я бы преобразовал вектор в растр. Кошка будет гарантировать, что у вас будет один уникальный идентификатор на полигон. Если у вас есть столбец с уникальным числовым идентификатором, вы можете использовать этот столбец. Метка колонки является необязательной:

v.to.rast input = слой mypolygonlayer = 1 output = mypolygons use = cat labelcolumn = NameMappingUnit

Затем запустите r.stats, чтобы получить статистику:

r.stats -a -l input = mypolygons, разделитель корины =; выход = / дом / Паулу / corinastats.csv

Последний шаг - открыть файл corinastats.csv, например, в LibreOffice и создать сводную таблицу или использовать R для создания кросс-таблицы.

Ecodiv
источник
3

Я знаю, что этот пост довольно старый, но недавно я хотел провести такой же анализ, но загрузка таких программ, как R, немного затрудняет работу моего компьютера и требует одобрения. После многих часов исследования метода, который я мог использовать только с QGis и Excel, я обнаружил, что этот метод работает лучше всего для меня, и хотел предложить его людям в такой же ситуации.

  1. Прикрепить полигон к растровому слою (Растр → извлечение → клипер: входной файл = растровый слой, выберите выходное имя и местоположение, нажмите на слой маски, выберите полигон → хорошо)

  2. Полигонизировать слой обрезки (Растр → Конверсия → Полигонизация: входной файл = ваш слой клипа, сохранить вывод → ОК)

  3. Вычисление количества пикселей (Нажмите на файл формы, который вы только что создали → калькулятор открытого поля: поставьте галочку «создать новое поле» и добавьте имя поля, Function = geometry → area → ok). Теперь у вас должен быть новый столбец в вашей таблице атрибутов, показывающий количество пикселей.

  4. Сохранить слой полигонизации (щелкните правой кнопкой мыши слой полигонизации, сохраните как: format = DBF file, сохраните как → ok)

  5. Суммирующее количество пикселей для каждой среды обитания (запустите Excel, откройте файл, если у вас нет заголовков, добавьте по одному для каждого столбца, щелкните пустую ячейку, перейдите на вкладку DATA, объедините, убедитесь, что это сумма, нажмите на Красная стрелка рядом с «Обзор ...» и выберите два столбца (включая заголовки), нажмите «Добавить» и отметьте оба поля «Верхний ряд» и «Левый столбец» → ОК)

  6. Если, как и я, у вас есть много полигонов для анализа и вам необходимо сравнить их в одной таблице, этот шаг будет полезным. В новой книге Excel перечислите номера ваших мест обитания в столбце A (для меня от 1 до 48) и поместите два столбца, которые вы только что объединили, в столбцы B и C (среда обитания в B и количество пикселей в C). В ячейку D1 напишите следующую формулу: = IFNA (INDEX (C: C; MATCH (A2; B: B; 0)); "") и перетащите (или дважды щелкните в правом нижнем углу) вниз до последнего значения (так что если у вас есть 48 мест обитания до клетки D48). Количество пикселей теперь находится в соответствующих ячейках вашей среды обитания, и вы можете повторить этот процесс для всех ваших полигонов.

Эмили
источник
2

Как насчет преобразования данных CORINE в набор векторных полигонов с помощью QGIS ( Растр> Конверсия> Полигонизация ), а затем с помощью функции объединения ( Вектор> Инструменты геообработки> Объединение ) для объединения с полигонами. Результирующий векторный набор данных будет содержать области каждого класса CORINE в каждом многоугольнике.

Энди Харфут
источник
спасибо за это предложение. Еще не думал о векторном союзе. Возможно я попробую это, если R-обработка как-то терпит неудачу.
Curlew
0

QGIS.

В транке QGIS есть еще одна версия ZonalStats, которая называется Zonal Statistics.

Это выполняет функцию, которую вы требуете.

Что касается рабочего процесса, мне не ясно, сколько у вас растров или это просто полосы в растре?

Уилли
источник
спасибо за комментарий, но зональная статистика ест только растр без категорий. Я использую магистраль QGIS 1.9
Curlew
0

В противоположность большинству ответов, приведенных выше, я бы сказал, что лучшим вариантом является растеризация полигонов, а не работа с двумя наборами растровых данных вместо двух наборов данных полигонов. Это намного менее интенсивно обрабатывает и, следовательно, является единственным простым в реализации решением для обработки больших растров и больших файлов полигонов в R.

После растеризации ваших полигонов в точно такой же степени и разрешении растровых данных вы можете составить сводную статистику, как описано здесь , в виде таблицы , которая подходит, если ваш растр помещается в память (растровые слои малого / среднего размера) или вы можете преобразовать каждую категорию в двоичную форму с помощью reclassфункции и чем рассчитать zonalстатистику для каждого класса. Вот решение, которое объединяет растеризацию и зональную статистику в одну функцию и прекрасно работает с очень большими наборами данных.

joaoal
источник