Стилизация данных в Overpass Turbo
Введение
Карты — это язык, на котором говорит география. Но даже самые точные данные теряют силу, если их нельзя «увидеть». Представьте: вы нашли в OpenStreetMap все нужные объекты — дороги, парки, кафе — но на карте они сливаются в одно серое пятно. Как выделить главное? Как сделать так, чтобы карта «заговорила»?
Ответ — MapCSS. Оно помогает нам отображать данные как мы того хотим. Мы можем менять цвета, иконки, прозрачность, режим отображения, вывод информации как хотим. Всё это помогает в расследовании и изучении местности.
Начало
MapCSS — это язык стилей для карт. Если вы знакомы с CSS, который используется для оформления веб-страниц, то MapCSS покажется вам очень похожим. Но вместо того чтобы стилизовать HTML-элементы, MapCSS работает с географическими данными.
Основные возможности MapCSS:
- Цвета и прозрачность
Задавайте цвета для линий, заливки полигонов и текста. - Иконки и изображения
Добавляйте иконки для точек (например, кафе, парков, магазинов). - Текстовые подписи
Отображайте теги (например,name
,population
) прямо на карте. - Условные стили
Меняйте внешний вид объектов в зависимости от их тегов (например, дороги разного типа могут быть разного цвета).
Начинаем стилизовать данные.
Цвета.
Для этого используется специальный блок {{style: ... }}
, который добавляется в ваш запрос.
Давайте начнем с простого. Найдём кафе в центре Москвы.
nwr["amenity"="cafe"]({{bbox}}); out center;
Пока у нас результаты отображаются в виде жёлтых точек.
{{style: // а тут будут мы будем стилизовать наши данные }}
- Внутри нам нужно будет указать, что мы хотим стилизовать. Мы укажем node, потому что у нас результат - это точки.
- Далее ставим квадратные скобки и в них пишем какие именно точки мы хотим стилизовать, в нашем случае amenity=cafe (можно указать просто amenity, если у нас только cafe и других amenity не имеется)
- Ставим фигурные скобки и в них уже стилизуем нашу точку.
{{style: node[amenity=cafe]{} }}
Внутри фигурных скобок пишем следующий код:
{{style: node[amenity=cafe]{ color: black; fill-color: black; } }}
Цвет мы можем указывать как в hex коде (например #000000), так и просто написать название цвета на английском. Я покрасил все кафешки в чёрный.
Если у вас на карте изображены не только кафешки, а еще и другие объекты, допустим зоопарки. То окрасить зоопарки другим цветом можно аналогичным способом, просто добавьте зоопарк в {{style:}} и стилизуйте как хотите. Получается у вас кафешки будут одного стиля, а зоопарки другого. И так вы будете их отличать. Например я хочу, чтобы кафешки были красными, а зоопарки зелеными.
( nwr["amenity"="cafe"]({{bbox}}); nwr["tourism"="zoo"]({{bbox}}); ); out geom; {{style: node[amenity=cafe]{ color: white; fill-color: red; fill-opacity: 1; } area[tourism=zoo]{ color: white; fill-color: green; fill-opacity: 0.7; } }}
Про area и fill-opacity мы еще поговорим в этой статье. Вот, что у нас получилось:
Непрозрачность
А как поменять прозрачность точки? Я хочу супер чёрную точку!
Это можно сделать с помощью тега fill-opacity, чтобы сделать супер черную непрозрачную точку, непрозрачность выставим на 1.
Я так делать конечно не рекомендую, потому что если много точек, то все начнет сливаться, нужно хотя бы изменить цвет контура (тег color). Давайте добавим белый цвет контура. Кстати у цвета контура тоже есть непрозрачность, для этого есть тег color-opacity, его тоже выставляем на 1.
Ну это намного лучше! Теперь ничего не сливается и всё хорошо.
Давайте повторим основные ключи для непрозрачности.
Непрозрачность можно делать не только для точек, а еще и для иконок, на них мы сейчас и посмотрим.
Иконки
А я не хочу, чтобы кафешки отображались просто черными точками. Я хочу добавить свою иконку, чтобы она была красивая и офигенная. Я могу такое сделать?
Да, можешь. Для этого есть такие теги:
icon-image: выбираем любую иконку для наших точек. В ключе для этого тега мы указываем URL картинки.
Я добавлю для наших кафешек вот такую иконку:
Пишем тег icon-image и указываем ссылку на изображение. А размер иконки, я пожалуй, выберу 25.
У меня получаются такие стили:
{{style: node[amenity=cafe]{ icon-image: url('https://img4.teletype.in/files/3e/45/3e45687a-502c-4f23-a167-992702287f70.png'); icon-width: 25; } }}
Прозрачность иконок вы также можете настроить с помощью дополнительного слова opacity.
Сборник официальных иконок Overpass Turbo можете найти здесь.
Давайте повторим теги для иконок! Вот они:
Стилизуем вывод информации.
Я совсем не понимаю, что это за кафешки, я не вижу их названия. На каждую приходится нажимать, чтобы это посмотреть. Я хочу, чтобы названия кафешек отображались сразу! Как это сделать?
Ты можешь сделать и такое! Давай оставим наши иконки для кафешек и добавим к ним названия самого заведения.
А для этого мы используем следующий ключ:
В нашем случае мы будем выводить название кафешки, поэтому я пишу так:
text: name;
Всё! Теперь у нас отображаются еще и названия кафешек. Разве это не круто?
Вывести можно не только название, а вообще всё, что указано в характеристиках объекта (сколько этажей, часы работы, номер остановки и многое другое)
Давайте я добавлю к этой информации еще и часы работы кафешки.
Нужно как-то отобразить сразу два тега. Для этого можно использовать функцию eval(). Туда можно впихнуть любой текст и теги. Чтобы объеденять строки нужно использовать конкатенацию, в MapCSS оператором конкатенации является просто точка. Щас я вам покажу код, но вы сильно не путайтесь, щас я все объясню.
text: eval('tag("name") . '(' . tag("opening_hours") . ')'');
Если вы когда нибудь программировали на Python, то там, чтобы конкатенировать строки мы использовали знак плюс. Здесь мы используем точку, чтобы объеденять слова и значения тегов.
Здесь я соеденяю название кафешки со скобочкой, дальше конкатенирую рабочие часы и присоеденяем вторую скобочку. Чтобы ответ выглядел как-то так:
Давайте посмотрим, что у нас получилось:
Отлично! Теперь у нас указывается название кафешки и часы работы (если имеется). И так вы можете совмещать различные данные.
Можно даже сделать так, чтобы явно указать, что это название и :
text: eval(''Название: ' . tag("name") . ', Время работы: (' . tag("opening_hours") . ')'');
Также можно в eval производить математические вычисления, например если я хочу уменьшить размер иконки в 5 раз.
icon-width: eval("25/5");
таким убразом у нас размер иконки уменьшится в 5 раз от изначального и станет размером 5. Вычисления можно производить и с полученными данными, например с численностью населения, этажностью здания и другими числовыми параметрами, если такие имеются.
Тегов к выводу информации очень много, можно настраивать шрифт и параметры вывода. Вот полный список тегов:
А нам достаточно запомнить только тег text, потому что он основной.
Стилизуем линии.
Итак, мы узнали как стилизовать точки, теперь давайте посмотрим, что можно сделать с линиями.
Сейчас я покажу как выглядят линии без стилизации. Ищем главные дороги центра в центре Москвы:
way["highway"="primary"]({{bbox}});
Синии линии и дефолтные точки (если приблизить карту, то точки исчезают, остается только линия).
Мы можем поменять их цвет, прозрачность, ширину, паттерн отрисовки и многое другое. Ну что-же давайте поменяем цвет линии на чёрный (по классике). Добавляем в стили теги color (цвет линии), fill-color (цвет точек), opacity (непрозрачность линий):
{{style: way[highway=primary]{ color: black; fill-color: black; opacity: 1; } }}
Линии стали чёрными. Также можно отображать линии в виде штрихов. Для этого используйте тег dashes: x,x,x,x; (где x какое-то значение), можно поиграться со значениями, я поставил 8,8,4,4, также изменю ширину линии на 2 (width:2;).
Всё довольно аккуратно и понятно.
Я считаю больше вам про стилизацию линий знать и не надо, этого достаточно.
Вот основные теги для стилизации линий:
fill-color: цвета точек (Если приближать карту, эти точки пропадают)
dashes: x, x, x, x (где x - какое-то значение). Указываете этот тег, если хотите, чтобы линия отображалась штрихами.
Вот полная таблица тегов для линий:
Стилизуем полигоны
Полигон - это область, которым обозначают геометрию зданий, парков и других объектов, которые имеют площадь.
Давайте опять на примере кафешек поищем объекты, только на выходе пропишем
out geom;
out center;
потому что нам нужно вывести геометрию объекта.
P.S out center выводит центр всех объектов. Если это точка, то она так точкой и остается, а если это полигон, то показывается его центр как точка. (Получается на выходе мы получаем точки всех центров).
out geom показывает геометрию всех объектов. Если это точка, то она так точкой и остается, а если это полигон, он будет показываться как полигон.
Давайте найдем кафешки с геометрией:
wr["amenity"="cafe"]({{bbox}}); out geom;
wr ищет way и relation сразу, потому что полигон это замкнутая в себя линяя (way), также заведение может быть отмечено как relation. Как отмечаются заведения (почему некоторые отмечают как node, а некоторые как way и relation) я могу рассказать в полном туториале overpass turbo, поэтому поставьте лайк.
Теперь давайте давайте добавим стили к полигону.
Окрашу кафешку красным цветом с белой обводкой, непрозрачность заливки 0.5:
{{style: area[amenity=cafe]{ fill-color:red; fill-opacity: 0.5; color: white; } }}
Прошу заметить, что в MapCSS для полигонов уже используется area, а не way.
Кафешек с геометрией в Москве не очень много отмечено, в основном это точки. Поэтому давайте покажу на примере зданий. Переделаем код, вот так:
wr["building"]({{bbox}}); out geom; {{style: area[building]{ fill-color:red; fill-opacity: 0.5; color: white; } }}
На выходе получаем абсолютно все здания:
Теперь посмотрим наглядно сколько из этих зданий квартир, изменим немного стили и окрасим теперь все квартиры в синий. Остальные здания останутся красными.
wr["building"]({{bbox}}); out geom; {{style: area[building]{ fill-color:red; fill-opacity: 0.5; color: white; } area[building=apartments]{ fill-color:blue; fill-opacity: 0.5; color: white; } }}
В этом коде сначала все здания перекрашиваются в красный, а потом меняем цвет квартир с красного на синий. Это можно было конечно сделать иначе, но этот способ тоже имеет место быть.
Ну грубо говоря, половина из всех этих зданий являются квартирами.
Стилистика полигонов от точек ничем не отличается. Поэтому не будем заострять на них внимание.
Давайте я покажу несколько примеров как можно использовать стилистику в GEOINT. На самом деле примеров использования гораздо больше, их просто бесконечное множество, поэтому я уверен вы тоже сможете найти в этом применение.
Примеры использования.
1. Находим кафе, в котором был человек.
Допустим мы хотим найти кафе, в котором был человек (фото в кофе он выложил в социальной сети, определить по фото нам никак не удается). Посмотрев предыдущее выложенное фото, там он был в Cбербанке определенного района в городе Санкт-Петербург. Промежуток между постами 15 минут. Нам нужна наглядная информация обо всех кафешках в местности рядом со сбербанком, чтобы мы начали конкретный поиск.
Для этого найдём и выведем сбербанки, также выведем все кафе в этом районе, чтобы начать смотреть самые близжайшие к нему.
nwr["brand"="Сбербанк"]({{bbox}}) -> .bank; nwr["amenity"="cafe"]({{bbox}}) -> .cafe; .bank out geom; .cafe out geom; {{style: node[brand=Сбербанк], area[brand=Сбербанк] { fill-color: blue; color:blue; } node[amenity=cafe], area[amenity=cafe] { fill-color: red; color:red; } }}
Кафе окрасили в красный, а сбербанки в синий.
Теперь нам наглядно видно и мы можем предположить в какое кафе пошел человек:
Тут можно решить таким способом: можно посмотреть и найти нужный нам сбербанк, а потом рядом с ним брутфорсить нужное кафе (от самых ближних до дальних). Давайте посмотрим следующий случай, в котором может пригодится стилистика.
2. Наглядно показываем различие первых двух цифр в ID автобусных остановках в Южной Корее.
Кто не в курсе, то в Сеуле у автобусных остановок есть ID. Первые две цифры ID это район. Можете почитать мой райтап, если не видели. Давайте теперь найдем все автобусные остановки начинающиеся с цифр 18,19,20,21,22,23,24,25. Расскрасим их разными цветами и посмотрим на карте, что у нас получится.
nwr["highway"="bus_stop"]["ref"~"^18|^19|^20|^21|^22|^23|^24|^25"]({{bbox}}); out geom; {{style: node[ref=~/^18/] { fill-color: blue; color:white; fill-opacity:1; } node[ref=~/^19/] { fill-color: red; color:white; fill-opacity:1; } node[ref=~/^20/] { fill-color: green; color:white; fill-opacity:1; } node[ref=~/^21/] { fill-color: purple; color:white; fill-opacity:1; } node[ref=~/^22/] { fill-color: black; color:white; fill-opacity:1; } node[ref=~/^23/] { fill-color: white; color:white; fill-opacity:1; } node[ref=~/^24/] { fill-color: grey; color:white; fill-opacity:1; } node[ref=~/^25/] { fill-color: orange; color:white; fill-opacity:1; } }}
Уууух, код конечно не очень маленький. Но он лёгкий. В стилистике мы можем использовать regex, для этого после равно пишется ~/regex/ (вместо regex пишете свое. Знак ^ означает, что мы ищем все айдишники которые начинаются с этих цифр).
Таким образом мы наглядно увидели сколько остановок в районах 18-25.
3. Котик вместо точек.
Давайте немного расслабимся. Точки это слишком скучно, давайте поменяем точек на котика!
В duckduckgo пишем "cat head" и указываем, что мы хотим искать transparent картинки (с прозрачным фоном).
А теперь я найду все ветеринарные клинки в центре Москвы и вместо точек у меня будет этот котик!
nwr["amenity"="veterinary"]({{bbox}}); out center; {{style: node[amenity=veterinary]{ icon-image: url("https://img2.teletype.in/files/1e/05/1e05fa06-3ae8-4e94-ad04-e8014f4e2420.png"); icon-width: 40; } }}
4. Дурка
А теперь к нашим котикам добавим психиатрические больницы с такой иконкой:
Вот наш код с котиками и с дурками:
( nwr["amenity"="veterinary"]({{bbox}}); nwr["name"~"Психиатрическая"]({{bbox}}); ); out center; {{style: node[amenity=veterinary]{ icon-image: url("https://img2.teletype.in/files/1e/05/1e05fa06-3ae8-4e94-ad04-e8014f4e2420.png"); icon-width: 40; } node[amenity=hospital], node[amenity=clinic]{ icon-image: url("https://img1.teletype.in/files/06/41/0641e831-31c6-442e-b6ae-9f6b9c323cb8.png"); icon-width: 40; } }}
На основе этих данных, можно вычислить лучшую дурку.
Вот она. Она лучшая, потому что там наибольшая концентрация котиков, выше шанс вылечиться.
Заключение
И так мы можем стилизовать данные как хотим и сколько хотим. Менять бесконечное количество цветов, иконок, вывода информации. Всё это помогает в эффективном решении задач и проведении расследований. Я лишь показал малую часть примеров (хоть они прикольные и смешные).
Если вам было полезно, то поставьте лайк. Я старался. Можете задонатить, если хотите. Вот основные источники, которые я использовал, тут можете найти таблицу тегов и другую информацию:
Документация по стилистике Overpass Turbo.
Статья может дополняться и улучшаться, по мере необходимости и желания.
В скором времени хочу написать туториал по всему Overpass Turbo, поэтому поставьте лайк :)
❤️❤️❤️Угостить автора пельмешками.