CSV-файлы с координатами остаются одним из самых распространённых способов передачи геоданных в прикладных задачах: логистика, трекинг, анализ точек продаж, экспорт из GPS-устройств, выгрузки из CRM и телематики. В контексте работы с HERE Maps API такие данные чаще всего используются для динамического построения объектов на карте — маркеров, кластеров, маршрутов и слоёв визуализации.
Типичная CSV-структура для картографических задач содержит как минимум два столбца:
latitude,longitude
55.7558,37.6173
51.5074,-0.1278
48.8566,2.3522
Однако на практике почти всегда добавляются дополнительные поля:
id,name,latitude,longitude,category,timestamp
1,Moscow,55.7558,37.6173,city,2026-06-01T10:00:00Z
2,London,51.5074,-0.1278,city,2026-06-01T10:05:00Z
Ключевой момент при работе с картографическими API — строгая интерпретация координат:
Для обработки CSV в браузере или Node.js часто используется ручной разбор или специализированные библиотеки. При интеграции с HERE Maps API достаточно привести данные к массиву объектов.
Ручной парсинг:
function parseCSV(text) {
const lines = text.trim().split("\n");
const headers = lines[0].split(",");
return lines.slice(1).map(line => {
const values = line.split(",");
const obj = {};
headers.forEach((h, i) => {
obj[h.trim()] = values[i].trim();
});
return obj;
});
}
После преобразования данные приобретают структуру:
[
{ latitude: "55.7558", longitude: "37.6173", name: "Moscow" },
{ latitude: "51.5074", longitude: "-0.1278", name: "London" }
]
Для работы с картой значения координат должны быть приведены к числам:
const points = parsed.map(p => ({
lat: parseFloat(p.latitude),
lng: parseFloat(p.longitude),
name: p.name
}));
Инициализация карты требует платформы, слоя отображения и объекта карты.
const platform = new H.service.Platform({
apikey: "YOUR_API_KEY"
});
const defaultLayers = platform.createDefaultLayers();
const map = new H.Map(
document.getElementById("map"),
defaultLayers.vector.normal.map,
{
center: { lat: 0, lng: 0 },
zoom: 2,
pixelRatio: window.devicePixelRatio || 1
}
);
const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
const ui = H.ui.UI.createDefault(map, defaultLayers);
После преобразования CSV в массив координат формируются объекты
H.map.Marker.
const group = new H.map.Group();
points.forEach(point => {
const marker = new H.map.Marker({
lat: point.lat,
lng: point.lng
});
marker.setData(point.name);
group.addObject(marker);
});
map.addObject(group);
map.setCenter(group.getBoundingBox().getCenter());
map.getViewModel().setLookAtData({
bounds: group.getBoundingBox()
});
Использование группы объектов позволяет управлять всей коллекцией точек как единым слоем.
При работе с тысячами или десятками тысяч координат прямое добавление маркеров становится неэффективным. Основные проблемы:
Для оптимизации применяется:
1. Кластеризация точек
const clusteringProvider = new H.clustering.Provider(points.map(p => ({
lat: p.lat,
lng: p.lng
})));
const clusteringLayer = new H.map.layer.ObjectLayer(clusteringProvider);
map.addLayer(clusteringLayer);
Кластеризация автоматически объединяет близкие точки в группы, снижая визуальную нагрузку.
2. Ленивый рендеринг (chunking)
function addInChunks(points, chunkSize = 500) {
let index = 0;
function processChunk() {
const slice = points.slice(index, index + chunkSize);
slice.forEach(p => {
const marker = new H.map.Marker({ lat: p.lat, lng: p.lng });
map.addObject(marker);
});
index += chunkSize;
if (index < points.length) {
requestAnimationFrame(processChunk);
}
}
processChunk();
}
Такой подход предотвращает блокировку основного потока.
Многие функции HERE Maps API работают эффективнее с GeoJSON-структурами.
function toGeoJSON(points) {
return {
type: "FeatureCollection",
features: points.map(p => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [p.lng, p.lat]
},
properties: {
name: p.name
}
}))
};
}
GeoJSON можно использовать как промежуточный слой для аналитики, фильтрации и стилизации.
Часто CSV поступает через HTTP-запрос:
fetch("/data/points.csv")
.then(res => res.text())
.then(text => {
const data = parseCSV(text);
const points = data.map(p => ({
lat: parseFloat(p.latitude),
lng: parseFloat(p.longitude),
name: p.name
}));
addInChunks(points);
});
При работе с удалёнными источниками важно учитывать:
, или ;)Перед добавлением на карту данные должны проходить фильтрацию:
function isValidLatLng(lat, lng) {
return (
typeof lat === "number" &&
typeof lng === "number" &&
lat >= -90 && lat <= 90 &&
lng >= -180 && lng <= 180
);
}
Применение:
const clean = points.filter(p => isValidLatLng(p.lat, p.lng));
Типичные проблемы:
Решение заключается в нормализации:
function normalizeNumber(value) {
return parseFloat(String(value).replace(",", "."));
}
CSV-данные редко отображаются как единый слой. Чаще формируются логические группы:
Пример группировки:
const groups = points.reduce((acc, p) => {
if (!acc[p.category]) acc[p.category] = [];
acc[p.category].push(p);
return acc;
}, {});
Каждая группа может быть вынесена в отдельный слой карты:
Object.keys(groups).forEach(key => {
const layer = new H.map.Group();
groups[key].forEach(p => {
layer.addObject(new H.map.Marker({ lat: p.lat, lng: p.lng }));
});
map.addObject(layer);
});
При работе с потоковыми данными используется подход incremental parsing:
const reader = response.body.getReader();
const decoder = new TextDecoder();
let csvBuffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
csvBuffer += decoder.decode(value, { stream: true });
const lines = csvBuffer.split("\n");
csvBuffer = lines.pop();
lines.forEach(line => {
const [lat, lng] = line.split(",");
if (lat && lng) {
map.addObject(new H.map.Marker({
lat: parseFloat(lat),
lng: parseFloat(lng)
}));
}
});
}
CSV как источник геоданных в связке с HERE Maps API формирует универсальный механизм визуализации пространственной информации, где ключевую роль играет корректная нормализация координат, контроль структуры данных и выбор стратегии рендеринга в зависимости от объёма входящего массива.