Реалізація пошуку найближчих об'єктів (POI) у мобільному додатку

Коли карта в застосунку перетворюється на слайд-шоу з сотень маркерів, а пошук найближчої аптеки займає півхвилини — час задуматися про правильну реалізацію POI. Ми розробляємо пошук найближчих об'єктів з урахуванням масштабу даних та кластеризацією, обираючи оптимальний підхід — клієнтський або серверний. Наша команда реалізує проєкт під ключ, забезпечуючи швидке завантаження та стабільну роботу навіть із великими датасетами.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Реалізація пошуку найближчих об'єктів (POI) у мобільному додатку

Карти та геолокація в мобільних додаткахСереднійвід 1 дня до 3 днів
Часті запитання

Реалізація пошуку найближчих об'єктів (POI) у мобільному додатку

Уявіть: додаток відображає сотню маркерів на карті, а прокрутка перетворюється на слайд-шоу. Або користувач натискає «Знайти аптеку», а список завантажується півхвилини. Саме це відбувається, коли пошук найближчих об'єктів (POI) реалізований без урахування масштабу даних та без кластеризації. Ми, команда мобільних розробників з п’ятирічним досвідом, вирішили цю задачу для більш ніж 50 проєктів (iOS, Android, Flutter). Гарантуємо: POI завантажуватимуться за частки секунди навіть при датасеті у 100 000 точок.

Два підходи: клієнтський та серверний пошук

Клієнтський пошук — завантажуємо всі точки (або їх підмножину) у додаток, шукаємо найближчі на пристрої. Працює для невеликих наборів даних — до 5000 точок. Фільтрація за відстанню через формулу Гаверсина або через CLLocation.distance(from:) / Location.distanceTo(). Плюс: працює офлайн. Мінус: не можна зберігати мільйон точок у пам'яті.

Серверний пошук — PostGIS ST_DWithin, MongoDB $near, Elasticsearch geo_distance query. Для великих датасетів (від 10 000 точок) тільки цей варіант. Додаток надсилає координати та радіус, сервер повертає відсортований список. Використовуємо індексацію на стороні БД — це в десять разів швидше, ніж повний перебір.

Порівняння підходів

Параметр Клієнтський Серверний
Макс. точок ~5 000 не обмежено
Офлайн-режим Так Ні (тільки кеш)
Швидкість Миттєво 50-200 мс
Складність Низька Середня
Трафік Високий (всі дані) Низький (тільки результат)

Google Places Nearby Search

Для POI з відкритих даних (кафе, банки, аптеки) використовуємо Google Places API:

GET https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=55.75,37.62&radius=1000&type=pharmacy&key=...

На iOS через GMSPlacesClient.findPlaceLikelihoodList або прямий HTTP. На Android через Retrofit. Повертає до 20 результатів за запит, наступна сторінка — через pagetoken. Важливо: pagetoken активується не одразу, потрібна затримка 2 секунди перед запитом наступної сторінки.

Для кастомних точок (власні магазини, пункти видачі) — власний бекенд. PostGIS запит:

SELECT id, name, lat, lon,
       ST_Distance(geom, ST_MakePoint(:lon, :lat)::geography) AS distance_m
FROM locations
WHERE ST_DWithin(geom, ST_MakePoint(:lon, :lat)::geography, :radius)
ORDER BY distance_m
LIMIT 50;

Відображення на карті та кластеризація

Якщо точок більше 50 на екрані — потрібна кластеризація. На iOS: GMSMarkerClusterer з google-maps-ios-utils. На Android: ClusterManager з android-maps-utils. У Flutter: flutter_map + flutter_map_marker_cluster.

Кластери перераховуються при кожній зміні зуму. Без debounce на подію onCameraMove це викликає лаг — розрахунок кластерів має відбуватися асинхронно, не на main thread.

При тапі на кластер — плавне масштабування через CameraUpdate.newLatLngBounds() до меж кластера, не просто зум до центру.

Оновлення при переміщенні

Не перезапитувати POI на кожне оновлення геолокації. Логіка: запитуємо при першому завантаженні та при переміщенні користувача більше ніж на N метрів від центру останнього запиту (для більшості випадків — 300-500 м). CLLocation.distance(from: lastQueryCenter) > threshold. Додатково — кешуємо результати на годину, щоб знизити навантаження.

Чому варто обрати наш підхід?

Досвідчені розробники (iOS, Android, Flutter) використовують лише перевірені стеки: Swift 5.9, Kotlin, Flutter 3.x. Ми інтегрували Google Places API у 30+ проєктах і знаємо всі тонкощі pagetoken. Гарантуємо продуктивність: так, кластеризація рахується асинхронно, а запити ходять з debounce. Результат — карта не гальмує навіть на старих пристроях.

Що входить у роботу

  • Дослідження датасету та вибір стратегії (клієнт/сервер/гібрид)
  • Проєктування архітектури модуля POI
  • Інтеграція Google Places API або налаштування власного бекенду з PostGIS
  • Реалізація кластеризації з асинхронним перерахунком
  • Логіка оновлення при переміщенні з debounce та кешуванням
  • Unit-тести та UI-тести
  • Документація для розробників та навчання вашої команди
  • Підтримка після деплою: 1 місяць безкоштовно

Процес роботи

Етап Тривалість Результат
Аналітика 1 день Вивчення даних, навантаження, сценаріїв використання
Проєктування 1 день Вибір підходу, схема запитів
Реалізація 2-4 дні Код, налаштування індексів
Тестування 1 день Перевірка на реальних пристроях з різними радіусами
Деплой 1 день Публікація в магазини або розгортання сервера
Підтримка — Виправлення багів по гарячих лініях

Орієнтовні строки

Базова інтеграція (Google Places + карта + кластеризація) — від 3 до 5 днів. Повне рішення з серверним пошуком та кастомними точками — до 7 днів. Оцінимо ваш проєкт за один день — просто напишіть нам.

Як оптимізувати запити до сервера?

  • Використовуйте просторові індекси (GiST у PostGIS, 2dsphere у MongoDB)
  • Обмежте радіус: не більше 5 км для пішохідного пошуку
  • Додайте ліміт на кількість результатів (50-100)
  • Кешуйте відповідь на 5-10 хвилин для статичних POI
  • При частих запитах від одного користувача — агрегуйте їх у batch

Типові помилки

  • Відсутність debounce при зміні зуму — інтерфейс гальмує
  • Запит нової сторінки Places API без затримки — отримуємо порожню відповідь
  • Зберігання всіх координат у пам'яті — перевитрата пам'яті
  • Ігнорування pagetoken — бачимо лише 20 результатів
  • Кластеризація на main thread — лаги при скролі
Приклад конфігурації кластеризації на Swift
let clusterManager = GMUClusterManager(mapView: mapView, algorithm: GMUNonHierarchicalDistanceBasedAlgorithm(), renderer: renderer)
clusterManager.setDelegate(self, mapDelegate: self)

Зв'яжіться з нами — отримайте консультацію щодо архітектури POI для вашого додатка. Оцінимо проєкт за один день, запропонуємо найкраще рішення під ключ.

Наші компетенції:

Останні роботи

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1010
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    903
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1332
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1180
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1107
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    714