MapLibre GL JS поддерживает работу с GeoJSON-источниками, включая все
стандартные типы геометрий спецификации GeoJSON, среди которых особое
место занимает GeometryCollection. Этот тип представляет
собой контейнер, объединяющий несколько геометрий разных типов в одном
объекте, что принципиально отличает его от MultiPoint,
MultiLineString и MultiPolygon, где
допускается только однородный набор координат.
GeometryCollection определяется как объект с типом
"GeometryCollection" и массивом геометрий в поле
geometries:
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [30.5, 50.5]
},
{
"type": "LineString",
"coordinates": [
[30.0, 50.0],
[31.0, 51.0]
]
}
]
}
Ключевая особенность заключается в том, что внутри коллекции могут
находиться любые валидные геометрии GeoJSON, включая вложенные
GeometryCollection, хотя на практике такие конструкции
редко используются из-за сложности обработки.
В MapLibre GL JS GeometryCollection поддерживается через
GeoJSONSource. Однако важно понимать, что обработка таких
объектов имеет особенности:
geometries интерпретируется как
отдельная геометрия;layer), а не
на уровне коллекции.При добавлении источника:
map.addSource('collection-source', {
type: 'geojson',
data: {
type: 'Feature',
geometry: {
type: 'GeometryCollection',
geometries: [
{
type: 'Point',
coordinates: [30.5, 50.5]
},
{
type: 'LineString',
coordinates: [
[30.0, 50.0],
[31.0, 51.0]
]
}
]
}
}
});
MapLibre распаковывает коллекцию и обрабатывает каждую геометрию как отдельный элемент потока данных.
При визуализации GeometryCollection в MapLibre GL JS
проявляется важное ограничение: один слой не может одновременно
корректно стилизовать разные типы геометрий.
Если источник содержит GeometryCollection, то:
circle-layer отобразит только Pointline-layer отобразит только
LineStringfill-layer отобразит только PolygonЭто означает, что одна коллекция фактически “разделяется” на логические подмножества в зависимости от типа слоя.
Пример фильтрации:
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'collection-source',
filter: ['==', '$type', 'Point']
});
map.addLayer({
id: 'lines-layer',
type: 'line',
source: 'collection-source',
filter: ['==', '$type', 'LineString']
});
Ключевая концептуальная разница:
В контексте MapLibre GL JS предпочтение обычно отдаётся Multi-типам, поскольку они обеспечивают более предсказуемое поведение в стиле и производительности.
GeometryCollection увеличивает нагрузку на обработку
данных по нескольким причинам:
Де-нормализация данных MapLibre должен развернуть коллекцию в набор геометрий.
Усложнение фильтрации Каждый элемент требует
проверки $type.
Рост числа render-объектов Вместо одного объекта фактически обрабатывается несколько.
При больших объёмах данных это может приводить к:
GeometryCollection применяется, когда один логический объект состоит из нескольких типов геометрий, например:
Пример:
{
"type": "Feature",
"properties": {
"name": "Station A"
},
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [29.0, 49.0]
},
{
"type": "Polygon",
"coordinates": [
[
[28.9, 48.9],
[29.1, 48.9],
[29.1, 49.1],
[28.9, 49.1],
[28.9, 48.9]
]
]
}
]
}
}
В слоях MapLibre GL JS фильтрация GeometryCollection работает только через стандартные GeoJSON-предикаты:
$typegeometry-type выраженияpropertiesНельзя напрямую обратиться к конкретной геометрии внутри коллекции по индексу без предварительной трансформации данных.
Пример фильтра:
filter: ['==', ['geometry-type'], 'Polygon']
При использовании cluster: true в
GeoJSONSource GeometryCollection ведёт себя
неоднозначно:
Это создаёт несогласованность, если коллекция используется как единый объект представления.
На практике для повышения совместимости с MapLibre GL JS часто выполняется нормализация:
Пример преобразования:
function expandGeometryCollection(feature) {
if (feature.geometry.type !== 'GeometryCollection') return [feature];
return feature.geometry.geometries.map((geom) => ({
type: 'Feature',
properties: feature.properties,
geometry: geom
}));
}
Такой подход позволяет:
В остальных случаях в экосистеме MapLibre GL JS предпочтительнее использовать строгие типы GeoJSON без коллекций.
MapLibre не рассматривает коллекцию как единый визуальный примитив, что приводит к “частичному отображению”.
Без фильтра $type возможна некорректная отрисовка всех
геометрий в одном слое.
Хотя спецификация допускает вложенность, в реальных приложениях это часто приводит к ошибкам парсинга или потере производительности.
Использование GeometryCollection в MapLibre GL JS обычно сигнализирует о необходимости пересмотра модели данных:
Архитектурно это снижает связность и повышает предсказуемость поведения карты при рендеринге и взаимодействии с пользователем.