Реализация 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 interpolation через 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 требует разработки — зависит от сложности интеграции с телематической платформой. Стоимость рассчитывается индивидуально.







