ScaleLine

Библиотека OpenLayers предназначена для создания интерактивных веб-карт с поддержкой векторных и растровых слоёв, проекций, взаимодействий и UI-контролов. Одним из базовых элементов пользовательского интерфейса карты является компонент масштабной линейки ScaleLine, реализованный в виде ol.control.ScaleLine.


Масштабная линейка служит для визуального отображения соответствия между расстоянием на экране и реальной дистанцией на местности. В отличие от численного масштаба (например, 1:50000), ScaleLine даёт наглядное представление в метрах или километрах, обновляясь при изменении масштаба карты.

Основные задачи компонента:

  • отображение текущего линейного масштаба карты;
  • автоматическая адаптация при зуме;
  • поддержка различных единиц измерения;
  • корректная работа в разных проекциях;
  • обеспечение визуальной ориентировки пользователя.

Подключение и базовая конфигурация

Контрол добавляется в карту через массив controls или методом map.addControl.

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
import ScaleLine from 'ol/control/ScaleLine.js';

const scaleLineControl = new ScaleLine();

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM()
    })
  ],
  view: new View({
    center: [0, 0],
    zoom: 2
  }),
  controls: [scaleLineControl]
});

Контрол автоматически вычисляет масштаб на основе текущего разрешения view.


Единицы измерения масштаба

ScaleLine поддерживает несколько режимов отображения:

  • metric — метры и километры;
  • imperial — футы и мили;
  • nautical — морские мили;
  • degrees — угловые единицы (реже используется);
  • us — комбинированная система США;
  • scaleline — автоматический выбор подходящего формата.
import ScaleLine from 'ol/control/ScaleLine.js';

const scaleLineControl = new ScaleLine({
  units: 'metric'
});

При изменении масштаба карты единицы автоматически пересчитываются для сохранения читаемости.


Внутренняя логика расчёта масштаба

ScaleLine опирается на разрешение карты (view.getResolution()), которое определяет количество метров на пиксель. Базовая логика:

  • определяется текущая проекция;
  • вычисляется количество метров на пиксель;
  • подбирается «красивое» значение длины линии;
  • масштаб округляется до удобных значений (1, 2, 5 × 10ⁿ).

Упрощённо вычисление выглядит так:

distance = resolution × pixelWidth

где pixelWidth — ширина линии в пикселях.


Варианты отображения: line и bar

ScaleLine может отображаться в двух основных стилях:

Линейный режим (line)

Классическое отображение в виде одной полосы с подписью.

new ScaleLine({
  units: 'metric',
  bar: false
});

Баровый режим (bar)

Разделённая шкала с несколькими сегментами, более наглядная при больших масштабах.

new ScaleLine({
  units: 'metric',
  bar: true
});

Баровый режим полезен для аналитических карт, где важна визуальная сегментация расстояний.


Поведение при изменении масштаба

ScaleLine подписывается на события изменения view:

  • change:resolution
  • change:center

При каждом изменении пересчитывается длина линии и её подпись. Это обеспечивает синхронность между картой и UI без ручного обновления.


Работа в разных проекциях

В OpenLayers масштабная линейка учитывает особенности проекции:

  • в EPSG:3857 (Web Mercator) расчёты приближённые, но стабильные;
  • в географических проекциях EPSG:4326 используется сферическая модель;
  • в кастомных проекциях возможны искажения.

Особенность: ScaleLine всегда стремится привести результат к метрам, даже если исходная проекция оперирует градусами.


Настройка минимальной и максимальной длины

Контрол позволяет регулировать диапазон допустимых размеров линейки:

new ScaleLine({
  minWidth: 100,
  maxWidth: 200
});

Это влияет на алгоритм выбора «красивого» значения длины.


Форматирование подписей

Подписи автоматически формируются на основе выбранных единиц:

  • 500 m
  • 2 km
  • 3 mi
  • 100 ft

При необходимости можно кастомизировать отображение через CSS:

.ol-scale-line {
  background: rgba(0, 0, 0, 0.6);
  color: white;
  padding: 4px;
  border-radius: 2px;
}

Размещение на карте

ScaleLine является DOM-контролом и может быть размещён в стандартных позициях:

import {defaults as defaultControls} from 'ol/control';

const map = new Map({
  controls: defaultControls().extend([
    new ScaleLine({
      units: 'metric'
    })
  ])
});

Контрол по умолчанию размещается в нижнем левом углу карты.


Поведение при DPI и масштабировании экрана

ScaleLine учитывает devicePixelRatio, что критично для:

  • Retina-дисплеев;
  • мобильных устройств;
  • экранов с нестандартной плотностью пикселей.

Алгоритм пересчёта гарантирует, что физическая длина линии остаётся корректной независимо от устройства.


Стилизация и кастомизация

DOM-структура ScaleLine включает:

  • контейнер .ol-scale-line;
  • внутреннюю линию .ol-scale-line-inner;
  • текстовое значение.

Пример расширенной кастомизации:

.ol-scale-line {
  bottom: 10px;
  left: 10px;
  font-family: Arial;
  font-size: 12px;
}

.ol-scale-line-inner {
  border: 2px solid #2b8cff;
  border-top: none;
}

Программное управление

Контрол можно обновлять и заменять динамически:

map.removeControl(scaleLineControl);

const newScaleLine = new ScaleLine({
  units: 'imperial'
});

map.addControl(newScaleLine);

Также возможно изменение параметров через пересоздание, так как прямой мутации конфигурации не предусмотрено.


Использование в аналитических приложениях

ScaleLine часто применяется в:

  • GIS-системах;
  • логистических сервисах;
  • погодных картах;
  • военных и навигационных приложениях;
  • образовательных картографических интерфейсах.

Причина — визуальная интерпретация расстояний без необходимости вычислений.


Особенности реализации и производительность

ScaleLine относится к лёгким UI-компонентам:

  • не требует WebGL;
  • не перерисовывает слой карты;
  • работает только с DOM;
  • реагирует только на изменения view.

Это делает его практически бесплатным по производительности даже при частых зумах.


Ограничения модели масштаба

Несмотря на точность, ScaleLine имеет ограничения:

  • в высоких широтах Web Mercator даёт искажения;
  • на глобальных масштабах линейка становится приблизительной;
  • при нестандартных проекциях требуется осторожность в интерпретации.

В таких случаях линейка служит ориентиром, а не метрологическим инструментом.


Интеграция с другими контролами

ScaleLine часто комбинируется с:

  • Zoom контролом;
  • MousePosition;
  • OverviewMap;
  • FullScreen контролом.

Так формируется полноценная навигационная панель карты.


Поведение при анимации карты

При плавном изменении zoom или center ScaleLine обновляется синхронно с анимацией view. Обновление происходит на каждом кадре, но оптимизируется внутренним throttling-механизмом, чтобы избежать избыточных перерасчётов.


Пользовательские сценарии расширения

Расширение поведения возможно через наследование:

class CustomScaleLine extends ScaleLine {
  constructor(options) {
    super(options);
  }

  render() {
    super.render();
    // дополнительная логика
  }
}

Такая модель используется для добавления нестандартных подписей или логирования масштабов.


Взаимодействие с view resolution

ScaleLine напрямую зависит от:

  • resolution — ключевой параметр масштаба;
  • projection — система координат;
  • dpi устройства.

Любое изменение resolution автоматически инициирует перерасчёт длины шкалы, что делает компонент полностью реактивным относительно состояния карты.