Реалізація геозон для IoT-пристроїв (Geofencing) у мобільному додатку
Геозона спрацювала — трекер вийшов у зону. Але уведомлення прийшло через 4 хвилини. За це час самокат уїхав на 600 метрів за периметр складу. Проблема в тому, де саме перевіряється перетинання геозони: на сервері раз у N секунд або у реальному часі при кожному входящому пакеті.
Серверна vs клієнтська геолокація
Для IoT-пристроїв (трекери, датчики, транспорт) геозоні завжди перевіряються на сервері. IoT-пристрій не запускає ваш додаток — він просто посилає GPS-пакети. Мобільний додаток отримує вже вичислене событие через push-уведомлення або WebSocket.
Це контрастує зі сценарієм, коли геозону перевіряє сам смартфон користувача через CLLocationManager.startMonitoring(for region:) (iOS) або GeofencingClient.addGeofences() (Android). Але для IoT-fleet — тільки серверна сторона.
Як працює серверна геозона
PostgreSQL + PostGIS — стандартний стек:
SELECT zone_id, zone_name
FROM geofences
WHERE ST_Contains(geometry, ST_SetSRID(ST_MakePoint($lon, $lat), 4326));
Індекс GIST на geometry прискорює ST_Contains до мікросекунд. При 500 входящих пакетах у секунду від всього флоту — навантаження прийнятне навіть на одному інстансі PostgreSQL.
Перехід enter/exit визначається через state machine у Redis: при кожному событієпорівнюємо з попередньою станом пристрою. Якщо було outside → стало inside → emit событие geofence_entered.
Створення та редагування геозон у додатку
Користувач рисує геозону на карті — круг або довільний полігон.
Круговая зона. Найпростіший варіант: GMSCircle (Android) / MKCircle (iOS) з центром та радіусом. Користувач ставить точку, тягне за ручку для задання радіусу. Зберігається як {lat, lng, radius_meters}.
Полігональна зона. Користувач тапає по точкам на карті, формуючи замкнутий контур. GMSPolygon / MKPolygon з live-preview при додаванні точок. Остання точка з'єднується з першою автоматично при натисканні «Закрити фігуру».
Редагування: перетаскування вершин (draggable Marker на кутових точках), додавання проміжних точок через midpoint handles. Це стандартний паттерн для polygon editor на картах.
Валідація: самопересічення полігону — ST_IsValid(geometry) на сервері перед збереженням. Клієнт отримує помилку та підсвічує проблемний учасник.
Уведомлення та реакції
При спрацьовуванні геозони сервер відправляє push через FCM (Android) / APNs (iOS) з priority: high. Для time-critical алертів (дитина вийшла з безпечної зони, грузовик виїхав за периметр) використовуємо APNs content-available: 0 (видимий push) — він прилітає навіть в Doze mode Android.
Уведомлення містить: назва пристрою, назва зони, тип событія (вхід/вихід), час. На iOS — UNNotificationCategory з action «Відкрити карту» для швидкого переходу. Deep link передається в userInfo payload.
У самому додатку — лента подій геозон з фільтрацією по пристрою/зоні/типу событія. Паганіація через cursor-based pagination (не offset — таблиця подій росте швидко).
Настройка чутливості
Трекер присилає точку раз у 10–30 секунд. При цій частоті пристрій може «проскочити» крізь вузьку геозону без єдиної точки усередину. Рішення:
- Збільшити частоту запису при наближенні до зони — деякі трекери підтримують «зону тривоги» та автоматично учащают запис
- Перевіряти перетинання відрізка
[prev_point, cur_point]з границею зони черезST_Intersects(ST_MakeLine(...), geometry)— ловить транзитні перетинання - Буферизація: розширюємо зону на N метрів (
ST_Buffer) для раннього попередження
Графік
Реалізація геозон (створення/редагування полігонів + уведомлення про перетинання) при готовій серверній частині: 3–5 робочих днів. Якщо потрібна розробка серверної логіки з PostGIS + Redis state machine — 1–2 тижні. Вартість розраховується індивідуально.







