Один из главных параметров карты — это информативность. Грубо говоря, это то, сколько информации можно считать с карты своими глазами. На самом подробном масштабе всё выглядит просто: места на экране много и нужно рисовать всё, что интересно пользователю (есть у нас в файле данных). Хотя тут остаётся важная задача — определить, что же всё-таки ему интересно. На обзорных масштабах всё сложнее: данных слишком много и надо выбрать те, которые повысят информативность и наглядность карты. Одновременно с этим карту нельзя перегружать. Если отобразить всё, то она станет нечитаемой. А пригодных для отображения на обзорном масштабе без предварительной обработки видов интересных пользователю объектов практически нет!

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



Суть в том, что нужно отобразить красивую дорожную сеть на обзорных масштабах карты. Это делается для того, чтобы карта не казалась пустой. На покупных данных эта задача успешно решается стилями. Когда все данные приходят от одного поставщика, они однородны и можно просто описать, какие дороги нужно рисовать на каких масштабах. Но OpenStreetMap не такой. Карта, которая заполняется пользователями со всего мира, таит в себе массу различий и региональных особенностей в методах картирования. На обзорных масштабах эти различия видны особенно явно. Из-за них не получается нарисовать связную и красивую сеть дорог поверх карты.

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

Исходные данные


Для обозначения дорог в OpenStreetMap используется тег highway. Он может принимать значения motorway, trunk, primary, secondary, residental, service и другие. Подробнее про тег можно почитать в Wiki проекта.

Тегом motorway обозначают магистрали. В Москве им отмечены платные трассы («Дон», М-11, новая Ленинградка) и некоторые вылетные магистрали (Симферопольское шоссе). Однако этим тегом не отмечен МКАД и большинство вылетных магистралей. В Польше всего пара трасс имеет тег motorway. Причём одна из них — это объезд города. В Европе и США этот тег более распространён и образует связную дорожную сеть, но многие дороги из США заканчиваются на границе с Канадой. Всё это делает невозможным использование одного тега motorway.


Дороги, отмеченные тегом motorway

Следующий по важности дорог — тег trunk. Им отмечены «наиболее важные дороги, которые не являются motorway». При учёте этого тега в Москве появляются МКАД и Бетонка, также отмечены большинство вылетных магистралей. А в Польше отметились только несколько дополнительных объездов городов. Европейская дорожная сеть утратила целостность. Здесь много объездов обозначено как highway=trunk. В США таких дорог немного, и они почти теряются в развитой сети дорог motorway.

В итоге на карте не получается единой дорожной сети. В разных городах одинаковыми тегами обозначают разные по качеству дороги. Зачастую более «весомые» теги обозначают крохотные участки объездов городов. Так как вся магистраль не отмечена этими тегами, дорога «повисает» в воздухе, что выглядит некрасиво. А сама проблема не нова. Осмеры сталкиваются с ней давно, только воз и ныне там.

Метод расчёта


Итак, задача — нарисовать дороги на обзорном масштабе. Причём все дороги нарисовать нельзя, так как карта сразу же станет нечитаемой. Получается, что надо поднимать только «главные». Главность дорог можно определять по-разному, я выбрал путь, при котором оцениваю важность дороги по тому, насколько она участвует в построении маршрута из пункта А в пункт B. Для этого я строю маршруты и проверяю, по каким дорогам эти маршруты прошли.

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

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

Первая попытка: соединяем дорогами все столицы


В качестве первого эксперимента я взял все столицы на земле (точки городов с тегом capital=yes) и построил дороги «каждый с каждым». На обзорный масштаб я поднял все дороги, которые хотя бы раз использовались при прокладке маршрутов. В результате у меня получилась единая сеть, которая хорошо покрыла Европу и даже западную часть России. Но здесь себя снова проявила региональная разница в обычаях картографирования OSM. В России тегом capital=yes отмечаются все города, которые являются административными центрами областей, например Тула. А вот в США тегом capital отмечен только город Вашингтон. В результате получившаяся дорожная сеть в США скудна и проходит вся вдоль восточного побережья. Непокрытой осталась и Сибирь.





Также со временем я заметил, что дорожная сеть между столицами получается уж больно плотной. Несмотря на довольно понятное описание тега в его предложении (proposal), которое определяет значения yes/no, самое популярное значение… capital=8!!! На capital=yes/no приходится меньше 3,7%! Вот и верь после этого документации OSM. Кроме того, capital=yes массово используется на Филиппинах. Чтобы разделять местные столицы, нужно рассматривать значение admin_level. Который тоже сильно различается по миру. В вики даже есть табличка, как читать этот тег.

Вторая попытка


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

На примере России получилось, что в европейской части у нас много городов отмечены тегом capital и все другие города отсеялись. А вот Якутия населена гораздо меньше. Чтобы нарисовать здесь хоть что-то, алгоритм поднимает на обзорную карту посёлок Депутатский с 2831 жителем и дорогу к нему. Но поскольку таких городов на карте заметно больше, то я провожу от них дороги только до нескольких ближайших городов. Это позволяет уменьшить количество обращений к роутеру и упростить сами запросы.



Выводы


Вот что в результате у меня получилось:



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

Комментарии (29)


  1. gibson
    06.04.2016 11:27

    Вы только эту задачу преследовали? Из этой карты можно очень много интересной информации получить!


    1. Gard
      06.04.2016 11:30
      +3

      Я преследовал только задачу отображения связной сети дорог.


      1. bopoh13
        07.04.2016 18:40

        Где, например, трасса Москва — Ярославль?


  1. ooprizrakoo
    06.04.2016 11:27

    А почему Ярославское шоссе не попало в обзорную карту? Вроде бы дорога хорошая, широкая, и по ней 150 спокойно можно ехать. Интересно просто с т.з. алгоритмов чем она от Рязанки отличается, например.


    1. Gard
      06.04.2016 11:39
      +2

      Ярославское Шоссе в итоге попало на обзорную карту, но на более низких масштабах. На скрине с результатом показаны только дороги между столицами. На более подробном масштабе появляются дороги между большими городами, и там дорога Москва-Ярославль-Архангельск есть.


  1. mas
    06.04.2016 12:30

    Дорога Киев-Одесса ведёт в… Тирасполь, а Кишинёва вообще нет :|


    1. Gard
      06.04.2016 12:42

      Тирасполь в данных OSM имеет тег capital=yes, как и Кишинёв. Поэтому дороги до этих городов построены. Одесса такого тега не имеет и располагается географически близко к Тирасполю. Из-за этого трасса Киев-Одесса рисуется не полностью. Кишинёв скрыт, чтобы хватило места для названия государства «Молдова». На других масштабах он, конечно, появится. Это именно та проблема, которую я описывал в начале статьи: места на карте не хватает для отображения всех объектов и названий. Чем-то приходится жертвовать.


      1. mas
        06.04.2016 12:50
        -2

        Так о том же и речь, что ваши правила пока не совершенны, и подумайте, как их улучшить, на примере конкретного места. У того же Гугла в том районе всё получается.


  1. Komzpa
    06.04.2016 12:42

    А можно получить результирующие данные в адекватном формате на условиях ODbL? :)


    1. Gard
      06.04.2016 12:58

      Можно зайти в наш github и собрать свои данные :) Результаты расчётов быстро устаревают так как OSM изменяется каждый день.


  1. Habra__User
    06.04.2016 14:18

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


  1. Dmitry_Th
    06.04.2016 16:20

    Тот самый случай, когда проприетарное на три головы выше 'свободного'


    1. vlivyur
      08.04.2016 14:53
      +1

      Тот самый случай, когда вы не сможете повторить такое же на данных от Гугла/Яндекса и пр.


  1. EndUser
    06.04.2016 22:48
    +1

    Это касается maps.me и/или mail.ru?


  1. 54300
    06.04.2016 23:35

    Проблема не в осм, так оно и есть как на первом рисунке(Дороги, отмеченные тегом motorway), связная сеть дорог начинаеться в Германии. Чехию проблемно ехать. В Польше А4 норм но не достроена возле Ржешова. А восточней Польши автобанов нет. Первая картика рулит.


    1. vicnaum
      07.04.2016 00:49

      Именно. На первой картинке есть нормальная автострада Гданьск-Варшава. На результате оно пропало, но появилась какая-то непонятная дорога на Познань через Быдгошч (двухполоска через деревни). Хотя в Польше вообще ад с дорогами.


  1. xenohunter
    07.04.2016 12:14

    Что, если, помимо населённости, учитывать ещё и удалённость от других населённых пунктов? То есть, чем более обособлен город или посёлок, тем меньше для него порог вхождения в дорожную сеть по численности населения.


    1. Gard
      08.04.2016 13:59
      +1

      Так в итоге и получилось: города сортируются по населённости. И начиная с самого населённого города, если рядом нет других использованных городов, мы используем этот город.


  1. anonymous
    00.00.0000 00:00


    1. anonymous
      00.00.0000 00:00


      1. anonymous
        00.00.0000 00:00


    1. anonymous
      00.00.0000 00:00


      1. anonymous
        00.00.0000 00:00


        1. anonymous
          00.00.0000 00:00


          1. anonymous
            00.00.0000 00:00


            1. anonymous
              00.00.0000 00:00


              1. anonymous
                00.00.0000 00:00


                1. anonymous
                  00.00.0000 00:00


                  1. anonymous
                    00.00.0000 00:00