GeoJSON Feature — базовая единица данных, используемая в веб-картографии и являющаяся фундаментом для работы с векторными слоями в MapLibre GL JS. В рамках спецификации GeoJSON каждый объект карты представляется как отдельная сущность с геометрией и набором свойств, которые могут быть интерпретированы стилями слоёв, фильтрами и интерактивными обработчиками.
Feature представляет собой объект, который объединяет геометрические данные и атрибутивную информацию. В MapLibre GL JS он используется для описания конкретных объектов на карте: точек, линий, полигонов и их вариаций.
Базовая структура Feature:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [30.31413, 59.93863]
},
"properties": {
"name": "Объект",
"category": "example"
}
}
Поле geometry определяет пространственную форму объекта.
Поддерживаются основные типы:
Геометрия является обязательной частью Feature, за исключением случая
null, который используется для временно отсутствующих или
скрытых объектов.
Поле properties содержит произвольные данные, которые не
влияют на геометрию, но активно используются в визуализации и
логике:
{
"properties": {
"id": 42,
"name": "Парк",
"population": 12000,
"visible": true
}
}
В MapLibre GL JS эти данные применяются:
FeatureCollection — это контейнер, объединяющий множество Feature в единый объект GeoJSON. Он является основным форматом передачи данных в источники MapLibre.
Структура:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [30.1, 59.9]
},
"properties": {
"id": 1,
"label": "A"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [30.2, 59.8]
},
"properties": {
"id": 2,
"label": "B"
}
}
]
}
FeatureCollection используется как основной формат для
GeoJSONSource, обеспечивая динамическое обновление данных
на карте.
GeoJSON источник подключается через addSource:
map.addSource('points-source', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
});
Обновление данных выполняется через setData:
map.getSource('points-source').setData(featureCollection);
Это позволяет динамически изменять отображаемые объекты без пересоздания слоя.
Feature напрямую не отображается на карте — он становится видимым только через слой (layer). Слой определяет:
Пример слоя:
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points-source',
paint: {
'circle-radius': 6,
'circle-color': '#ff0000'
}
});
Каждый Feature в FeatureCollection проходит через слой и отображается согласно его стилю.
Одной из ключевых возможностей является фильтрация объектов на основе их свойств:
map.addLayer({
id: 'filtered-layer',
type: 'circle',
source: 'points-source',
filter: ['==', ['get', 'category'], 'park'],
paint: {
'circle-color': '#00aa00'
}
});
Фильтры позволяют выделять подмножества Feature без изменения исходного источника данных.
MapLibre GL JS предоставляет механизм feature-state,
позволяющий хранить временное состояние объекта независимо от
GeoJSON:
map.setFeatureState(
{ source: 'points-source', id: 1 },
{ hover: true }
);
В стилях это состояние используется через выражения:
'circle-color': [
'case',
['boolean', ['feature-state', 'hover'], false],
'#ff0000',
'#0000ff'
]
FeatureState применяется для интерактивных сценариев:
Для работы с состояниями и обновлениями каждому Feature может быть
назначено уникальное поле id:
{
"type": "Feature",
"id": 10,
"geometry": {
"type": "Point",
"coordinates": [30, 60]
},
"properties": {}
}
Наличие id позволяет:
GeoJSON источник в MapLibre не является иммутабельным. Полная замена
данных происходит через setData, что требует передачи новой
FeatureCollection:
const updated = {
type: 'FeatureCollection',
features: [
...oldFeatures,
newFeature
]
};
source.setData(updated);
Это приводит к полной перерасчётке отображения слоя, что важно учитывать при работе с большими массивами данных.
MapLibre GL JS позволяет извлекать Feature, уже отрендеренные на карте:
const features = map.queryRenderedFeatures(point, {
layers: ['points-layer']
});
или по геометрической области:
const features = map.queryRenderedFeatures(bbox, {
layers: ['points-layer']
});
Результатом являются объекты Feature, обогащённые информацией о визуализации.
Feature активно участвует в обработке событий карты:
map.on('click', 'points-layer', (e) => {
const feature = e.features[0];
console.log(feature.properties);
});
Каждое событие передаёт массив Feature, соответствующих точке взаимодействия.
Properties Feature могут использоваться в сложных выражениях стиля:
'circle-radius': [
'interpolate',
['linear'],
['get', 'population'],
0, 4,
1000, 8,
10000, 16
]
Это позволяет строить визуализации, зависящие от атрибутивных данных.
При работе с тысячами и миллионами Feature критичны:
Кластеризация:
map.addSource('points', {
type: 'geojson',
data: featureCollection,
cluster: true,
clusterRadius: 50
});
Feature в этом случае объединяются в агрегированные объекты.
GeoJSON строго определяет порядок координат:
"coordinates": [longitude, latitude]
Нарушение порядка приводит к некорректному отображению Feature на карте.
Feature является связующим звеном между:
Эта модель обеспечивает декларативное описание пространственных данных, где геометрия и свойства отделены от их визуального представления и поведения.