Одной из ключевых возможностей Kepler.gl является работа с удалёнными источниками данных. Вместо хранения файлов непосредственно в приложении данные могут загружаться по URL-адресу с веб-серверов, API, облачных хранилищ или CDN. Такой подход особенно полезен при работе с большими наборами геоданных, динамически обновляемой информацией и распределёнными архитектурами.
Загрузка данных из URL позволяет:
В типичном сценарии приложение выполняет следующие действия:
Схема процесса:
URL
↓
HTTP-запрос
↓
Получение данных
↓
Парсинг
↓
addDataToMap()
↓
Отображение на карте
Kepler.gl способен работать с различными типами геопространственных данных:
| Формат | Назначение |
|---|---|
| CSV | Табличные данные |
| JSON | Универсальный формат обмена |
| GeoJSON | Географические объекты |
| KML | Геоданные Google Earth |
| Shapefile | Классический GIS-формат |
| GPX | GPS-треки и маршруты |
При загрузке через URL наиболее часто используются CSV и GeoJSON.
Предположим, имеется удалённый файл:
https://example.com/data/cities.csv
Содержимое:
city,lat,lng,population
Almaty,43.238949,76.889709,2000000
Astana,51.169392,71.449074,1400000
Shymkent,42.341685,69.590101,1100000
Получение данных осуществляется через Fetch API:
fetch('https://example.com/data/cities.csv')
.then(response => response.text())
.then(data => {
console.log(data);
});
После получения содержимое файла представляет собой обычную строку.
Kepler.gl содержит набор утилит для обработки данных.
Импорт:
import {processCsvData} from '@kepler.gl/processors';
Загрузка и обработка:
fetch('https://example.com/data/cities.csv')
.then(response => response.text())
.then(csv => {
const dataset = processCsvData(csv);
dispatch(
addDataToMap({
datasets: dataset
})
);
});
После выполнения данные автоматически появляются на карте.
GeoJSON является одним из наиболее распространённых форматов пространственных данных.
Пример URL:
https://example.com/data/regions.geojson
Получение данных:
fetch('https://example.com/data/regions.geojson')
.then(response => response.json())
.then(data => {
console.log(data);
});
Структура GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [76.889709, 43.238949]
},
"properties": {
"name": "Almaty"
}
}
]
}
Для преобразования используется специальный процессор.
import {processGeojson} from '@kepler.gl/processors';
Пример:
fetch('https://example.com/data/regions.geojson')
.then(response => response.json())
.then(json => {
const dataset = processGeojson(json);
dispatch(
addDataToMap({
datasets: dataset
})
);
});
Kepler.gl автоматически определяет типы геометрий:
Современный подход предполагает использование асинхронных функций.
async function loadData() {
const response = await fetch(
'https://example.com/data/cities.csv'
);
const csv = await response.text();
const dataset = processCsvData(csv);
dispatch(
addDataToMap({
datasets: dataset
})
);
}
Вызов:
loadData();
Код становится более читаемым по сравнению с цепочками
.then().
Часто требуется отображать сразу несколько наборов данных.
Например:
cities.csv
roads.geojson
regions.geojson
Загрузка выполняется параллельно:
const [
citiesResponse,
roadsResponse,
regionsResponse
] = await Promise.all([
fetch('/data/cities.csv'),
fetch('/data/roads.geojson'),
fetch('/data/regions.geojson')
]);
Получение содержимого:
const cities = await citiesResponse.text();
const roads = await roadsResponse.json();
const regions = await regionsResponse.json();
Преобразование:
const cityDataset = processCsvData(cities);
const roadDataset = processGeojson(roads);
const regionDataset = processGeojson(regions);
Передача в карту:
dispatch(
addDataToMap({
datasets: [
cityDataset,
roadDataset,
regionDataset
]
})
);
Для корректного управления слоями рекомендуется задавать идентификаторы.
const dataset = {
info: {
id: 'cities',
label: 'Cities'
},
data: processCsvData(csv).data
};
Добавление:
dispatch(
addDataToMap({
datasets: dataset
})
);
Преимущества:
Источник данных необязательно должен быть файлом.
Возможна загрузка из REST API.
Пример ответа сервера:
[
{
"name": "Almaty",
"lat": 43.238949,
"lng": 76.889709
},
{
"name": "Astana",
"lat": 51.169392,
"lng": 71.449074
}
]
Получение данных:
const response = await fetch(
'https://api.example.com/cities'
);
const data = await response.json();
Не все API возвращают данные в формате, который может напрямую использоваться картой.
Преобразование:
const rows = data.map(city => ({
name: city.name,
latitude: city.lat,
longitude: city.lng
}));
Создание структуры таблицы:
const dataset = {
fields: [
{name: 'name'},
{name: 'latitude'},
{name: 'longitude'}
],
rows: rows.map(item => [
item.name,
item.latitude,
item.longitude
])
};
После этого данные можно передать в карту.
Иногда набор данных регулярно изменяется.
Пример обновления каждые 30 секунд:
setInterval(async () => {
const response = await fetch(
'/data/vehicles.geojson'
);
const geojson = await response.json();
const dataset = processGeojson(geojson);
dispatch(
addDataToMap({
datasets: dataset
})
);
}, 30000);
Такой механизм часто используется для:
Удалённый сервер может быть недоступен.
Поэтому необходимо контролировать ошибки.
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(
`HTTP Error: ${response.status}`
);
}
const data = await response.json();
console.log(data);
}
catch (error) {
console.error(error);
}
Типичные проблемы:
Перед обработкой рекомендуется проверять статус.
const response = await fetch(url);
if (response.status === 404) {
console.log('Файл не найден');
}
if (response.status === 500) {
console.log('Ошибка сервера');
}
Наиболее распространённые коды:
| Код | Значение |
|---|---|
| 200 | Успешно |
| 201 | Создано |
| 301 | Перенаправление |
| 403 | Доступ запрещён |
| 404 | Не найдено |
| 500 | Ошибка сервера |
При загрузке данных с другого домена часто возникает ошибка:
Access to fetch at ...
has been blocked by CORS policy
Причина заключается в ограничениях браузера.
Сервер должен отправлять заголовок:
Access-Control-Allow-Origin: *
Либо:
Access-Control-Allow-Origin: https://myapp.com
Без корректной настройки CORS браузер блокирует запрос ещё до получения данных.
URL может содержать параметры фильтрации.
Пример:
const url =
'https://api.example.com/events?year=2025';
Формирование параметров через URLSearchParams:
const params = new URLSearchParams({
year: 2025,
country: 'Kazakhstan'
});
const response = await fetch(
`https://api.example.com/events?${params}`
);
Такой подход упрощает построение динамических запросов.
Некоторые API требуют авторизацию.
const response = await fetch(url, {
headers: {
Authorization: 'Bearer TOKEN'
}
});
Дополнительные заголовки:
headers: {
Authorization: 'Bearer TOKEN',
Accept: 'application/json',
'Content-Type': 'application/json'
}
При работе с большими файлами желательно отображать состояние загрузки.
Пример:
setLoading(true);
try {
const response = await fetch(url);
const json = await response.json();
const dataset = processGeojson(json);
dispatch(
addDataToMap({
datasets: dataset
})
);
}
finally {
setLoading(false);
}
Типичный интерфейс:
{
loading && (
<div>
Loading...
</div>
)
}
Для уменьшения нагрузки на сервер можно сохранять результаты запросов.
Простейший вариант:
const cache = new Map();
Проверка:
if (cache.has(url)) {
return cache.get(url);
}
Сохранение:
cache.set(url, data);
Преимущества:
Наиболее распространённый сценарий в React-приложениях выглядит следующим образом:
useEffect(() => {
async function load() {
const response = await fetch(
'/data/cities.geojson'
);
const geojson =
await response.json();
const dataset =
processGeojson(geojson);
dispatch(
addDataToMap({
datasets: dataset
})
);
}
load();
}, []);
После монтирования компонента карта автоматически получает данные и строит визуализацию без участия пользователя.
При работе с крупными геоданными рекомендуется:
Особенно заметен эффект оптимизации при загрузке миллионов точек или сложных полигональных объектов, где размер исходного файла может достигать сотен мегабайт. В таких случаях правильная организация удалённого источника данных оказывает большее влияние на производительность приложения, чем последующая настройка визуализации внутри Kepler.gl.