Управление картой во Flutter с помощью Yandex MapKit

Курс посвящен работе с пакетом yandex_mapkit во Flutter на основе примеров управления картой. Вы научитесь инициализировать карту, управлять камерой, изменять масштаб и позиционирование.

1. Введение в Yandex MapKit и базовая настройка проекта

Введение в Yandex MapKit и базовая настройка проекта

Интеграция геолокационных сервисов является неотъемлемой частью современных мобильных приложений. Yandex MapKit представляет собой мощную библиотеку для работы с картографическими данными, маршрутизацией и поиском мест. Использование этого инструмента во Flutter позволяет создавать кроссплатформенные приложения с нативным уровнем производительности и глубокой интеграцией экосистемы Яндекса.

Выбор картографического провайдера зависит от целевой аудитории приложения. Если продукт ориентирован на страны СНГ, Яндекс Карты часто предоставляют более высокую детализацию зданий, актуальную информацию о пробках и точную маршрутизацию по сравнению с конкурентами.

| Характеристика | Yandex MapKit | Google Maps SDK | | :--- | :--- | :--- | | Детализация в СНГ | Высокая (включая контуры зданий и дворы) | Средняя | | Офлайн-карты | Поддерживаются из коробки | Ограниченная поддержка | | Ценообразование | Бесплатно до определенного лимита запросов | Платная основа с ежемесячным бонусом | | Интеграция во Flutter | Через сторонние пакеты (например, yandex_mapkit) | Официальный пакет от Google |

> Картографический интерфейс — это не просто статичная картинка, а сложная интерактивная система, требующая точного управления состоянием камеры, слоями данных и пользовательским вводом.

Получение API-ключа и настройка платформ

Для работы с картами необходимо получить уникальный идентификатор разработчика. Процесс начинается в Кабинете Разработчика Яндекса, где создается новый ключ для MapKit API. Этот ключ привязывается к вашему приложению и позволяет серверам Яндекса отслеживать количество запросов.

Например, если лимит бесплатного тарифа составляет 1000 запросов в сутки, а ваше приложение делает 5 запросов при каждом открытии карты, то бесплатного лимита хватит на 200 уникальных сессий в день. При превышении этого значения потребуется переход на коммерческий тариф.

После получения ключа необходимо настроить нативные платформы, так как Flutter-пакет является оберткой над нативными SDK для Android и iOS.

Настройка Android

Инициализация ключа в Android происходит на этапе запуска приложения. Для этого необходимо внести изменения в файл MainApplication.kt (или MainActivity.kt, в зависимости от структуры проекта).

Также в файле android/app/build.gradle необходимо убедиться, что минимальная версия Android SDK соответствует требованиям пакета (обычно это minSdkVersion 21 или выше).

Настройка iOS

Для платформы iOS инициализация выполняется в файле AppDelegate.swift. Важно сделать это до регистрации плагинов Flutter.

Интеграция зависимости в проект

После нативной настройки необходимо добавить сам пакет в проект Flutter. Это делается через файл конфигурации pubspec.yaml.

Выполнив команду flutter pub get, вы загрузите необходимые Dart-интерфейсы для взаимодействия с нативными картами.

Создание базового виджета карты

Основой пользовательского интерфейса является виджет YandexMap. Он отображает саму карту и предоставляет коллбэк onMapCreated, который возвращает YandexMapController. Этот контроллер — главный инструмент разработчика для программного управления картой.

Контроллер позволяет выполнять множество операций: * Изменять масштаб и позицию камеры * Получать текущие координаты центра экрана * Ограничивать область прокрутки * Управлять слоями (пробки, пользовательская локация)

Рассмотрим базовый пример экрана с картой:

В этом примере карта займет все доступное пространство экрана. Однако без управления камерой она откроется на координатах по умолчанию (обычно это центр Москвы или нулевые координаты).

Управление камерой: масштаб, наклон и азимут

Для перемещения по карте используется метод moveCamera у объекта YandexMapController. Камера в MapKit описывается классом CameraPosition, который включает в себя четыре ключевых параметра:

  • Target (Цель) — географические координаты (широта и долгота), на которые смотрит камера.
  • Zoom (Масштаб) — уровень приближения.
  • Azimuth (Азимут) — направление камеры относительно севера в градусах.
  • Tilt (Наклон) — угол наклона камеры относительно поверхности земли.
  • Масштаб измеряется в условных единицах. Значение означает, что на экране видна вся планета, а значение позволяет рассмотреть отдельные здания. Если установить масштаб , пользователь увидит несколько кварталов города.

    Азимут измеряется в градусах от до . При азимуте север находится сверху экрана. Если установить азимут , карта повернется так, что сверху окажется восток.

    Наклон также измеряется в градусах. Значение означает вид строго сверху (2D-режим). Увеличение этого значения переводит карту в 3D-режим, позволяя видеть объемные модели зданий.

    Пример программного перемещения камеры с анимацией:

    В данном коде используется класс CameraUpdate, который генерирует новое состояние камеры. Анимация типа smooth обеспечивает плавный перелет от текущей точки к новой за 2 секунды. Если анимация не нужна, можно передать MapAnimationType.linear с нулевой длительностью.

    Помимо установки абсолютной позиции, контроллер позволяет изменять параметры относительно текущего состояния. Например, методы CameraUpdate.zoomIn() и CameraUpdate.zoomOut() увеличивают или уменьшают масштаб на одну единицу, не меняя координаты центра и наклон.

    Понимание работы YandexMapController и параметров камеры является фундаментом для создания сложных сценариев: от слежения за перемещением курьера до реализации кастомных кнопок управления интерфейсом карты.

    2. Инициализация виджета YandexMap и работа с контроллером

    Инициализация виджета YandexMap и работа с контроллером

    После успешной настройки нативных платформ и получения API-ключа, следующим шагом в разработке геолокационного приложения является детальная настройка пользовательского интерфейса карты. Базовое отображение карты — это лишь холст. Для создания полноценного продукта необходимо научиться управлять этим холстом: менять его внешний вид, реагировать на жесты пользователя и программно перемещать фокус внимания.

    Расширенная настройка виджета YandexMap

    Виджет YandexMap предоставляет множество параметров для кастомизации визуального представления и поведения карты. По умолчанию карта отображается в стандартном дневном режиме с включенными жестами, однако эти параметры можно жестко задать через конструктор виджета.

    Ключевые параметры виджета YandexMap: * mapType — определяет тип подложки. Может принимать значения MapType.map (схема), MapType.satellite (спутник) или MapType.hybrid (гибрид). * nightModeEnabled — булево значение, включающее темную тему карты. Полезно для синхронизации с системной темой устройства. * tiltGesturesEnabled — разрешает или запрещает пользователю менять угол наклона карты (свайп двумя пальцами вверх/вниз). * zoomGesturesEnabled — управляет возможностью масштабирования щипком (pinch-to-zoom). * rotateGesturesEnabled — отвечает за вращение карты двумя пальцами.

    > Отключение определенных жестов часто применяется в сценариях, где карта выполняет роль статичного фона или когда случайное вращение может дезориентировать пользователя (например, в приложениях для вызова такси).

    Рассмотрим пример инициализации карты с заданными ограничениями:

    Жизненный цикл и асинхронность контроллера

    Связь между Flutter-кодом и нативным SDK Яндекса осуществляется через YandexMapController. Этот объект не создается разработчиком напрямую; он передается в коллбэк onMapCreated в момент, когда нативная платформа завершает рендеринг базового слоя карты.

    Поскольку инициализация карты занимает некоторое время, хорошей практикой является использование класса Completer из библиотеки dart:async. Это позволяет безопасно обращаться к контроллеру из любой части виджета, гарантируя, что карта уже готова к приему команд.

    Используя _completer.future, можно дождаться готовности контроллера перед выполнением таких действий, как перемещение камеры или добавление маркеров.

    Программное управление камерой

    Для изменения видимой области используется метод moveCamera, который принимает объект CameraUpdate. Существует несколько способов сформировать этот объект в зависимости от задачи.

    | Метод CameraUpdate | Описание | Сценарий использования | | :--- | :--- | :--- | | newCameraPosition | Устанавливает точные значения широты, долготы, масштаба, азимута и наклона. | Переход к конкретному адресу или городу. | | zoomIn / zoomOut | Изменяет текущий масштаб на шаг. | Реализация кнопок «+» и «-» на экране. | | zoomTo | Устанавливает конкретное значение масштаба, не меняя координаты центра. | Сброс масштаба до уровня улицы. | | panTo | Сдвигает центр карты к новой точке, сохраняя текущий масштаб и наклон. | Слежение за движущимся объектом (курьером). |

    Пример реализации кнопок масштабирования. Допустим, текущий масштаб карты равен (уровень района). Если пользователь нажимает кнопку приближения, вызывается метод zoomIn(), и масштаб становится . Если нажать еще раз — (уровень нескольких зданий).

    Фокусировка на области: BoundingBox

    Часто возникает задача показать на экране не одну точку, а целую область — например, маршрут от точки А до точки Б или все доступные магазины в городе. Для этого используется BoundingBox (ограничивающий прямоугольник).

    Географические координаты подчиняются строгим математическим правилам. Широта варьируется в диапазоне от до градусов, а долгота — от до градусов. BoundingBox задается двумя точками: юго-западной (минимальные и ) и северо-восточной (максимальные и ).

    Контроллер может автоматически рассчитать необходимый масштаб и позицию камеры, чтобы заданный BoundingBox целиком поместился на экране устройства.

    В этом примере камера переместится так, чтобы охватить заданный прямоугольник координат, автоматически подобрав оптимальный уровень zoom.

    Обработка событий карты

    Интерактивность подразумевает реакцию на действия пользователя. YandexMap предоставляет несколько важных коллбэков для отслеживания событий.

  • onCameraPositionChanged — вызывается при любом изменении позиции камеры (свайп, программное перемещение, изменение масштаба). Возвращает текущую позицию, причину изменения (жест пользователя или API) и флаг завершения движения.
  • onMapTap — срабатывает при коротком нажатии на карту. Возвращает координаты (Point) места касания.
  • onMapLongTap — срабатывает при долгом удержании пальца на карте. Часто используется для установки пользовательских меток.
  • Пример использования onCameraPositionChanged для получения координат центра экрана в реальном времени (например, для реализации функционала «Указать адрес точкой на карте»):

    Параметр finished имеет критическое значение. Если пользователь активно скроллит карту, событие вызывается десятки раз в секунду со значением finished: false. Выполнение тяжелых операций (например, сетевых запросов) в этот момент приведет к зависанию интерфейса. Запрос следует отправлять только тогда, когда finished становится true, что означает полную остановку камеры.