В OpenLayers объект View представляет состояние
отображения карты. Именно он определяет, какую часть географического
пространства видит пользователь в текущий момент времени, на каком
уровне масштабирования находится карта и под каким углом она
повернута.
Архитектурно View отделён от объекта карты
(Map). Карта отвечает за отображение слоёв и взаимодействие
с пользователем, а View хранит параметры отображения
пространства координат.
Наиболее важные характеристики объекта View:
center);zoom);resolution);rotation);Схематически взаимодействие выглядит следующим образом:
Map
├── Layers
├── Controls
├── Interactions
└── View
├── Center
├── Zoom
├── Resolution
└── Rotation
Без объекта View карта не может определить, какой
участок данных необходимо отображать.
Обычно объект создаётся одновременно с картой.
import Map from 'ol/Map';
import View from 'ol/View';
const map = new Map({
target: 'map',
view: new View({
center: [0, 0],
zoom: 3
})
});
Здесь задаются два основных параметра:
center — координаты центра карты;zoom — начальный уровень масштабирования.Центр определяет координаты точки, которая будет находиться в середине окна карты.
const view = new View({
center: [4180000, 7500000],
zoom: 5
});
Получение текущего центра:
const center = view.getCenter();
console.log(center);
Изменение центра:
view.setCenter([5000000, 7000000]);
После вызова метода карта автоматически перерисуется.
По умолчанию OpenLayers использует проекцию Web Mercator
(EPSG:3857).
Поэтому координаты центра обычно задаются не в градусах широты и долготы, а в метрах.
Для преобразования координат применяется функция
fromLonLat.
import { fromLonLat } from 'ol/proj';
const view = new View({
center: fromLonLat([37.6176, 55.7558]),
zoom: 10
});
Здесь:
После преобразования карта будет центрирована на Москве.
Параметр zoom определяет уровень детализации.
const view = new View({
center: [0, 0],
zoom: 4
});
Получение текущего масштаба:
const zoom = view.getZoom();
Установка нового масштаба:
view.setZoom(8);
Увеличение масштаба:
view.setZoom(view.getZoom() + 1);
Уменьшение масштаба:
view.setZoom(view.getZoom() - 1);
Чем больше значение масштаба, тем ближе отображается карта.
Примерная зависимость:
| Zoom | Масштаб |
|---|---|
| 0 | Весь мир |
| 3 | Континенты |
| 6 | Страны |
| 10 | Города |
| 15 | Районы |
| 18+ | Улицы и здания |
Внутри OpenLayers основным параметром отображения является не
масштаб, а разрешение (resolution).
Разрешение показывает количество метров на пиксель.
Например:
const resolution = view.getResolution();
Установка разрешения:
view.setResolution(500);
Чем меньше значение разрешения:
Связь между масштабом и разрешением вычисляется автоматически.
Поэтому разработчики чаще работают через zoom, а
OpenLayers преобразует его в resolution.
Объект View поддерживает вращение карты.
Поворот задаётся в радианах.
const view = new View({
center: [0, 0],
zoom: 5,
rotation: Math.PI / 4
});
Здесь карта повернётся на 45 градусов.
Получение текущего угла:
const rotation = view.getRotation();
Изменение угла:
view.setRotation(Math.PI / 2);
Сброс поворота:
view.setRotation(0);
Во многих приложениях необходимо запретить слишком сильное увеличение или уменьшение.
Для этого используются параметры:
const view = new View({
center: [0, 0],
zoom: 5,
minZoom: 2,
maxZoom: 18
});
Теперь:
Такие ограничения часто применяются при работе с собственными тайловыми слоями.
Вместо масштаба можно ограничивать разрешение.
const view = new View({
center: [0, 0],
minResolution: 5,
maxResolution: 10000
});
Подобный подход используется в специализированных ГИС-приложениях, где требуется точный контроль отображения.
Иногда требуется запретить перемещение карты за пределы определённого региона.
Для этого используется параметр extent.
const view = new View({
center: [0, 0],
zoom: 5,
extent: [
-5000000,
-5000000,
5000000,
5000000
]
});
Структура массива:
[minX, minY, maxX, maxY]
Пользователь не сможет прокручивать карту за границы указанного прямоугольника.
Объект предоставляет методы доступа ко всем ключевым параметрам.
const center = view.getCenter();
const zoom = view.getZoom();
const resolution = view.getResolution();
const rotation = view.getRotation();
Пример:
console.log({
center: view.getCenter(),
zoom: view.getZoom(),
rotation: view.getRotation()
});
Подобная информация часто используется для сохранения пользовательского состояния интерфейса.
Простейший способ изменить отображение — установить новый центр.
view.setCenter(
fromLonLat([30.3141, 59.9386])
);
После выполнения карта переместится к Санкт-Петербургу.
Одновременно можно изменить масштаб.
view.setCenter(
fromLonLat([30.3141, 59.9386])
);
view.setZoom(12);
Метод fit() автоматически подбирает центр и масштаб
таким образом, чтобы заданная область полностью поместилась на
экране.
view.fit([
4000000,
7000000,
5000000,
8000000
]);
После вызова:
Обычно метод используется вместе с геометриями.
const extent = feature
.getGeometry()
.getExtent();
view.fit(extent);
Если объект находится далеко от текущей области просмотра, карта автоматически переместится к нему.
Для предотвращения прилипания объекта к краям окна используются внутренние отступы.
view.fit(extent, {
padding: [50, 50, 50, 50]
});
Порядок значений:
[top, right, bottom, left]
Метод animate() позволяет плавно изменять параметры
отображения.
Пример плавного перемещения:
view.animate({
center: fromLonLat([37.6176, 55.7558]),
duration: 2000
});
Карта переместится в течение двух секунд.
view.animate({
zoom: 12,
duration: 1500
});
Переход будет происходить плавно.
view.animate({
center: fromLonLat([37.6176, 55.7558]),
zoom: 10,
rotation: Math.PI / 6,
duration: 3000
});
Изменяются сразу:
Метод позволяет создавать цепочки переходов.
view.animate(
{
zoom: 5,
duration: 1000
},
{
center: fromLonLat([37.6176, 55.7558]),
duration: 1000
},
{
zoom: 12,
duration: 1000
}
);
Последовательность будет следующей:
Такой эффект часто используется для навигации между объектами.
Если объект создавался внутри карты, получить его можно через метод
getView().
const view = map.getView();
После этого становятся доступны все методы управления отображением.
view.setZoom(10);
view.setCenter(
fromLonLat([37.6176, 55.7558])
);
Объект View генерирует события изменения параметров.
Отслеживание масштаба:
view.on('change:resolution', () => {
console.log(view.getZoom());
});
Отслеживание центра:
view.on('change:center', () => {
console.log(view.getCenter());
});
Отслеживание поворота:
view.on('change:rotation', () => {
console.log(view.getRotation());
});
Такие обработчики используются для синхронизации карты с пользовательским интерфейсом.
Частая задача — сохранять текущую позицию карты между сеансами работы.
view.on('change:center', saveState);
view.on('change:resolution', saveState);
function saveState() {
localStorage.setItem(
'mapState',
JSON.stringify({
center: view.getCenter(),
zoom: view.getZoom()
})
);
}
Восстановление состояния:
const state = JSON.parse(
localStorage.getItem('mapState')
);
if (state) {
view.setCenter(state.center);
view.setZoom(state.zoom);
}
Наиболее востребованные методы:
| Метод | Назначение |
|---|---|
getCenter() |
Получение центра |
setCenter() |
Установка центра |
getZoom() |
Получение масштаба |
setZoom() |
Установка масштаба |
getResolution() |
Получение разрешения |
setResolution() |
Установка разрешения |
getRotation() |
Получение угла поворота |
setRotation() |
Установка угла поворота |
fit() |
Подгонка области под экран |
animate() |
Плавное изменение параметров |
calculateExtent() |
Получение текущей видимой области |
Иногда требуется узнать координаты участка карты, который отображается в текущий момент.
const extent = view.calculateExtent(
map.getSize()
);
console.log(extent);
Результат:
[
minX,
minY,
maxX,
maxY
]
Эти данные используются для:
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import { fromLonLat } from 'ol/proj';
const view = new View({
center: fromLonLat([37.6176, 55.7558]),
zoom: 8,
minZoom: 3,
maxZoom: 18
});
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: view
});
document
.getElementById('zoomIn')
.addEventListener('click', () => {
view.setZoom(
view.getZoom() + 1
);
});
document
.getElementById('zoomOut')
.addEventListener('click', () => {
view.setZoom(
view.getZoom() - 1
);
});
document
.getElementById('goToMoscow')
.addEventListener('click', () => {
view.animate({
center: fromLonLat([37.6176, 55.7558]),
zoom: 12,
duration: 2000
});
});
Данный пример демонстрирует основные возможности объекта
View: