В нашей документации мы, в основном, приводим простые примеры, помогающие лучше понять основы работы YourMaps. Однако простыми примерами возможности нашего сервиса не исчерпываются.
Ниже мы по шагам пройдем процесс решения прикладной задачи, которая вылилась в вот такой вот граф пайплайна:
![](https://docs.yourmaps.io/content/images/2020/05/image-8.png)
Итак, перед нами стояла задача - получить полигоны зданий, в которых находятся медицинские учреждения - клиники или врачебные кабинеты. В OSM такое обозначается тегами amenity=clinic или doctors (есть и другие значения этого тега, связанные с медициной, но нас интересовали именно эти два).
Для начала создадим два фильтра по этим двум значениям тега и объединим их результат с помощью операции объединения:
![](https://docs.yourmaps.io/content/images/2020/05/image-9.png)
Запустим пайплайн и поглядим на результат:
![](https://docs.yourmaps.io/content/images/2020/05/image-10.png)
Мы видим, что наши значения тега встречаются как у зданий (синий прямоугольник справа), так и в виде отдельных точек (маркеры). Так работает тегирование в OSM - всякие объекты внутри зданий (магазины или вот клиники), не занимающие все здание целиком, отмечаются точками внутри полигона здания.
Проблема в том, что нам были нужны именно сами полигоны зданий, но с тегами медицинского объекта. Чтобы этого добиться, нам надо:
- Выделить все здания (это объекты с тегом building)
- Найти те из них, в которые попадают точки с нужными нам значениями amenity
- Объединить значения тегов здания и точки внутри
Для выборки зданий мы используем узел выборки по наличию тега. Так как конкретное значение тега building нам не важно, важно лишь его присутствие.
![](https://docs.yourmaps.io/content/images/2020/05/image-11.png)
Далее нам надо отобрать только точечные объекты-клиники, так как именно они находятся внутри зданий. Для этого мы будем использовать узел выборки по типу геометрии:
![](https://docs.yourmaps.io/content/images/2020/05/image-12.png)
Теперь нам нужно среди зданий отобрать те, которые пересекаются хотя бы с одной клиникой. Для этого есть фильтр пересечения геометрий. На первый вход он принимает объекты, на второй - геометрию. На выход передаются те объекты, которые пересекаются хотя бы с одной геометрией со второго входа.
Подадим на вход объектов здания, на вход геометрий - наши точечные клиники и получим на выходе здания, которые содержат в себе клинику.
![](https://docs.yourmaps.io/content/images/2020/05/image-13.png)
Теперь нам осталось перенести теги с точечных клиник на здания, внутри которых они находятся. Для этого у нас есть узел слияния объектов. Этот узел ищет пересекающиеся объекты во входном потоке, объединяет их геометрии и теги, и полученные объекты передает на выход.
Подадим ему на вход наши здания (выход с фильтра пересечений) и клиники (выход с узла фильтра по геометрии). В результате он объединит здания и находящиеся внутри них клиники в один объект.
![](https://docs.yourmaps.io/content/images/2020/05/image-14.png)
Мы чуть не забыли про то, что иногда тег клиники ставится на все здание целиком.
Добавим вывод всех клиник, имеющих полигональную геометрию, сразу на выход с помощью еще одного узла объединения. Итоговый граф выглядит вот так:
![](https://docs.yourmaps.io/content/images/2020/05/image-15.png)
Казалось бы, это уже то, что надо:
![](https://docs.yourmaps.io/content/images/2020/05/image-16.png)
Где раньше была точка - теперь у нас полигон здания, с проставленным amenity=doctors.
Оданко OpenStreetMap не был бы таким, какой он есть, если бы в нем все было так просто. Расширим нашу область карты, чтобы она захватывала большую часть Васильевского острова, и увидим вот такое:
![](https://docs.yourmaps.io/content/images/2020/05/image-17.png)
Оказывается, иногда медицинские amenity ставят не на точку или здание, а на территорию медучреждения целиком. Нам придется еще доработать наш пайплайн, чтобы он смог обработать и такие варианты.
Если раньше мы просто брали полигональные amenity=clinic и подавали на выход, то теперь нам нужно выделить внутри них все здания и тоже перенести теги на здания.
Добавим еще один фильтр по пересечениям, в котором отберем теперь здания, которые содержатся внутри. Переключим режим на "Contains" - нам нужны здания, которые находятся полностью внутри территории клиники (иначе при дефолтной проверке "Intersects" мы можем получить здания, которые касаются ее края, но сами находятся за ее пределами)
![](https://docs.yourmaps.io/content/images/2020/05/image-18.png)
Теперь у нас есть полигоны клиник и здания на их территории. Мы не можем просто так их объединить с помощью узла Merge как делали для точечных клиник. Так как при объединении геометрии здания и большей по размеру клиники результатом будет опять большой полигон территории.
Поэтому мы сперва "вырежем" из клиник участки, соответствующие зданиям. Для этого используется узел Intersection. Он модифицирует объекты с первого входа, оставляя только ту часть их геометрии, которая пересекается хотя бы с одним объектом из второго входа.
![](https://docs.yourmaps.io/content/images/2020/05/image-20.png)
Разберемся, что тут происходит:
- Со входа 1 поступают все здания
- От фильтра 2 поступают полигональные клиники (это могут быть как отдельные здания, так и области)
- На выходе фильтра 3 мы получаем здания (со входа 1), которые содержатся хотя бы в одной клинике.
- Узел 4 принимает на первых вход клиники, на второй здания. Обрезает клиники, оставляя только ту часть их геометрии, которая находится хотя бы под одним зданием.
- Узел 5 объединяет работу предыдущих узлов - выход узла 3 (здания) и выход узла 4 (клиники, обрезанные до полигонов зданий).
- Узел 6 объединяет пересекающиеся объекты. Геометрия клиник и зданий уже совпадает после обрезки, поэтому меняются (объединяются) только теги. На выходе мы получаем объекты, имеющие геометрию зданий и теги и от зданий, и от клиник.
После этих правок территории уже обрабатываются правильно и мы получаем в итоге полигоны зданий
![](https://docs.yourmaps.io/content/images/2020/05/image-21.png)
Итоговый граф пайплайна выглядит вот так:
![](https://docs.yourmaps.io/content/images/2020/05/image-22.png)
Много узлов, зато при его создании практически не приходится думать о низкоуровневых заботах скачивания и обработки OSM, а лишь о высокоуровневых задачах взаимоотношений объектов на карте. При этом создание такой нетривиальной задачи экспорта не требует умения программировать, лишь перетаскивать блоки графа мышкой, с возможностью быстро запустить и оценить результат.
А сколько бы такое же заняло у вас в вашем текущем инструменте?