Обильные фильтруации

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

Буду фильтровать. Начну с фрагмента снимка SRTM:

Ну а хули елозить-то? Фильтровать — так фильтровать. К великой моей печали, вы в просьбах своих нихуя не говорите о предпочтительных способах фильтрации. Что-ж, поэкспериментируем, дабы никто не ушел обиженным.

Начнем с DTM-фильтра, в основе которого лежит статья Георга Фоссельмана. Технология фильтрации основана на предположении о том, что резкий перепад значений высоты на незначительном пространстве DEM-растра свидетельствует не об особенностях рельефа, а о наличии объектов местности, искажающих ЦМР. Проще говоря, если на левом пикселе высота десять метров, а на правом тридцать, то скорее всего на местности в данных точках вы вместо обрыва/карьера увидите стену леса, здание или другую нерельефную ебанину. Фильтр просматривает растр скользящим окном заданного радиуса и отделяет области с уклоном выше указанного. При соответствующих настройках, этот фильтр позволяет не только отделить неестественные превышения, но и разделить растр на слои равнин и уклонов.

На демке с территорией города Шахты, алгоритм фильтрации сбоит на терриконах и отвалах. Впрочем, на таких масштабах уместнее использовать вместо SRTM растры ASTER GDEM. На моем фрагменте все работает прекрасно. Вот вам равнины:

А вот уклоны свыше тридцати градусов:

Главное, помните фильтр только отделяет одни пиксели от других. Дать физическое объяснение результата — уже ваша задача. Вот какого хрена на острове Поперечном такие уклоны? Он же ровный как блин. У меня даже фоточка есть:

Чаще всего подобные искажения возникают за счет растительности. Отделить ее от рельефа практически невозможно. Но если на плакорах с этим можно почти смириться (нужно только забыть про разницу в возрастах, бонитетах, наличие дорог, лугов, болот и полей, ветровалы, бобров, пожары, рубки и усыхания), то получить детальную ЦМР для склонов долин обычно затруднительно. Да чего объяснять-то? Каждый из вас наверняка видел такую взаимосвязь растительности и рельефа:

Но хватит, уже про DTM. Вы можете подумать, что у меня нет чувства такта. Фильтр комочков (Filter clumps — да простят меня профессиональные переводчики) отсеивает связанные пикселы с единым значением, превышающие заданную площадь. Например, вот области в которых соприкасается не менее тридцати пикселов с единым значением высоты:

Мажоритарный фильтр (majority filter) делит растр на сегменты указанного размера. В каждом из них вычисляется значение большинства пикселов, которое впоследствии экстраполируется на всю область. В результате имеем следующее:

Исходный SRTM в приближении:

Результат работы мажоритарного фильтра в том же экстенте:

  • Для понимания, на рисунке ниже черные изолинии с SRTM наложены на красные изолинии с отфильтрованного растра. Результат налицо:

Морфологический фильтр, точнее фильтры. Спешу огорчить всех натуралистов. Умойтесь, к геоморфологии эти фильтры не имеют никакого отношения, даже несмотря на их специфические наименования. Базовых морфологических фильтров два: дилатация и эрозия. Кроме того, активно используются фильтры замыкания и размыкания. В первом применяется сначала дилатация, затем эрозия, во втором — наоборот. Нихрена не понятно? Не проблема. Вот вам иллюстрированная классификация. Основана на лучших моих художественных скиллах вкупе с простейшим графическим редактором:

При дилатации  происходит расширение пикселей, в результате которого изображение становится более светлым и размытым:

Красные линии — горизонтали с растра дилатации, черные — горизонтали SRTM:

При эрозии происходит обратный процесс. Однородные области увеличиваются в размере за счет подавления шума между ними.

Красные изолинии с растра эрозии на фоне черных горизонталей SRTM

Это размыкание

с горизонталями

А это замыкание

с горизонталями

Все, хватит про морфологические фильтры. Это банально и скучно. Самое время испить из фрактальной реки и вспомнить про богов алеатики. Дамы и господа! Леди и джентельмены! Мудачье! Специально для вас, Карл Гаусс со своим фильтром!

— ээээээ, а где растр то?

А не будет растра. Ибо визуально после применения фильтра различия почти не отличить. Суть фильтра в отсеивании областей с заданным стандартным отклонением. Что-бы вы не расстраивались вот вам картинка с изолиниями (standart deviation = 1):

Фильтр Ли. Это к китайцам не имеет никакого отношения, просто я в душе не ебу, как перевести «Multi direction lee filter» на адекватный русский язык. Более того, я с трудом понимаю что это вообще такое, а для чего это — не понимаю вообще. Но раз уж зашла речь про фильтрацию, грех не рассказать про эту хрень.

Фильтр разделяет растр на три дочерних: результат фильтрации, растр минимума стандартного отклонения и растр направления минимума стандартного отклонения.

Результат фильтрации визуально от оригинала не отличим:

Минимальное стандартное отклонение. Тут все почти просто, если найти мануал, объясняющий значение прилагательного «минимальное».  Результирующий растр в псевдоцветах выглядит так (чем краснее, тем выше стандартное отклонение):

Слой изолиний в той же палитре:

Но самое интересное — направление минимума стандартного отклонения. Я воздержусь от комментариев, лучше покажу вам результат и выпью своего пива.

Изолинии по растру направления минимума стандартного отклонения на фоне изолиний SRTM (черные линии):

Гораздо понятнее обстоят дела с ранговым фильтром. Просто указываете ранг сатистики и извлекаете пиксели с нужными значениями. Вот, например, медиана

Изолинии из результата фильтрации (50-й ранг) на фоне изолиний SRTM:

На этом все.

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

Да прибудет с нами псевдоцвет растра итогов применения фильтра Лапласа!

Ну и горизонтали, само-собой. Хотя, это все-таки не горизонтали, а просто изолинии.

Хотя, конечно, проще всего использовать простой фильтр. Особенно, если вы хотите строить горизонтали.

А еще проще совершенно не использовать фильтр. Я лично нефильтрованному вообще приоритет отдаю, у меня как раз тут еще немного осталось.

Надеюсь, на этом, ваша просьба о фильтрации полностью удовлетворена. Всем присутствующим спасибо. Все недовольные могут пройти нахуй, ибо тут у меня суверенный анархизм: хочешь с Бакуниным бухай, хочешь Вольтариану Де Клер еби. А советы ваши по поводу того, как мне следует статьи писать можете в жопу себе засунуть.

Векторная отмывка

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

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

Возьмем модифицированный фрагмент MODIS Blue Marble Next Generation с повышенной яркостью и контрастом для основы:
2

Для того, что-бы изобразить рельеф этой местности можно пойти классическим путем, наложив сверху полупрозрачную карту теней. А можно наложить векторный слой горизонталей и результат будет вполне неплох.
2a

Весь секрет в том, что горизонталей должно быть много (интерполируйте не жалея процессора), но каждая из линий должна быть максимально тонкой. В этом случае отдельные линии становятся незаметными, а склоны с присущими им сгущениями горизонталей проявляются на карте в виде градиента.
izorelef

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

izorelef2

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

3

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

1a

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

index

Из этого не следует, что векторная отмывка лучше растровой или наоборот. В разных ситуациях должны расцветать разные цветы. Интересно другое: отмывку вполне можно считать частным случаем изображения рельефа с помощью изолиний. А значит что? Правильно, если не брать в расчет всякого рода экзотику и цвет, то рельеф на картах изображается двумя способами: с помощью поперечной (отмывка, изолинии) и продольной штриховки. Последняя, к слову, незаслуженно забыта и хранит в себе огромный потенциал по визуализации рельефа. Да что там говорить, сами посмотрите (фрагмент карты взят с геомануала):

000109

Пивопровод на ХБК

В поселке ХБК сто четыре жилых дома, которые необходимо подключить к пивопроводу. Само собой, сделать это необходимо с минимальными издержками на прокладку труб и дальнейшее их обслуживание.

Для проектирования пивопроводной сети, откроем в QGis карту OpenStreetMap с помощью плагина QuickMapServices или его старого аналога OpenLayersPlugin:

1

Приблизим интересующий нас район, и создадим полигональный шейп-файл:
2

Обведем контуры поселка:
3
Теперь, требуется загрузить контуры домов, нуждающихся в подключении. В нашем случае самым простым решением будет импорт зданий из базы геоданных OpenStreetMap с помощью сервиса Overpass turbo. Мы для этих целей воспользуемся плагином QuickOSM, загрузив полигональные объекты со значением «building=apartmens». В OSM полигонального типа нет, модуль выполняет эту конвертацию за нас:
4
В результате получим векторные слой, который будем использовать для построения графа.

5

Прежде всего, получим вершины графа, путем извлечения центроидов полигонов:
6
Если бы мы располагали графическими картами в качестве исходного материала, то пришлось бы их отсканировать, затем привязать, затем оцифровать. Это конечно дольше, но мы бы расставили точки более сложным образом. Центроиды полигонов хорошо применять только в случае простых полигонов, на сложных это приводит к погрешности:
8
Впрочем, нас такая точность устраивает, тем более, что от каждого центроида будет идти разводящая сеть. Мы получили вершины графа. Теперь, используя триангуляцию Делоне создадим множество полигонов, каждая вершина которых будет точкой центроида зданий.
7
Преобразуем полигональную триангуляцию в сеть линий. С помощью команды «split» плагина Networks разобьем сеть на отдельные линии. Мы получили граф, достаточный для роутинга. Если нам потребуется кратчайшим образом связать между собой две его вершины, достаточно будет просто использовать модуль RoadGraph:
9
При необходимости, можно добавить каждому ребру графа определенный вес. Полученные полилинии можно экспортировать в виртуальный слой и во внешний шейп.
15

Но у нас немного другая задача — построить сеть с ребрами минимальной длины. Для этого рассчитаем длину каждого ребра, используя встроенный калькулятор QGis:
13
Раскрасим слой ребер по градиенту возрастания длины ребра.
14
Ребер у нас много, поэтому выведем длину каждого из них в качестве подписи:

4

Теперь начинается чистая математика: нам требуется выбрать наиболее подходящий алгоритм. Очень много зависит от конкретных условий проектирования, например нельзя оставлять висячие ребра, нельзя делать множественное ветвление и др.

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

Добавим домики, отметим точки ветвления сети, изменим для лучшей визуализации проекцию и схема готова.

2

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