Отображаем карты OpenStreetMap на iPhone 4 с учётом сетчаточного дисплея при помощи Leaflet

    Всякий, кому до сегодняшнего дня доводилось запускать полноэкранный пример работы движка Leaflet на новейших мобильниках iPhone 4, неизменно получал перед собою вот какую карту OpenStreetMap в новоайфоновском разрешении 640×960:

    [скриншот]

    Как видите, векторный гипертекст (подпись под картою) выглядит существенно лучше по качеству, чем растровый текст (надписи на карте) и чем контуры дорог на карте. Это потому, что растровые картинки на сетчаточном дисплее по умолчанию состоят из квадратов 2×2 реальных (физических) пикселов — стало быть, растровый текст получается угловатым, контуры дорог получаются ступенчатыми, и так далее.

    Сегодня это положение дел изменилось к лучшему.

    Сегодня mourner внёс в Leaflet написанный мною джаваскрипт, который проверяет значение window.devicePixelRatio и запускает на сетчаточных дисплеях использование вчетверо большего количества вчетверо меньших по площади (вдвое меньших по размеру) тайлов карты. (Тайлы 256×256 уменьшаются до 128×128 условных пикселов, что составляет 256×256 физических пикселов сетчаточного дисплея.)

    Мой джаваскрипт настроен срабатывать не по умолчанию, а только в том случае, если при создании тайлового слоя задан параметр «detectRetina» со значением «true». Дело в том, что вдвое более чёткие надписи одновременно становятся и вдвое более мелкими — далеко не для всех слоёв это может быть удобно.

    Например, если поверх слоя ненадписанных космоснимков или не надписанных карт в вашем приложении лежит слой отдельных надписей (скажем, локализованных под язык письменной речи конкретного пользователя), то вы легко сможете уменьшить тайлы космоснимков (да и тайлы карт, если контуры дорог не выйдут чрезмерно тонкими), повысив их чёткость, но при этом не тронуть надписи, если они при уменьшении в два раза становятся чрезмерно трудночитаемыми, хотя и чёткими.

    Надеюсь, это улучшение прекрасного mournerовского движка карт окажется для кого-нибудь полезным.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 17

      +12
      Увидел в RSS «сетчаточный дисплей» и решил проверить — не Мицгол-ли автор?
        +6
        Очень информативный комментарий. Как и мой, впрочем.
          +5
          Продолжу цепочку информативных комментариев:
          Если дисплей — сетчаточный, то OpenStreetMap надо называть открытыми уличными картами, JavaScript — явовым скриптом, тайлы — лоскутами, пикселы — светящимися точечками на экране, растр — граблями, а Leaflet — листочечной яваскриптовой библиотекой.
            +4
            >JavaScript — явовым скриптом
            Явовым сценарием же.
              +3
              Поддерживаю. Издеваются над нормальным названием «ретина-дисплей»
                0
                Мля! Только после вашего коммента я понял, что «сетчаточный дисплей» — это «retina»!!! о_0

                У меня просто нет слов…
            +11
            Мицгол, уже ведь обсуждалось, что в русском языке есть слово «Ретина» и в словарях оно присутствует. Фигли ты не меняешься?
              +1
              Дело в том, что вдвое более чёткие надписи одновременно становятся и вдвое более мелкими — далеко не для всех слоёв это может быть удобно.


              Просто для прояснения ситуации, обозначенной в цитате, так как «вчетверо большего количества вчетверо меньших...» немного запутанно: я так понимаю, это значит что нам дают не тот же тайл, который был 128x128, в разрешении 256x256, а 4 тайла 128x128 (что равносильно, вчетверо большему куску карты вместо того же самого). Так? Иначе надписи были точно такие же.

              В этом случае интересен вопрос, как же генерятся такие тайлы. Из векторного исходника? Если так, то есть ли хотя бы теоретическиая возможность перегенерить тайлы в 256x256?
                0
                Наконец долгожданный первый комментарий по существу дела.

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

                Мой код использует то обстоятельство, что число тайлов удваивается на каждом последующем уровне увеличения (на уровне 0 весь мир помещается внутри единственного тайла — квадрата 256×256, на уровне 1 — внутри четырёх тайлов, и так далее). Соответственно, достаточно обратиться к последующему уровню увеличения и взять оттуда четыре тайла 256×256, придав им размер 128×128 — и задача будет решена: каждый из них ляжет на реальные пикселы сетчаточного дисплея один к одному.

                Перегенерирования не происходит.
                  +1
                  Спасибо за более подробное описание, хотя то, что это не 4 копии одного тайла, это в прицнипе понятно было=)

                  Насчет перегенерации, я имел в виду, не в контекcте данного движка, а в прицнипе OSM, смогут ли они когда-нибудь предоставить тайлы для дисплеев с высокой плотностью, так чтобы описанной проблемы с надписями не было.
                    +1
                    Прозреваю, что рост популярности сетчаточных дисплеев приведёт со временем к тому, что будут создаваться специальные тайлы вчетверо большей площади специально для таких дисплеев.

                    Возможны и совершенно векторные тайлы сравнительно произвольного размера, отображаемые на квадратных холстах (<canvas>): примером этого подхода служит движок «Kothic JS».
                +1
                А где скрин с результатом?
                  0
                  Увы, у меня нет iPhone 4, так что решать эту проблему пришлось абсолютно вслепую, ориентируясь на комментарии других пользователей движка.
                  0
                  Стало, пожалуй — лучше.
                  Но есть ещё над чем поработать. Если я всё сделал правильно, конечно.
                    0
                    Ничего не изменилось. В мобильном примере к Leaflet мой код ещё не включён настройкою.
                      0
                      Жаль. Так и подозревал, что я недопонял.
                      Сравнивал по серенькому значку, который на моём снимке — рядом с кнопкой уменьшения.
                        0
                        А есть способ, всё же сделать снимок с iPhone 4?
                        Могу посодействовать.

                  Only users with full accounts can post comments. Log in, please.