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

Реалізація пошуку найближчих об'єктів (POI) у мобільному додатку Уявіть: додаток відображає сотню маркерів на карті, а прокрутка перетворюється на слайд-шоу. Або користувач натискає «Знайти аптеку», а список завантажується півхвилини. Саме це відбувається, коли пошук найближчих об'єктів (POI) реа

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Реалізація пошуку найближчих об'єктів (POI) у мобільному додатку
Середній
від 1 дня до 3 днів

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

Часті запитання

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Реалізація пошуку найближчих об'єктів (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 для вашого додатка. Оцінимо проєкт за один день, запропонуємо найкраще рішення під ключ.