Fill

В Mapbox GL JS слой типа fill предназначен для визуализации полигональных геометрий: областей, административных границ, водных объектов, земельных участков и любых других сущностей, представленных замкнутыми контурами в источнике данных. Основная задача этого слоя — заливка внутренней области полигона цветом, градиентом или текстурой с управляемыми параметрами прозрачности, обводки и поведения при масштабировании карты.

Fill-слой всегда привязывается к источнику данных через source и опционально через source-layer (в случае векторных тайлов). Чаще всего используется источник типа GeoJSON, где каждая feature содержит геометрию Polygon или MultiPolygon.

map.addSource('regions', {
  type: 'geojson',
  data: '/data/regions.geojson'
});

map.addLayer({
  id: 'regions-fill',
  type: 'fill',
  source: 'regions'
});

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

Ключевые свойства fill-слоя

Fill-слой управляется преимущественно через блок paint, который отвечает за визуальное отображение:

  • fill-color
  • fill-opacity
  • fill-outline-color
  • fill-pattern
  • fill-translate
  • fill-translate-anchor
  • fill-antialias

Каждое из этих свойств влияет на поведение отрисовки в WebGL и может быть динамически связано с данными.


fill-color: базовая заливка и выражения

fill-color задаёт основной цвет полигона. Поддерживаются статические значения и выражения (expressions), включая интерполяцию по зуму и данным.

map.addLayer({
  id: 'regions-fill',
  type: 'fill',
  source: 'regions',
  paint: {
    'fill-color': '#2ecc71'
  }
});

Более сложный вариант использует данные GeoJSON:

'fill-color': [
  'match',
  ['get', 'type'],
  'forest', '#27ae60',
  'water', '#3498db',
  'urban', '#95a5a6',
  '#cccccc'
]

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


fill-opacity: управление прозрачностью

fill-opacity определяет степень прозрачности заливки. Это важный параметр при наложении нескольких слоёв.

paint: {
  'fill-color': '#e74c3c',
  'fill-opacity': 0.5
}

Допустимо использование интерполяции по масштабу:

'fill-opacity': [
  'interpolate',
  ['linear'],
  ['zoom'],
  5, 0.2,
  10, 0.6
]

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


fill-outline-color: контуры полигонов

fill-outline-color задаёт цвет границы полигона, не требуя отдельного line-слоя. Это упрощает структуру карты при базовых сценариях визуализации.

paint: {
  'fill-color': '#1abc9c',
  'fill-outline-color': '#2c3e50'
}

Однако важно учитывать ограничение: fill-outline-color рисуется только для границ отдельных features и не заменяет полноценный line-слой при сложной стилизации контуров.


fill-pattern: текстурирование полигонов

fill-pattern позволяет использовать изображения из спрайтового атласа вместо однотонной заливки.

map.addImage('diagonal-stripes', image);

map.addLayer({
  id: 'regions-fill',
  type: 'fill',
  source: 'regions',
  paint: {
    'fill-pattern': 'diagonal-stripes'
  }
});

Это применяется для:

  • штриховки зон ограничений
  • визуализации категорий с текстурой
  • имитации материалов (например, лес, вода, промышленная зона)

fill-translate и fill-translate-anchor

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

paint: {
  'fill-color': '#8e44ad',
  'fill-translate': [10, 10],
  'fill-translate-anchor': 'map'
}

Возможны два режима привязки:

  • map — смещение относительно карты
  • viewport — смещение относительно экрана

Это используется для эффектов тени, псевдо-3D и выделения активных областей.


fill-antialias: сглаживание границ

fill-antialias управляет сглаживанием краёв полигонов. При значении true WebGL выполняет дополнительную обработку для уменьшения «лесенок» на диагональных границах.

paint: {
  'fill-color': '#16a085',
  'fill-antialias': true
}

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


Данные и фильтрация fill-слоёв

Fill-слои часто работают с фильтрами на уровне feature-state или свойств GeoJSON.

filter: ['==', ['get', 'region'], 'europe']

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

map.setFeatureState(
  { source: 'regions', id: 12 },
  { selected: true }
);

И использование в стиле:

'fill-color': [
  'case',
  ['boolean', ['feature-state', 'selected'], false],
  '#f1c40f',
  '#bdc3c7'
]

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


Взаимодействие с событиями карты

Fill-слои активно используются вместе с событиями:

  • click
  • mousemove
  • mouseenter
  • mouseleave
map.on('mousemove', 'regions-fill', (e) => {
  map.getCanvas().style.cursor = 'pointer';
});

Получение данных объекта:

map.on('click', 'regions-fill', (e) => {
  const feature = e.features[0];
  console.log(feature.properties);
});

Для корректной работы необходимо убедиться, что слой является интерактивным и поддерживает picking в WebGL.


Слои fill и порядок отрисовки

Порядок добавления слоя влияет на визуальную иерархию. Fill-слои обычно размещаются под line и symbol слоями.

Типичная структура:

  1. background
  2. fill (полигоны)
  3. line (границы)
  4. symbol (подписи)
map.addLayer(fillLayer, 'waterway-label');

Вставка перед конкретным слоем позволяет точно контролировать рендеринг.


Производительность и оптимизация fill-слоёв

При работе с большим количеством полигонов ключевыми становятся следующие факторы:

  • упрощение геометрии (simplification)
  • использование vector tiles вместо GeoJSON
  • ограничение фильтрами отображаемого набора данных
  • минимизация выражений в paint-параметрах
  • кеширование источников

GeoJSON с десятками тысяч вершин может существенно замедлить рендеринг, поэтому в продакшн-сценариях предпочтение отдаётся тайловым источникам.


Динамическое обновление стилей fill

Fill-слой можно обновлять без пересоздания:

map.setPaintProperty('regions-fill', 'fill-color', '#9b59b6');

Или переключать режим отображения:

map.setPaintProperty('regions-fill', 'fill-opacity', 0.3);

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


Сложные выражения и data-driven styling

Fill-слои поддерживают полноценную систему выражений Mapbox Style Specification:

'fill-color': [
  'interpolate',
  ['linear'],
  ['get', 'population'],
  0, '#2ecc71',
  1000000, '#f1c40f',
  10000000, '#e74c3c'
]

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


Взаимодействие fill с другими слоями

Fill-слой часто используется совместно с line-слоем для усиления читаемости границ:

map.addLayer({
  id: 'regions-line',
  type: 'line',
  source: 'regions',
  paint: {
    'line-color': '#2c3e50',
    'line-width': 1
  }
});

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


Особенности рендеринга WebGL

Fill-слои в Mapbox GL JS рендерятся через WebGL-пайплайн. Каждый полигон триангулируется, после чего преобразуется в набор треугольников. Это означает:

  • сложные полигоны увеличивают нагрузку на GPU
  • пересечения и дырки обрабатываются на этапе триангуляции
  • качество геометрии напрямую влияет на производительность

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


Использование feature-state для интерактивной аналитики

Feature-state позволяет отделить данные от стиля, создавая реактивные визуализации:

'fill-color': [
  'case',
  ['==', ['feature-state', 'hover'], true],
  '#ffcc00',
  '#3498db'
]

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


Комбинирование fill-pattern и opacity

При использовании текстур fill-pattern прозрачность влияет на восприятие паттерна:

paint: {
  'fill-pattern': 'pattern-image',
  'fill-opacity': 0.7
}

Это позволяет создавать гибридные визуализации, где текстура и цвет работают совместно, а не конкурируют визуально.