GRASS: пример расчёта "зональной статистики" по векторам

Решенные задачи, первая запись - описание решения.
Ответить
Александр Мурый
Гуру
Сообщения: 5073
Зарегистрирован: 26 сен 2009, 16:26
Статьи: 3
Проекты: 5/1
Репутация: 727
Ваше звание: званий не имею
Откуда: Москва

GRASS: пример расчёта "зональной статистики" по векторам

Сообщение Александр Мурый » 26 ноя 2012, 16:54

Дано: пусть имеется векторная карта с линиями "profiles" и сетка квадратов заданного размера.

Задача: найти суммы длин линий по квадратам, занести значения сумм в атрибутивную таблицу для каждого квадрата.

Необходимое условие: атрибутивные таблицы векторов должны иметь подключение НЕ к DBF (например, к SQLite). Как "переподключить" атрибут.таблицы, описано здесь.

Решение:
  • пусть имеется векторная карта с линиями "profiles" (1 на картинке), задаём по ней текущий регион

    Код: Выделить всё

    g.region vect=profiles
  • создаём в текущем регионе векторную сетку с ячейкой 1x1 км (2 на картинке)

    Код: Выделить всё

    v.mkgrid map=grid_1km grid=10,10 position=region
  • разрезаем линии сеткой на отдельные участки (3 на картинке, каждая линия имеет случайный цвет)

    Код: Выделить всё

    v.overlay ainput=profiles atype=line binput=grid_1km operator=and out=profiles_parts
  • добавляем в атрибут.таблицу для "резаных" линий поле "length" и вносим в поле "length" длину каждой линии

    Код: Выделить всё

    v.db.addcol map=profiles_parts col="length double"
    v.to.db map=profiles_parts option=length col=length

    Получается примерно такая таблица:

    Код: Выделить всё

    cat  a_cat  b_cat  b_row  b_col  b_rown  b_coln  length
    1    1      1      10     1      J       A       428.63861
    2    3      4      10     4      J       D       245.687834
    3    6      28     8      8      H       H       607.625541
    4    7      71     3      1      C       A       461.793565
    5    9      95     1      5      A       E       929.552621
    6    10     25     8      5      H       E       379.969092
    7    11     73     3      3      C       C       628.197767
    8    12     29     8      9      H       I       479.090412
    9    2      2      10     2      J       B       294.183353
    
  • добавляем в атрибут.таблицу сетки поле "length_sum" и с помощью SQL и группировки по номеру ячейки (GROUP BY) считаем общую длину всех линий в каждой ячейке

    Код: Выделить всё

    v.db.addcol grid_1km col="length_sum double"

    Тут, скорее всего, можно на чистом SQL, но я сделал в виде shell-скрипта

    Код: Выделить всё


    #!/bin/sh
    echo "SELECT b_cat,SUM(length) FROM profiles_parts GROUP BY b_cat" | db.select -c | while read line; do
    CAT=$(echo "$line" | cut -d"|" -f1)
    SUM=$(echo "$line" | cut -d"|" -f2)

    echo "UPDATE grid_1km SET length_sum = $SUM WHERE cat = $CAT" | db.execute
    done

    В итоге атрибут. таблица нашей сетки имеет вид:

    Код: Выделить всё

    cat  row  col  rown  coln  length_sum 
    1    10   1    J     A     428.63861   
    2    10   2    J     B     294.183353  
    3    10   3    J     C
    4    10   4    J     D     245.687834  
    5    10   5    J     E
    6    10   6    J     F
    7    10   7    J     G
    8    10   8    J     H
    9    10   9    J     I
  • Суммы длин линий по квадратам — номер 4 на картинке.
Изображение
Редактор материалов, модератор форума

Ответить

Вернуться в «Рецепты»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость