Реалізація GPS-трекінгу транспорту в мобільному IoT-додатку
GPS-трекер на транспортному засобі відправляє пакет кожні 10 секунд. Це 8640 записів на добу на один об'єкт. При 50 транспортних засобах — 432 000 точок на день. Додаток повинен відображати поточну позицію кожного у реальному часі та не тормозити при перегляді історії за неділю.
Отримання даних від IoT-трекерів
Апаратний GPS-трекер (Teltonika FMB140, Queclink GV620, Concox GT06N) відправляє дані по TCP/UDP на сервер, використовуючи власний бінарний протокол або MQTT. Мобільний додаток не взаємодіє з трекером безпосередньо — це задача сервера телематики. Клієнт отримує обробленний потік через WebSocket або REST API.
Різниця між WebSocket та polling у цьому сценарії відчутна. Polling кожні 10 секунд на 50 об'єктів = постійні HTTP-запити, overhead на handshake, затримка до 10 секунд. WebSocket з серверними подіями: сервер пушить оновлення відразу при отриманні нового пакету від трекера, затримка — 1–2 секунди, нема лишніх запитів.
Відображення на карті
Кожен трекер — маркер на карті з іконкою транспортного засобу, напрямком руху (bearing) та статусом. Три ключові моменти:
Bearing-анімація. Трекер міняє напрямок — іконка повинна повертатися плавно, не скачком. На Android: ObjectAnimator.ofFloat(marker, "rotation", oldBearing, newBearing).setDuration(500). На iOS: CABasicAnimation(keyPath: "transform.rotation.z") на шарі маркера.
Плавне переміщення. Маркер рухається до нової координати, не стрибає. ValueAnimator з LatLngInterpolator на Android; на iOS — CABasicAnimation з CGPoint інтерполяцією через MKAnnotationView.coordinate.
Кластеризація. При зумі нижче 12 окремі маркери сливаються. Використовуємо Supercluster-порт для Flutter або нативний GMSMarkerClusterer (Android) / CMClusterAnnotationView (iOS). Кластер показує лічильник транспортних засобів усередину.
Історія треку
Історія за день — від 5 000 до 15 000 точок залежно від частоти запису. Рисувати Polyline з 10 000 точок безпосередньо — це лаг при render. Два підходи:
Дискретизація Douglas-Peucker на сервері. При запиті історії сервер спрощує трек з епсилон-параметром, залежним від рівня зуму: при zoom 10 достатньо ~500 точок, при zoom 17 — повна деталізація. Клієнт запитує трек з параметром зуму.
LOD при прокрутці. Завантажуємо трек за вибраний період шматками при скролі часового слайдера. Поза видимою областю — не рендеримо.
Зупинки в треку вичисляються на сервері: кластер точок з speed < 5 км/ч довше N хвилин = зупинка. Адреса — reverse geocoding через Google Maps Geocoding API або Nominatim, кешується в базі.
Швидкість та алерти
Перевищення швидкісного режиму, різкий займання, різкий прискорення — вичисляється з сирих даних телематики (speed, accelerometer якщо трекер підтримує). Алерт відправляється через FCM/APNs push з high priority. У додатку — UNNotificationCategory з action «Відкрити карту» для iOS, PendingIntent з deep link для Android.
Геозонні алерти: вхід/вихід з зони. Перевірка ST_Contains у PostGIS при кожному входящому пакеті — сотні тисяч перевірок на добу при великому флоті. Оптимізація: просторовий індекс GIST на geometry колонці, R-tree на геозонах у пам'яті (GeoHashing для первісної фільтрації).
З практики
Трекінг цементовозів: 35 машин, інтервал запису 15 сек, історія на 90 днів. Проблема при переглядіністорії за місяць: Polyline з 720 000 точок вішав UI на 4–5 секунд. Після впровадження динамічної дискретизації (200 точок при zoom 10, 5000 при zoom 16) — плавно на Samsung A32.
Графік
Реалізація GPS-трекінгу транспорту в мобільному IoT-додатку (карта реального часу + історія + алерти) при готовому серверному API: 1–2 тижні. Якщо API потребує розробки — залежить від складності інтеграції з телематичною платформою. Вартість розраховується індивідуально.







