Регистрация кастомных проекций

В основе работы картографических приложений лежит преобразование координат между различными системами координат. OpenLayers оперирует проекциями через модуль ol/proj, предоставляя механизм регистрации стандартных и пользовательских систем координат, включая интеграцию с библиотекой proj4.

Проекция в OpenLayers описывает способ преобразования географических координат (долгота/широта) в координаты карты (пиксели или условные единицы) и обратно. Для большинства веб-карт используется EPSG:3857, однако при работе с локальными системами координат, инженерными данными или нестандартными датасетами требуется регистрация пользовательских проекций.


Базовая архитектура проекций

В OpenLayers каждая проекция описывается объектом, содержащим:

  • идентификатор (обычно EPSG-код),
  • единицы измерения,
  • диапазон допустимых координат (extent),
  • параметры мира (world extent),
  • трансформации координат,
  • дополнительные метаданные.

Ключевой модуль:

import Projection from 'ol/proj/Projection';
import { addProjection, addCoordinateTransforms } from 'ol/proj';

Интеграция с proj4

Большинство нестандартных систем координат описывается через proj4-строки. OpenLayers поддерживает автоматическую регистрацию через proj4.

import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';

Регистрация выполняется один раз на уровне приложения:

proj4.defs("EPSG:2154",
  "+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 " +
  "+lon_0=3 +x_0=700000 +y_0=6600000 " +
  "+ellps=GRS80 +units=m +no_defs"
);

register(proj4);

После регистрации OpenLayers автоматически распознаёт EPSG-код и может выполнять трансформации координат.


Создание пользовательской проекции

Когда требуется полный контроль над поведением системы координат, используется явное создание объекта Projection.

import Projection from 'ol/proj/Projection';
import { addProjection } from 'ol/proj';

const customProjection = new Projection({
  code: 'CUSTOM:1001',
  units: 'm',
  extent: [0, 0, 1000000, 1000000]
});

addProjection(customProjection);

Ключевые параметры

code

  • уникальный идентификатор
  • может быть EPSG или произвольным кодом

units

  • degrees
  • m (метры)
  • pixels
  • tile-pixels

extent

  • ограничение рабочей области карты
  • критично для корректного отображения тайлов

Определение границ (extent)

Extent определяет допустимую область координат. Без корректного extent карта может:

  • «уезжать» за пределы мира,
  • некорректно масштабироваться,
  • неправильно рассчитывать тайлы.

Пример:

const projection = new Projection({
  code: 'LOCAL:2000',
  units: 'm',
  extent: [300000, 6000000, 400000, 6100000]
});

Extent должен соответствовать реальной системе координат источника данных.


Добавление пользовательских трансформаций координат

Если требуется не просто зарегистрировать проекцию, а полностью контролировать преобразование координат, используется:

import { addCoordinateTransforms } from 'ol/proj';

Прямое и обратное преобразование

addCoordinateTransforms(
  'EPSG:4326',
  'CUSTOM:1001',
  function (coordinate) {
    return [
      coordinate[0] * 1000,
      coordinate[1] * 1000
    ];
  },
  function (coordinate) {
    return [
      coordinate[0] / 1000,
      coordinate[1] / 1000
    ];
  }
);

Такая схема используется в случаях:

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

Регистрация EPSG через proj4 и OpenLayers

Типовой сценарий для EPSG-кодов:

import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';

proj4.defs("EPSG:32637",
  "+proj=utm +zone=37 +datum=WGS84 +units=m +no_defs"
);

register(proj4);

После регистрации система может использовать:

import { fromLonLat } from 'ol/proj';

const coord = fromLonLat([69.2401, 41.2995], 'EPSG:32637');

Использование проекции в карте

Проекция задаётся на уровне View:

import View from 'ol/View';

const view = new View({
  projection: 'EPSG:3857',
  center: [0, 0],
  zoom: 2
});

Для пользовательской проекции:

const view = new View({
  projection: 'CUSTOM:1001',
  center: [500000, 500000],
  zoom: 3
});

Особенности работы с тайлами

При использовании кастомных проекций критично учитывать:

1. Согласование с tile grid

Тайловая сетка должна соответствовать системе координат:

import TileGrid from 'ol/tilegrid/TileGrid';

const tileGrid = new TileGrid({
  extent: [0, 0, 1000000, 1000000],
  resolutions: [1000, 500, 250, 125]
});

2. Совпадение origin

Неверный origin приводит к смещению тайлов:

origin: [0, 0]

Axis orientation и особенности EPSG

Некоторые EPSG-коды используют нестандартную ориентацию осей (lat/lon вместо lon/lat). OpenLayers учитывает это автоматически при наличии корректного определения proj4.

При ручной регистрации важно:

  • проверять порядок координат,
  • избегать ручного swap без необходимости,
  • использовать proj4 как источник истины.

Множественные проекции в одном приложении

OpenLayers поддерживает одновременное использование нескольких систем координат.

Типовой сценарий:

  • карта отображается в EPSG:3857,
  • данные приходят в EPSG:4326,
  • локальные слои используют EPSG:32637.

Преобразование выполняется автоматически:

import { transform } from 'ol/proj';

const result = transform(
  [69.2401, 41.2995],
  'EPSG:4326',
  'EPSG:3857'
);

Частые ошибки при регистрации проекций

Отсутствие extent

Без extent OpenLayers не может корректно вычислить границы карты.

Несоответствие units

Метры вместо градусов приводят к:

  • неверному масштабированию,
  • смещению слоёв,
  • неправильной работе zoom levels.

Неполная регистрация proj4

Если register(proj4) не вызван, EPSG-код не будет распознан.


Практическая модель построения кастомной проекции

Типовой алгоритм:

  1. Определение CRS (proj4 строка)
  2. Регистрация через proj4.defs
  3. Вызов register(proj4)
  4. Проверка доступности EPSG-кода
  5. Создание View с нужной проекцией
  6. Настройка extent и tile grid
  7. При необходимости — добавление addCoordinateTransforms

Согласование источников данных и проекции карты

Корректная работа достигается только при согласовании:

  • WMS/WMTS сервера,
  • векторных данных,
  • клиентской проекции,
  • tile grid,
  • extent.

Любое несоответствие приводит к визуальным артефактам: смещению слоёв, разрывам тайлов или некорректному масштабированию.