Реализация прямого геокодирования (координаты по адресу) в мобильном приложении
Когда пользователь вводит адрес в поле доставки или регистрации, а приложению нужны координаты — это прямое геокодирование. Задача простая, пока не сталкиваешься с частичными вводами, опечатками, адресами без индекса и корпусами, которые Google не знает.
Типичные проблемы
CLGeocoder.geocodeAddressString(_:completionHandler:) на iOS принимает произвольную строку и возвращает массив CLPlacemark. Проблема — нет параметра региона по умолчанию: строка «Ленина 5» без города вернёт плейсмарк из Казахстана или вообще nil. Обязательно передавать CLRegion с центром и радиусом, соответствующим целевому рынку.
На Android Geocoder.getFromLocationName(address, maxResults) до Android 13 выполняется в основном потоке и легко вызывает NetworkOnMainThreadException, если забыть вынести в IO dispatcher или фоновый поток. Ещё одна особенность: на эмуляторе без Google Play Services возвращает пустой список без ошибки — баг, который ловят только при тестировании на реальном устройстве.
Как реализуем
Для точности используем Google Maps Geocoding API напрямую: maps.googleapis.com/maps/api/geocode/json?address=…®ion=ru&language=ru&key=…. Ответ содержит geometry.location с координатами и geometry.viewport — прямоугольник, который удобно передавать в CameraUpdate.newLatLngBounds() для правильного зума карты после перехода.
В кейсе с российскими адресами добавляем DaData как первый провайдер: их suggestions/api/4_1/rs/geocode/ лучше справляется с корпусами, строениями и промзонами. Если DaData вернул пустой результат — fallback на Google. Такая двухуровневая схема покрывает 98%+ адресов.
На Flutter — geocoding пакет для платформенного варианта или прямой HTTP-клиент (Dio) к Geocoding API. Результат кэшируем в Hive или sqlite с TTL 24 часа: одинаковые адреса запрашиваются повторно редко, но кэш экономит квоту API-ключа.
Срок реализации: один-два дня в зависимости от количества провайдеров и требований к офлайн-поведению.







