Частые ошибки и их решения

Одна из наиболее частых проблем связана с несовпадением систем координат. В OpenLayers базовая веб-карта работает в проекции EPSG:3857 (Web Mercator), тогда как большинство геоданных приходит в EPSG:4326 (WGS84).

Типичная ошибка проявляется в виде «пустой карты» или объектов, смещённых на тысячи километров.

Основные симптомы:

  • координаты выглядят корректными, но объекты не отображаются;
  • маркеры появляются «в океане»;
  • GeoJSON загружается, но находится вне области видимости.

Ключевой источник проблемы — отсутствие преобразования координат:

import { fromLonLat, transform } from 'ol/proj';

// неправильно (4326 напрямую в карту)
const point = [55.75, 37.61];

// правильно
const point = fromLonLat([37.61, 55.75]);

Для GeoJSON критично учитывать dataProjection и featureProjection:

import GeoJSON from 'ol/format/GeoJSON';

const format = new GeoJSON();

const features = format.readFeatures(data, {
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

Проблемы с отображением слоёв

Частая ситуация — слой создан, но не отображается.

Основные причины:

  • слой не добавлен в карту;
  • источник (source) не загружает данные;
  • неверный порядок слоёв;
  • прозрачность или стиль делают слой «невидимым».

Проверка базовой структуры:

const layer = new TileLayer({
  source: new OSM()
});

const map = new Map({
  target: 'map',
  layers: [layer],
  view: new View({
    center: [0, 0],
    zoom: 2
  })
});

Если слой векторный и пустой, проблема часто в источнике:

const vector = new VectorSource({
  url: 'data.geojson',
  format: new GeoJSON()
});

Ошибки загрузки GeoJSON часто связаны с CORS или неверным форматом данных.


Ошибки CORS и загрузки тайлов

При использовании внешних WMS/XYZ/WMTS источников часто возникает блокировка браузером.

Симптомы:

  • в консоли ошибки CORS;
  • тайлы не загружаются;
  • белая сетка вместо карты.

Причины:

  • сервер не отдаёт заголовок Access-Control-Allow-Origin;
  • используется HTTP вместо HTTPS;
  • неправильный URL шаблон тайлов.

Пример корректного XYZ слоя:

new TileLayer({
  source: new XYZ({
    url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
  })
});

Если сервер не поддерживает CORS, требуется прокси, иначе OpenLayers не сможет получить данные.


Некорректная настройка View и центрирования

Ошибки центра карты приводят к «пустому экрану».

Типичные причины:

  • центр задан в неправильной проекции;
  • используется [lon, lat] без преобразования;
  • слишком большой или слишком маленький zoom;
  • extent не соответствует данным.

Ошибочный вариант:

view: new View({
  center: [55.75, 37.61],
  zoom: 10
});

Правильный:

view: new View({
  center: fromLonLat([37.61, 55.75]),
  zoom: 10
});

Ошибки работы с GeoJSON и Feature

GeoJSON может быть валидным по JSON, но не подходить OpenLayers.

Типичные проблемы:

  • перепутаны coordinates;
  • отсутствует type: "Feature" или FeatureCollection;
  • неправильный порядок координат [lat, lon] вместо [lon, lat];
  • геометрии null или пустые массивы.

Пример корректной структуры:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [37.61, 55.75]
  },
  "properties": {}
}

Частая ошибка — ручное создание объектов без учета спецификации OpenLayers:

new Feature({
  geometry: new Point([37.61, 55.75]) // ошибка без transform
});

Проблемы со стилями (Style Function)

Стили в OpenLayers часто становятся источником неожиданных эффектов.

Основные ошибки:

  • функция стиля возвращает undefined;
  • стиль пересоздаётся на каждый рендер без кэширования;
  • не учитывается масштаб;
  • используется неправильный fill/stroke.

Ошибка:

style: function () {
  if (condition) {
    return new Style({ ... });
  }
  // ничего не возвращается
}

Правильно:

style: function () {
  return new Style({
    stroke: new Stroke({
      color: 'blue',
      width: 2
    })
  });
}

Для производительности стиль лучше кэшировать, иначе при большом количестве объектов начинается деградация FPS.


Проблемы с перерисовкой и обновлением источников

VectorSource не всегда автоматически обновляет отображение.

Симптомы:

  • данные добавлены, но не отображаются;
  • изменения геометрии не видны;
  • кластеризация не пересчитывается.

Причины:

  • не вызван changed();
  • используется modify без обновления source;
  • асинхронная загрузка не завершена.

Принудительное обновление:

vectorSource.addFeature(feature);
vectorSource.changed();

Ошибки взаимодействий (Interactions)

Конфликты между взаимодействиями приводят к «сломанных» жестов карты.

Типичные ситуации:

  • одновременно включены Draw и Select;
  • DoubleClickZoom мешает редактированию;
  • DragPan конфликтует с кастомными обработчиками.

Пример отключения:

map.getInteractions().forEach(function (interaction) {
  if (interaction instanceof DoubleClickZoom) {
    interaction.setActive(false);
  }
});

Проблемы с fit() и extent

Метод fit() часто используется неправильно.

Ошибки:

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

Неправильный вариант:

map.getView().fit([]);

Правильный:

map.getView().fit(vectorSource.getExtent(), {
  padding: [50, 50, 50, 50],
  maxZoom: 12
});

Ошибки производительности при большом количестве объектов

При тысячах объектов карта начинает тормозить.

Причины:

  • слишком сложные стили;
  • отсутствие кластеризации;
  • частые вызовы setStyle;
  • неиспользование WebGL слоёв.

Кластеризация как решение:

import Cluster from 'ol/source/Cluster';

const clusterSource = new Cluster({
  distance: 40,
  source: vectorSource
});

Ошибки работы с размерами контейнера

OpenLayers не всегда автоматически реагирует на изменение размера контейнера.

Симптом:

  • карта отображается частично;
  • серый фон вместо тайлов;
  • смещение элементов управления.

Решение связано с вызовом обновления размера:

map.updateSize();

Особенно важно при:

  • открытии модальных окон;
  • изменении flex/grid layout;
  • динамической загрузке интерфейса.

Ошибки порядка слоёв и zIndex

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

Причины:

  • отсутствие zIndex;
  • добавление слоёв в неправильном порядке;
  • прозрачные слои перекрывают базовую карту.

Пример управления:

layer.setZIndex(10);
baseLayer.setZIndex(0);

Ошибки WMTS и сложных источников

WMTS часто требует строгой конфигурации.

Типичные ошибки:

  • неверный matrixSet;
  • неправильный tileGrid;
  • несоответствие проекции сервера и клиента.

Симптом:

  • тайлы загружаются частично;
  • сетка смещена;
  • пустые области при зуме.

Утечки памяти и накопление слушателей событий

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

Проблемы:

  • рост потребления памяти;
  • дублирование событий;
  • замедление интерфейса.

Ошибка:

map.on('click', handler);
// без unByKey или un

Правильный подход:

import { unByKey } from 'ol/Observable';

const key = map.on('click', handler);
unByKey(key);