Под катом небольшой рассказ озум-левелах: почему встандартном виде они неподходят для больших территорий икак масштаб влияет назагрузку тайлов ивнешний вид карты.
Зум-левел
Для обозначения масштаба вWebGL-карте 2ГИС, как ивомногих других картах, используется число зум-левел или просто зум. Зум, равный нулю, соответствует масштабу карты, при котором весь мир помещается вквадрат размером 256256px.
Карта мира при zoom = 0
Увеличение зума наединицу соответствует растяжению карты вдва раза. Напервом зуме весь мир будет размером 256 2 = 512px. Начетвёртом получаем размер 256 2 2 2 2 = 4096px.
Такая система позволяет обозначать диапазон масштабов удобными для понимания числами. Например, zoom = 11 примерно один крупный город наэкране, zoom = 19позволяет детально рассмотреть здания ипроходы между ними.
Проекция Меркатора
Вкартах 2ГИС используется картографическая проекция Меркатора. Картографическая проекция способ отобразить сферическую поверхность Земли наплоской карте.
Так как плоскость ишар неодно итоже, любая картографическая проекция искажает форму или размеры объектов. Впроекции Меркатора объекты набольших широтах накарте выглядят больше, чем объекты наэкваторе. Поэтому натаких картах Гренландия выглядит размером сАфрику, хотя фактически еёплощадь меньше площади Африки в14раз. Здесь можно рассмотреть, как проекция искажает размеры стран.
Если Россию приблизить к экватору, её размер на карте значительно уменьшается
Растяжение объектов пропорционально 1 / cos(lat), где lat широта объекта. Из этой формулы следует, что объекты на широте Санкт-Петербурга (lat = 60) на карте будут растянуты в два раза. А объекты на Северном или Южном полюсах (lat = 90) и вовсе растянутся до бесконечности. Именно поэтому на картах в проекции Меркатора никогда не рисуются полюса на них обрезается всё севернее и южнее 85 широты.
Подробнее о проекции Меркатора можно почитать в этом наглядном и увлекательном материале.
Проблемы сзумом ипроекцией Меркатора
Изсвойств проекции Меркатора вытекает главная проблема сзумами: один итотже зум-левел наразных широтах соответствует разным фактическим масштабам карты.
Сравним скриншоты карты на14-м зуме вМурманске (широта69) иТашкенте (широта41).
15-й зум в Мурманске
15-й зум в Ташкенте
Видно, насколько сильно отличаются поразмеру дома. ВМурманске они крупные, вТашкентеже карта мельчит.
При создании стилей карты мыхотим придать ейопределённый внешний вид. Для этого задаём ширину дорог впикселях взависимости отзума или зум, скоторого начинаем показывать дома. Стили, написанные для одной широты, надругой будут выглядеть совсем иначе. Смысл, заложенный вних, исказится, так как зумы будут означать уже другой фактический масштаб.
Решение
Для решения этой проблемы мыввели понятие styleZoom, который может отличаться отобычного zoom.
Обычный zoom | StyleZoom |
Определяет масштабирование объектов | Определяет, какие тайлы грузить |
Записывается в url | Определяет, для какого масштаба применять стили |
Используется в привычных методах getZoom / setZoom | Используется в методах getStyleZoom / setStyleZoom |
Совпадает с растровыми тайлами |
styleZoom вычисляется изzoom ишироты посдедующей формуле: styleZoom = zoom + log2(1/ (2 * cos(lat)).
Изформулы вытекают следующие свойства styleZoom:
- Нашироте 60styleZoom = zoom. Так как стили изначально писались наНовосибирск иМоскву, решили взять эту широту забазовую.
- Наширотах <60styleZoom < zoom. Наэкваторе styleZoom = zoom 1.
- Наширотах >60 styleZoom > zoom.
Посмотрим теперь, как будут выглядеть Ташкент и Мурманск при styleZoom = 15.
Ташкент, styleZoom = 15 (zoom 15.59)
Мурманск, styleZoom = 15 (zoom 14.53)
Хорошо видно, что styleZoom соответствует реальному масштабу карты вне зависимости отшироты: дома визуально неотличаются поразмеру, карта вдвух разных городах выглядит одинаково.
Ограничения
Умеханизма коррекции есть недостатки, которые проявляются вдвух сценариях работы скартой.
zoom < 9
Нанебольших зумах, когда наэкране виден весь мир или его бльшая часть, перетаскивание карты вверх-вниз приводит кбольшим изменениям широтыи, соответственно, styleZoom.
Вовремя перетаскивания это может привести кзагрузке новых тайлов, переключению стилей, появлению или исчезновению объектов ит.п. Чтобы избежать этого эффекта, приzoom<9коррекция отключается, иstyleZoom приравнивается кzoom.
lat > 60
Наочень больших широтах styleZoom становится сильно больше zoom. Так как styleZoom отвечает зато, какие тайлы грузить, может оказаться, например, что на14-м зуме мызагрузим иотобразим тайлы 16-го зума. Тайл 16-го зума в16раз меньше поплощади, чем тайл 14-го зума. Иесли обычно наэкран попадает 30тайлов, товэтом случае ихбудет 480. Аколичество тайлов сильно влияет напроизводительность. Чтобы незагружать видеокарту наэтих широтах, при lat > 60коррекция отключается, иstyleZoom также приравнивается кzoom.
Вместо вывода
Подключайте API наших WebGL-карт иоформляйте картыпод задачи вашего сервиса, непереживая, как они будут выглядеть вразных городах.
Запост отдельное спасибо Лёше Федосову. Лёха, привет!