Генерализация векторных данных в GRASS: различия между версиями

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
 
(не показано 11 промежуточных версий 2 участников)
Строка 1: Строка 1:
{{Статья|Черновик}}
{{Статья|Черновик}}


"Рыба" статьи [http://gis-lab.info/share/DR/grassgen/grass-generalization.html отсюда]
== Введение ==


=Генерализация shp-файлов средствами GRASS GIS=
В статье рассматривается генерализация средствами ГИС GRASS.


В статье рассматривается пример генерализации shp-файлов средствами GRASS GIS. Статья написана по мотивам следущего [http://gis-lab.info/forum/viewtopic.php?f=29&t=6368 обсуждения на форуме].
== Предварительная обработка данных ==


Одним из самых распространенных форматов векторных файлов является формат shp. К сожалению, данный формат не является топологическим, и, как следствие, при генерализации данных полигонального типа, хранящихся в этом формате почти неизбежны осложнения. Самой частой проблемой будет возникновение "дырок" между двумя граничащими полигонами или наложение этих полигонов друг на друга. Выходом из ситуации может служить использование топологического формата хранения данных и соответствующих инструментов редактирования, например, GRASS GIS. GRASS GIS - геоинформационная система с открытым исходным кодом, одной из особенностей которой является хранение и обработка векторных данных с учетом топологии.
* Если данные уже в базе данных GRASS, то можно переходить к самой генерализации (см. следующий раздел).
* Если данные нужно импортировать, то можно использовать генерализацию импортируемых полигонов по площади. Для этого у модуля [http://grass.gis-lab.info/grass64/manuals/html64_user/v.in.ogr.html v.in.ogr] есть опция '''min_area''', отвечающая за минимальную площадь импортируемых полигонов. '''Внимание''': площадной порог задаётся в квадратных единицах (текущих единицах области GRASS), с одним исключение: в области с географической системой координат ("широта/долгота") порог выставляется в квадратных метрах ''(А можно на это ссылку? А то не понятно, как считаются квадратные метры в широте/долготе)'' (взято из мануала [http://grass.gis-lab.info/grass64/manuals/html64_user/v.in.ogr.html v.in.ogr], последний обзац в DESCRIPTION).  


== Генерализация полигонов средствами GRASS GIS ==


Предположим, что имеется файл в формате shp, в котором хранятся полигоны. Требуется произвести генерализацию этого файла. Для определенности будем работать с [http://gis-lab.info/data/rusbounds-rosreestr/regions2010_wgs_shp.7z данным] файлом.
Предположим, что имеется файл в формате shp, в котором хранятся полигоны. Требуется произвести генерализацию этого файла. Для определенности будем работать с [http://gis-lab.info/data/rusbounds-rosreestr/regions2010_wgs_shp.7z данным] файлом.
Схема работы будет следующая:
* Импортируем данные в GRASS GIS
* Произведем генерализацию
* Экспортируем результат
===Импорт данных в GRASS GIS===


Поскольку исходный файл содержит данные в системе координат широта/долгота, то предварительно спроецируем его в другую систему координат (например, Меркатора). Эту операцию можно проделать любыми доступными инструментами, в т.ч. и GRASS GIS, но мы воспользуемся [http://gis-lab.info/qa/ogr2ogr-examples.html ogr2ogr
Поскольку исходный файл содержит данные в системе координат широта/долгота, то предварительно спроецируем его в другую систему координат (например, Меркатора). Эту операцию можно проделать любыми доступными инструментами, в т.ч. и GRASS GIS, но мы воспользуемся [http://gis-lab.info/qa/ogr2ogr-examples.html ogr2ogr
Строка 33: Строка 24:
  v.in.ogr -e dsn=/home/dima/Desktop/General/reg/regions2010/regions2010_wgs.shp out=regions min_area=1 snap=100
  v.in.ogr -e dsn=/home/dima/Desktop/General/reg/regions2010/regions2010_wgs.shp out=regions min_area=1 snap=100


В результате в текущую область будет импортирована вектроная карта, которая получит название regions. На рисунке показан фрагмент получившейся карты:
В результате в текущую область будет импортирована векторная карта, которая получит название regions. На рисунке показан фрагмент получившейся карты:


[[Файл:Grass-generalization-01.png|Результат импорта]]
[[Файл:Grass-generalization-01.png|Результат импорта]]


===Генерализация===
== Описание модулей и немного теории ==
 
ГИС GRASS предоставляет неплохие возможности для генерализации векторных данных разных типов (как линий, так и полигонов). В данной статье рассматриваются оба модуля с функциями генерализации - [http://grass.gis-lab.info/grass64/manuals/html64_user/v.clean.html v.clean] и [http://grass.gis-lab.info/grass64/manuals/html64_user/v.generalize.html v.generalize].   
 
=== Модуль v.clean ===
 
Модуль '''v.clean''' предназначен для автоматического поиска и обработки топологических ошибок. Модуль имеет две опции, касающиеся генерализации:
 
* Инструмент '''prune''' отвечает за удаление близко расположенных узлов линий и границ. Если обрабатывается граница полигона, то топология не нарушается за счёт того, что первый и последний сегмент границы никогда не изменяются и, кроме того, полигоны и их центроиды никогда не удаляются. Используется [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%BC%D0%B5%D1%80%D0%B0_%E2%80%94_%D0%94%D1%83%D0%B3%D0%BB%D0%B0%D1%81%D0%B0_%E2%80%94_%D0%9F%D0%B5%D0%BA%D0%B5%D1%80%D0%B0 классический алгоритм Дугласа-Пекера].
* Инструмент '''rmarea''' предназначен для удаления полигонов с заданным площадным порогом.
--> ''надо расписать, как именно оно работает '''*amuriy''' ''
 
=== Модуль v.generalize ===
 
Модуль '''v.generalize''' создан специально для генерализации данных, включая упрощение, сглаживание, сдвиг (смещение), а также генерализацию векторных сетей. Каждый инструмент -- реализация того или иного математического алгоритма.
 
==== Инструменты генерализации ====
--> ''может, лучше "Инструменты упрощения"? '''*amuriy''''' --> ''Как-то ухо режет. По своей сути это инструменты "прореживания", но это какой-то новый термин получается (во всяком случае, я его не встречал)'''*КД'''''
 
* Инструмент '''reduction''' -- самый простой алгоритм из представленных, удаляет точки линии, которые лежат около друг-друга ближе, чем на заданное пороговое расстояние. Таким образом, алгоритм использует один задаваемый пользователем параметр -- максимально допустимое расстояние, при котором точки считаются идентичными.
* Инструмент '''douglas''' реализует классический [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%BC%D0%B5%D1%80%D0%B0_%E2%80%94_%D0%94%D1%83%D0%B3%D0%BB%D0%B0%D1%81%D0%B0_%E2%80%94_%D0%9F%D0%B5%D0%BA%D0%B5%D1%80%D0%B0 алгоритм Дугласа-Пекера]. Инструмент принимает один параметр -- максимальное допустимое отклонение генерализованной линии от изначальной.
* Инструмент '''douglas_reduction''' представляет собой модификацию алгоритма Дугласа-Пекера, в которой задается дополнительный параметр -- желаемое количество точек генерализованной линии, которое требуется достичь (измеряется в процентах по сравнению с количеством точек исходной линии).
* Инструмент '''lang''' также похож на алгоритм Дугласа-Пекера. Основное отличие состоит в том, что lang представляет собой не рекурсивный алгоритм. Поэтому, во избежание рекурсии алгоритм использует дополнительный параметр (look_ahead), задающий число точек, которые требуется просмотреть, начиная от стартовой точки. Далее как и в алгоритме Дугласа-Пекера, строятся секущие линии между первой точкой и последующими, для каждой построенной секущей измеряется максимальное отклонение между ней и исходной линией. Если все отклонения не превышают порогового значения, то производится генерализация -- просмотренные сегменты линии заменяются одним. Таким образом, алгоритм использует два параметра: число просматриваемых точек и максимально допустимое отклонение.
* Инструмент '''reumann''' использует коридор из двух параллельных линий заданной ширины. Для построения коридора берутся две последовательные точки линии и в направлении, заданном отрезком между точками строится коридор. Далее определяется место выхода линии за границы коридора, в результате точки и сегменты исходной линии, которые попали внутрь коридора, замещаются одним сегментом и процесс повторяется со следующей парой непросмотренных точек. Параметр алгоритма -- ширина коридора.


GRASS GIS в своем составе имеет несколько модулей, которые могут быть использованы для генерализации данных. В этой статье рассматривается один из модулей - [http://grass.gis-lab.info/grass64/manuals/html64_user/v.clean.html v.clean], предназначенный автоматического поиска и обработки топологических ошибок. Данный модуль имеет параметр tool, определяющий инструменты обработки. Мы будем использовать две опции этого параметра:
==== Инструменты сглаживания ====
* Инструмент '''boyle''' сглаживает методом скользящего среднего: алгоритм расчитывает среднее между look_ahead последовательных точек линии, начиная с текущей. Таким образом алгоритм использует единственный параметры -- ширину окна look_ahead.
* Инструмент '''sliding_averaging''' сначала расчитывает средние кординаты для look_ahead точек до и look_ahead после текущей точки (т.е. усредняется 2*look_ahead+1 точка), полученные координаты запоминаются. Целевая (сглаженная) точка помещается на отрезке, проведенном между исходной и усредненной точкой, местоположение на котором задается параметром slide (0 -- исходная точка, 1 -- усредненная точка). Соответственно, алгоритм использует два параметра: ширину окна look_ahead и степень сдвига slide.
* Инструмент '''distance_weighting''' аналогичен предыдущему, за исключением того, что усредненная точка расчитывается методом взвешенного среднего. Как и sliding_averaging, алгоритм использует два параметра: ширину окна look_ahead и степень сдвига slide.
* '''Chaiken's Algorithm'''
* '''Hermite Interpolation'''
* '''Snakes'''


* Инструмент prune, которая отвечает за удаление близко расположенных узлов линий и границ. Особенностью этого инструмента является то, что если обрабатывается граница области (полигона), то топология не нарушается. Это достигается за счет того, что первый и последний сегмент границы нигогда не изменяется и, кроме того, области и центроиды никогда не удаляются.
== Практика ==
* Инструмент rmarea, предназначенный для удаления малых по площади областей.
 
=== Генерализация полигонов ===


Выполним следующую команду:
Выполним следующую команду:
Строка 58: Строка 79:
Дело в том, что на данном участке находился анклав, который не был удален инструментом rmarea, т.к. его размеры (свыше 40 000 000 000) превышают заданный порог, но при этом, если произвести генерализацию данного участка, то в результате генерализованная граница должна пересечь этот анклав. Понятно, что вновь появившееся пересечение меняет исходную топологию и поэтому недопустимо. Таким образом этот и подобные участки должны быть обработаны отдельно (вручную или автоматически с использованнием других порогов) в зависимости от того, что именно требуется получить на выходе.
Дело в том, что на данном участке находился анклав, который не был удален инструментом rmarea, т.к. его размеры (свыше 40 000 000 000) превышают заданный порог, но при этом, если произвести генерализацию данного участка, то в результате генерализованная граница должна пересечь этот анклав. Понятно, что вновь появившееся пересечение меняет исходную топологию и поэтому недопустимо. Таким образом этот и подобные участки должны быть обработаны отдельно (вручную или автоматически с использованнием других порогов) в зависимости от того, что именно требуется получить на выходе.


===Экспорт результатов===


После требуемой обработки экспортируем данные обратно в shp:
==== Сглаживание "зубчатых" полигонов ====
"Зубчатые" полигоны часто получаются, например, при векторизации растров. Опытным путём установлено, что самым оптимальным алгоритмом для их сглаживания подобных полигонов с максимальным сохранением формы является '''Chaiken'''.       
 
 
'''Пример''':
 
 
[[Файл:Small_poly_gener.png]]
 
 
Использовалась команда:
 
v.generalize in=vect out=vect_gener method=chaiken threshold=15
 
Размер меньшего из двух полигонов, изображённых на картинке, примерно 30 метров. Как видно из команды выше, сглаживание проводилось с порогом в 15м.
 


v.out.ogr in=regions_bona dsn=/home/dima/Desktop/General/reg/regions2010/result.shp
==== Генерализация полигонов с помощью буферных зон ====


И произведем обратное перепроецирование:
--> ''Пример [http://blog.cleverelephant.ca/2010/11/removing-complexities.html отсюда], надо это повторить в GRASS -- '''*amuriy''''' 


ogr2ogr -f "ESRI ShapeFile" result_wgs.shp result.shp -t_srs epsg:4326
Смысл:
-- делаем широкий буфер вокруг полигона, он скрывает мелкие ненкжные детали, оставляя общие очертания полигона;
-- делаем ещё один буфер "отрицательный" внутрь полигона (той же величиной, что и первый), чтобы уменьшить полигон до исходного.




== Генерализация линий средствами GRASS GIS ==
=== Генерализация линий ===
В данном разделе вопросы импорта и экспорта линейных объектов в систему GRASS GIS не рассматриваются, поскольку технология работы полностью аналогична описанной выше процедуре импорта/экспорта полигонов.


=== Инструменты v.clean для генерализации линейных объектов ===
Модуль v.clean c опцией "prune" можно использовать также и для генерализации линейных объектов.
Модуль v.clean можно использовать также и для генерализации линейных объектов, наиболее востребованными средствами будут следующие:
* Инструмент rmline, который удаляет линии и границы нулевой длины. При этом значение порога, указанное в параметре thresh, игнорируется.
* Инструмент rmsa удаляет небольшие углы между линиями ([http://grass.gis-lab.info/grass64/manuals/html64_user/v_clean_rmsa.png пример работы tool=rmsa в графическом виде]). Как и в случае использования инструмента rmline, пороговое значение игнорируется и удаление угла производится только в случае, если этот угол настолько мал, что он при вычислениях округляется до нуля.
* Инструмент rmdangle. !!!!!!!!!!!!!!! Для чего он нужен я толком не понял --- кто пользовался, распишите!!!!!!!!!!!!!!!

Текущая версия от 09:41, 28 июля 2012

Эта страница является черновиком статьи.


Введение

В статье рассматривается генерализация средствами ГИС GRASS.

Предварительная обработка данных

  • Если данные уже в базе данных GRASS, то можно переходить к самой генерализации (см. следующий раздел).
  • Если данные нужно импортировать, то можно использовать генерализацию импортируемых полигонов по площади. Для этого у модуля v.in.ogr есть опция min_area, отвечающая за минимальную площадь импортируемых полигонов. Внимание: площадной порог задаётся в квадратных единицах (текущих единицах области GRASS), с одним исключение: в области с географической системой координат ("широта/долгота") порог выставляется в квадратных метрах (А можно на это ссылку? А то не понятно, как считаются квадратные метры в широте/долготе) (взято из мануала v.in.ogr, последний обзац в DESCRIPTION).


Предположим, что имеется файл в формате shp, в котором хранятся полигоны. Требуется произвести генерализацию этого файла. Для определенности будем работать с данным файлом.

Поскольку исходный файл содержит данные в системе координат широта/долгота, то предварительно спроецируем его в другую систему координат (например, Меркатора). Эту операцию можно проделать любыми доступными инструментами, в т.ч. и GRASS GIS, но мы воспользуемся [http://gis-lab.info/qa/ogr2ogr-examples.html ogr2ogr


ogr2ogr -f "ESRI ShapeFile" regions2010 regions2010_wgs.shp -t_srs "+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +no_defs +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000 +to_meter=1"

Далее создаем область GRASS на основе полученного файла по одному из способов указанных здесь.

Заходим в созданную область и импортируем данные:

v.in.ogr -e dsn=/home/dima/Desktop/General/reg/regions2010/regions2010_wgs.shp out=regions min_area=1 snap=100

В результате в текущую область будет импортирована векторная карта, которая получит название regions. На рисунке показан фрагмент получившейся карты:

Результат импорта

Описание модулей и немного теории

ГИС GRASS предоставляет неплохие возможности для генерализации векторных данных разных типов (как линий, так и полигонов). В данной статье рассматриваются оба модуля с функциями генерализации - v.clean и v.generalize.

Модуль v.clean

Модуль v.clean предназначен для автоматического поиска и обработки топологических ошибок. Модуль имеет две опции, касающиеся генерализации:

  • Инструмент prune отвечает за удаление близко расположенных узлов линий и границ. Если обрабатывается граница полигона, то топология не нарушается за счёт того, что первый и последний сегмент границы никогда не изменяются и, кроме того, полигоны и их центроиды никогда не удаляются. Используется классический алгоритм Дугласа-Пекера.
  • Инструмент rmarea предназначен для удаления полигонов с заданным площадным порогом.

--> надо расписать, как именно оно работает *amuriy

Модуль v.generalize

Модуль v.generalize создан специально для генерализации данных, включая упрощение, сглаживание, сдвиг (смещение), а также генерализацию векторных сетей. Каждый инструмент -- реализация того или иного математического алгоритма.

Инструменты генерализации

--> может, лучше "Инструменты упрощения"? *amuriy --> Как-то ухо режет. По своей сути это инструменты "прореживания", но это какой-то новый термин получается (во всяком случае, я его не встречал)*КД

  • Инструмент reduction -- самый простой алгоритм из представленных, удаляет точки линии, которые лежат около друг-друга ближе, чем на заданное пороговое расстояние. Таким образом, алгоритм использует один задаваемый пользователем параметр -- максимально допустимое расстояние, при котором точки считаются идентичными.
  • Инструмент douglas реализует классический алгоритм Дугласа-Пекера. Инструмент принимает один параметр -- максимальное допустимое отклонение генерализованной линии от изначальной.
  • Инструмент douglas_reduction представляет собой модификацию алгоритма Дугласа-Пекера, в которой задается дополнительный параметр -- желаемое количество точек генерализованной линии, которое требуется достичь (измеряется в процентах по сравнению с количеством точек исходной линии).
  • Инструмент lang также похож на алгоритм Дугласа-Пекера. Основное отличие состоит в том, что lang представляет собой не рекурсивный алгоритм. Поэтому, во избежание рекурсии алгоритм использует дополнительный параметр (look_ahead), задающий число точек, которые требуется просмотреть, начиная от стартовой точки. Далее как и в алгоритме Дугласа-Пекера, строятся секущие линии между первой точкой и последующими, для каждой построенной секущей измеряется максимальное отклонение между ней и исходной линией. Если все отклонения не превышают порогового значения, то производится генерализация -- просмотренные сегменты линии заменяются одним. Таким образом, алгоритм использует два параметра: число просматриваемых точек и максимально допустимое отклонение.
  • Инструмент reumann использует коридор из двух параллельных линий заданной ширины. Для построения коридора берутся две последовательные точки линии и в направлении, заданном отрезком между точками строится коридор. Далее определяется место выхода линии за границы коридора, в результате точки и сегменты исходной линии, которые попали внутрь коридора, замещаются одним сегментом и процесс повторяется со следующей парой непросмотренных точек. Параметр алгоритма -- ширина коридора.

Инструменты сглаживания

  • Инструмент boyle сглаживает методом скользящего среднего: алгоритм расчитывает среднее между look_ahead последовательных точек линии, начиная с текущей. Таким образом алгоритм использует единственный параметры -- ширину окна look_ahead.
  • Инструмент sliding_averaging сначала расчитывает средние кординаты для look_ahead точек до и look_ahead после текущей точки (т.е. усредняется 2*look_ahead+1 точка), полученные координаты запоминаются. Целевая (сглаженная) точка помещается на отрезке, проведенном между исходной и усредненной точкой, местоположение на котором задается параметром slide (0 -- исходная точка, 1 -- усредненная точка). Соответственно, алгоритм использует два параметра: ширину окна look_ahead и степень сдвига slide.
  • Инструмент distance_weighting аналогичен предыдущему, за исключением того, что усредненная точка расчитывается методом взвешенного среднего. Как и sliding_averaging, алгоритм использует два параметра: ширину окна look_ahead и степень сдвига slide.
  • Chaiken's Algorithm
  • Hermite Interpolation
  • Snakes

Практика

Генерализация полигонов

Выполним следующую команду:

v.clean in=regions out=regions_bona type=boundary tool=prune,rmarea thresh=50000,100000000

В этой команде вызывается модуль v.clean с описанными выше инструментами. В данном случае параметр thresh задает настройки точности для инструмента prune в 50 000 (в единицах проекта), т.е. узлы, находящиеся ближе друг к другу, чем задано, будут удалены. Аналогично, будут удалены все области, чья площадь окажется меньше, чем 100 000 000 единиц. В результате выполнения будет создана карта regions_bona, фрагмент которой показан на рисунке:

Результат генерализации

Обратите внимание на то, что в восточной части показанного фрагмента осталась область, граница которой не была генерализована. Если увеличить масштаб, то получим следующий фрагмент:

Фрагмент с анклавом

Дело в том, что на данном участке находился анклав, который не был удален инструментом rmarea, т.к. его размеры (свыше 40 000 000 000) превышают заданный порог, но при этом, если произвести генерализацию данного участка, то в результате генерализованная граница должна пересечь этот анклав. Понятно, что вновь появившееся пересечение меняет исходную топологию и поэтому недопустимо. Таким образом этот и подобные участки должны быть обработаны отдельно (вручную или автоматически с использованнием других порогов) в зависимости от того, что именно требуется получить на выходе.


Сглаживание "зубчатых" полигонов

"Зубчатые" полигоны часто получаются, например, при векторизации растров. Опытным путём установлено, что самым оптимальным алгоритмом для их сглаживания подобных полигонов с максимальным сохранением формы является Chaiken.


Пример:


Small poly gener.png


Использовалась команда:

v.generalize in=vect out=vect_gener method=chaiken threshold=15

Размер меньшего из двух полигонов, изображённых на картинке, примерно 30 метров. Как видно из команды выше, сглаживание проводилось с порогом в 15м.


Генерализация полигонов с помощью буферных зон

--> Пример отсюда, надо это повторить в GRASS -- *amuriy

Смысл: -- делаем широкий буфер вокруг полигона, он скрывает мелкие ненкжные детали, оставляя общие очертания полигона; -- делаем ещё один буфер "отрицательный" внутрь полигона (той же величиной, что и первый), чтобы уменьшить полигон до исходного.


Генерализация линий

Модуль v.clean c опцией "prune" можно использовать также и для генерализации линейных объектов.