Draw point, line, polygon

Mapbox GL JS предоставляет мощный механизм интерактивного рисования геометрических объектов на карте через дополнительный модуль Mapbox GL Draw. Он позволяет создавать, редактировать и удалять точки, линии и полигоны, а также работать с результатами в формате GeoJSON.

Для работы с графическими примитивами требуется подключение двух библиотек: ядра карты и инструмента рисования.

<link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>

<link href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.js"></script>

Инициализация карты выполняется стандартным способом:

mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN';

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [37.6173, 55.7558],
  zoom: 10
});

Подключение инструмента рисования

Mapbox GL Draw добавляется как контрол к карте:

const draw = new MapboxDraw({
  displayControlsDefault: false,
  controls: {
    point: true,
    line_string: true,
    polygon: true,
    trash: true
  }
});

map.addControl(draw);

Контрол формирует панель инструментов, позволяющую переключаться между режимами создания геометрии и удалением объектов.

Режимы рисования

Точка (Point)

Режим точек используется для фиксации одиночных координатных объектов.

draw.changeMode('draw_point');

Точка представляется GeoJSON-объектом:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [37.6173, 55.7558]
  }
}

Типичные сценарии:

  • отметки объектов на карте
  • маркеры событий
  • пользовательские геопозиции

Линия (LineString)

Линейная геометрия используется для построения маршрутов, дорог и траекторий.

draw.changeMode('draw_line_string');

GeoJSON представление:

{
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [
      [37.6173, 55.7558],
      [37.6250, 55.7600]
    ]
  }
}

Ключевые особенности:

  • динамическое добавление вершин
  • автоматическое обновление геометрии при редактировании
  • поддержка произвольного количества точек

Полигон (Polygon)

Полигональная геометрия используется для описания областей.

draw.changeMode('draw_polygon');

GeoJSON структура:

{
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [37.6173, 55.7558],
        [37.6250, 55.7600],
        [37.6300, 55.7500],
        [37.6173, 55.7558]
      ]
    ]
  }
}

Особенности полигонов:

  • замыкание контура происходит автоматически
  • поддержка внутренних колец (holes)
  • вычисление площади возможно через сторонние библиотеки

Управление данными Draw

Все созданные объекты хранятся внутри внутреннего состояния Mapbox GL Draw и доступны через API:

const data = draw.getAll();

Удаление всех объектов:

draw.deleteAll();

Удаление по идентификатору:

draw.delete('feature-id');

Обновление объекта:

draw.add({
  id: 'custom-id',
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [37.6173, 55.7558]
  }
});

События рисования

Mapbox GL Draw генерирует набор событий для отслеживания изменений состояния:

создание объекта

map.on('draw.create', (e) => {
  const features = e.features;
});

обновление объекта

map.on('draw.update', (e) => {
  const updated = e.features;
});

удаление объекта

map.on('draw.delete', (e) => {
  const removed = e.features;
});

выбор объекта

map.on('draw.selectionchange', (e) => {
  const selected = e.features;
});

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

Ограничение типов геометрии

В ряде случаев требуется ограничить набор доступных инструментов:

const draw = new MapboxDraw({
  controls: {
    point: true,
    line_string: false,
    polygon: true,
    trash: true
  }
});

Это позволяет адаптировать интерфейс под конкретную задачу, например сбор точек без построения линий.

Редактирование геометрии

Редактирование активируется автоматически после выбора объекта. Возможности включают:

  • перемещение вершин
  • добавление новых узлов на линии
  • изменение формы полигона
  • удаление отдельных точек структуры

Программное переключение режима:

draw.changeMode('direct_select', { featureId: 'id' });

Работа с GeoJSON

Mapbox GL Draw полностью основан на спецификации GeoJSON, что обеспечивает совместимость с GIS-системами и аналитическими библиотеками.

Получение всех данных:

const geojson = draw.getAll();

Пример интеграции с внешним API:

fetch('/api/save', {
  method: 'POST',
  body: JSON.stringify(draw.getAll()),
  headers: {
    'Content-Type': 'application/json'
  }
});

Кастомизация стилей объектов

Отображение геометрии можно изменить через стили Mapbox:

map.addLayer({
  id: 'custom-points',
  type: 'circle',
  source: 'mapbox-gl-draw-cold',
  paint: {
    'circle-radius': 6,
    'circle-color': '#ff0000'
  }
});

Возможна настройка:

  • цвета линий
  • толщины обводки
  • заливки полигонов
  • поведения hover-состояний

Ограничение области рисования

Для контроля допустимой зоны используется проверка координат при создании объектов:

map.on('draw.create', (e) => {
  const feature = e.features[0];
  const coords = feature.geometry.coordinates;
});

Дополнительно возможно использовать Turf.js для пространственных проверок, например попадания в границы полигона.

Интеграция с внешними библиотеками

Mapbox GL Draw часто используется совместно с:

  • Turf.js для геоаналитики
  • Redux или Vuex для хранения состояния
  • Backend GIS системами

Пример вычисления длины линии:

const line = draw.getAll().features[0];
const length = turf.length(line, { units: 'kilometers' });

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

При работе с сотнями и тысячами геометрий критично учитывать:

  • частоту обновления состояния карты
  • использование simplification алгоритмов
  • минимизацию вызовов draw.getAll()
  • разделение слоёв отображения

Оптимизация линий:

const simplified = turf.simplify(feature, { tolerance: 0.001 });

Многослойное редактирование

В сложных сценариях рисование комбинируется с несколькими слоями:

  • слой отображения
  • слой редактирования
  • слой предварительного просмотра

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