Работа с массивами является одной из центральных тем при разработке интерактивных карт с использованием MapLibre GL JS, поскольку практически все входные и промежуточные данные в библиотеке представлены в виде структур, основанных на массивах: списки координат, коллекции GeoJSON-объектов, наборы слоёв, фильтры, результаты кластеризации и динамически обновляемые источники данных.
Основной формат данных, с которым работает MapLibre GL JS, — GeoJSON. Его структура опирается на массивы:
Типичная структура FeatureCollection:
const geojson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [37.6173, 55.7558]
},
properties: {
name: "Москва"
}
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [30.3141, 59.9386]
},
properties: {
name: "Санкт-Петербург"
}
}
]
};
Любая операция отображения, фильтрации или трансформации данных в MapLibre GL JS фактически сводится к операциям над массивом features.
Фильтрация используется для динамического управления отображением объектов на карте без изменения источника данных.
const cities = geojson.features.filter(feature => {
return feature.properties.population > 1000000;
});
После фильтрации массив может быть повторно загружен в источник:
map.getSource("cities").setData({
type: "FeatureCollection",
features: cities
});
Фильтрация часто используется для:
Метод map используется для трансформации структуры
массива без изменения исходного набора данных.
const transformed = geojson.features.map(feature => {
return {
...feature,
properties: {
...feature.properties,
label: feature.properties.name.toUpperCase()
}
};
});
В MapLibre GL JS подобные преобразования часто применяются для:
Метод reduce используется для вычисления статистики по
набору геоданных.
const totalPopulation = geojson.features.reduce((sum, feature) => {
return sum + (feature.properties.population || 0);
}, 0);
В картографических приложениях агрегирование применяется для:
Сортировка часто используется для управления визуальной иерархией данных.
const sorted = geojson.features.sort((a, b) => {
return b.properties.importance - a.properties.importance;
});
В контексте MapLibre GL JS это влияет на:
Важно учитывать, что сортировка изменяет исходный массив, поэтому часто используется копирование:
const sortedCopy = [...geojson.features].sort(...);
Геометрические типы в GeoJSON содержат массивы различной вложенности.
coordinates: [longitude, latitude]
coordinates: [
[37.6, 55.7],
[37.7, 55.8]
]
coordinates: [
[
[37.6, 55.7],
[37.7, 55.7],
[37.7, 55.8],
[37.6, 55.7]
]
]
Операции над такими массивами включают:
При работе с MapLibre GL JS важно избегать мутаций исходных массивов, так как источник данных может быть привязан к состоянию карты.
Неправильный подход:
geojson.features.push(newFeature);
map.getSource("data").setData(geojson);
Корректный подход:
const upd ated = {
...geojson,
features: [...geojson.features, newFeature]
};
map.getSource("data").setData(upd ated);
Иммутабельность обеспечивает:
MapLibre GL JS не требует полного пересоздания источника при каждом изменении, но эффективное сравнение массивов позволяет минимизировать перерисовку.
Пример дифференциального обновления:
function diffFeatures(oldArr, newArr) {
const oldIds = new Se t(oldArr.map(f => f.id));
return newArr.filter(f => !oldIds.has(f.id));
}
Такая логика используется для:
Кластеризация в MapLibre GL JS основана на группировке элементов массива.
Типичный подход — разбиение точек по пространственным признакам:
const clusters = points.reduce((acc, point) => {
const key = `${Math.floor(point.coordinates[0])}:${Math.floor(point.coordinates[1])}`;
if (!acc[key]) acc[key] = [];
acc[key].push(point);
return acc;
}, {});
Использование массивов в кластеризации позволяет:
При работе с полигонами и мультигеометрией часто требуется рекурсивная обработка массивов.
function flattenCoordinates(coords) {
return coords.reduce((acc, item) => {
if (Array.isArray(item[0])) {
return acc.concat(flattenCoordinates(item));
}
return acc.concat([item]);
}, []);
}
Такие операции применяются для:
Поиск объектов по атрибутам — частая операция в интерактивных картах.
const feature = geojson.features.find(f => f.properties.id === targetId);
Также используется проверка наличия:
const exists = geojson.features.some(f => f.properties.active);
Эти операции применяются при:
Группировка используется для построения тематических слоёв.
const grouped = geojson.features.reduce((acc, f) => {
const type = f.properties.type;
if (!acc[type]) acc[type] = [];
acc[type].push(f);
return acc;
}, {});
После группировки данные могут быть распределены по слоям MapLibre GL JS:
При работе с большими наборами данных в MapLibre GL JS критично учитывать производительность:
map и filter на
больших массивахfor вместо цепочек методов в горячих
циклахПример индексации:
const index = new Map();
geojson.features.forEach(f => {
index.set(f.properties.id, f);
});
При обновлении данных на карте массивы должны быть синхронизированы с
источниками через setData.
map.getSource("points").setData({
type: "FeatureCollection",
features: updatedFeatures
});
Типичные сценарии синхронизации:
На практике операции над массивами комбинируются в цепочки:
const result = geojson.features
.filter(f => f.properties.active)
.map(f => ({
...f,
properties: {
...f.properties,
score: f.properties.value * 2
}
}))
.sort((a, b) => b.properties.score - a.properties.score);
Такая композиция позволяет формировать сложные вычислительные пайплайны, которые напрямую влияют на визуализацию данных в MapLibre GL JS.