Реалізація теплових карт (Heatmaps) у мобільному додатку
Теплові карти у мобільному додатку — інструмент аналітики і навігації одночасно: показати щільність замовлень, популярні зони, активність водіїв. Проблема не в рендерингу — бібліотеки справляються, — а в роботі з великими датасетами на мобільному екрані без деградації FPS.
Як рендеряться теплові карти
Кожна бібліотека будує heatmap через kernel density estimation: для кожної точки на екрані розраховується зважена сума вкладів від всіх точок даних у заданому радіусі. Результат — bitmap-шар поверх карти.
iOS: GMUHeatmapTileLayer з google-maps-ios-utils. Дані — массив GMUWeightedLatLng. Радіус градієнта, мінімальна інтенсивність і кольорова схема налаштовуються через властивості шару. Тайловий механізм означає, що при скролі карти нові тайли рендеряться на льоту — без лагу, якщо датасет не величезний.
Android: HeatmapTileProvider з android-maps-utils. Принцип аналогічний. Передаємо Collection<LatLng> або Collection<WeightedLatLng> для зважених точок.
Flutter: google_maps_flutter не включає heatmap з коробки. Два варіанти: нативний platform channel до GMSMapView/MapView з GMUHeatmapTileLayer / HeatmapTileProvider, або бібліотека flutter_map + flutter_map_heatmap на основі canvas.
Робота з великими датасетами
Головна проблема: передавати 50 000 точок в GMUHeatmapTileLayer і чекати, поки він їх обробить на main thread — отримати ANR або заморозку на 3-4 секунди.
Правильний підхід — агрегація на сервері. Замість 50 000 сирих точок сервер повертає вже агреговані дані по сітці (grid aggregation): кожна клітина сітки — одна точка з вагою, рівною кількості подій в клітині. При зумі 10 — сітка 500×500 метрів, при зумі 14 — 50×50 метрів. Кількість точок скорочується до 200-500 незалежно від вихідного обсягу.
Серверна агрегація через PostGIS:
SELECT
round(lat::numeric, 3) AS lat_grid,
round(lon::numeric, 3) AS lon_grid,
COUNT(*) AS weight
FROM events
WHERE created_at > now() - interval '7 days'
GROUP BY lat_grid, lon_grid;
При зміні зуму карти — перезапитуємо агрегацію з новою точністю округлення. Дебаунс 500 мс на подію зміни зуму обов'язковий.
Кольорові схеми і інтерпретація
Стандартна кольорова схема (синій → зелений → жовтий → червоний) інтуїтивна, але не підходить для людей з дальтонізмом. Для B2B-аналітики краще працює одноколірний градієнт (білий → темно-синій) або кастомна схема бренду.
GMUHeatmapTileLayer приймає [GMUGradient] з массивом кольорів і позицій — налаштовується без перезбірки.
Строк: два-три дні — інтеграція бібліотеки, серверна агрегація (якщо потрібна), налаштування динамічного зуму, кольорова схема.







