Начало работы с MapKit для Flutter

В этом руководстве объясняется как установить и настроить библиотеку MapKit и создать карту с меткой для определенной локации.

Шаг 1. Получите API-ключ для работы с MapKit

Перед тем, как использовать MapKit SDK в своем приложении, вам нужно получить API-ключ.

  1. Перейдите в Кабинет Разработчика.

  2. Авторизуйтесь, используя учетную запись Яндекса, или зарегистрируйте новый аккаунт.

  3. Нажмите Подключить API и выберите MapKit – мобильный SDK.

  4. Введите информацию о себе и своем проекте, выберите тарифный план и нажмите Продолжить.

  5. После того, как ваш API-ключ будет успешно создан, он будет доступен на вкладке Интерфейсы APIMapKit – мобильный SDK.

Примечание

Активация API-ключей занимает около 15 минут.

Шаг 2. Добавьте библиотеку MapKit в проект

Библиотека MapKit SDK доступна в репозитории pub.dev.

  1. Создайте новый проект или откройте существующий, например, в Visual Studio Code или Android Studio.

  2. Откройте файл pubspec.yaml приложения (модуля). В секции dependencies добавьте зависимость:

    dependencies:
      # Облегченная библиотека, содержит только карту, слой пробок,
      # LocationManager, UserLocationLayer
      # и возможность скачивать офлайн-карты (только в платной версии). 
      yandex_maps_mapkit_lite:
        version: ^4.6.1-beta1
    
      # Полная библиотека в дополнение к lite версии предоставляет автомобильную маршрутизацию,
      # веломаршрутизацию, пешеходную маршрутизацию и маршрутизацию на общественном транспорте,
      # поиск, suggest, геокодирование и отображение панорам.
      # yandex_maps_mapkit:
      #   version: ^4.6.1-beta1
    
  3. Выполните pub get, чтобы синхронизировать проект и применить изменения.

    Если синхронизация завершилась успешно, при компиляции библиотека будет добавлена в проект автоматически.

Шаг 3. Добавьте API-ключ для MapKit

Для MapKit SDK необходимо, чтобы вы инициализировали библиотеку и установили API-ключ с помощью функции initMapkit.

Рекомендуем сделать это в вашей main() функции:

import 'package:yandex_maps_mapkit_lite/init.dart' as init;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await init.initMapkit(
    apiKey: 'YOUR_API_KEY'
  ); 
}

Важно

С помощью вызова init.initMapkit(String apiKey) загружаются все необходимые для MapKit нативные библиотеки.

Если вы не хотите, чтобы ваш API-ключ хранился файле, который будет включен в систему контроля версий, вы можете сделать это одним из способов:

  1. Определите флаг времени компиляции:

    flutter run --dart-define MAPKIT_API_KEY=your_api_key
    

    И используйте его так:

    import 'package:yandex_maps_mapkit_lite/init.dart' as init;
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      final mapkitApiKey = String.fromEnvironment('MAPKIT_API_KEY');
    
      await init.initMapkit(
        apiKey: mapkitApiKey
      ); 
    }
    
  2. Используйте пакет ENVied или создайте отдельный .dart файл, в котором будет находиться глобальная переменная, содержащая API-ключ.

Примечание

Убедитесь, что файлы, содержающие API-ключи, игнорируются вашей системой контроля версий.

Шаг 4. Добавьте карту

  1. Добавьте YandexMap в дерево виджетов:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
        
      await init.initMapkit(
        apiKey: 'YOUR_API_KEY'
      );
                
      runApp(const MyApp());
    }
      
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
      
      @override
      State<MyApp> createState() => _MyAppState();
    }
      
    class _MyAppState extends State<MyApp> {
      
      MapWindow? _mapWindow;
      
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: YandexMap(onMapCreated: (mapWindow) => _mapWindow = mapWindow)
          )
        );
      }
    }
    
  2. Когда карта становится видимой или невидимой для пользователя, отправляйте события onStart и onStop в Mapkit при помощи методов mapkit.onStart() и mapkit.onStop() соответственно.
    Иначе Mapkit не сможет отображать карту и прекратит ее обработку, когда приложение с картой станет невидимым для пользователя.

Создайте и запустите приложение. Пример приложения с кликабельной картой:

Карта с наименьшим увеличением

Чтобы изменить положение или масштаб карты, используйте метод Map.moveWithAnimation:

map.move(
  CameraPosition(
    Point(latitude: 55.751225, longitude: 37.629540),
    zoom: 17.0,
    azimuth: 150.0,
    tilt: 30.0
  )
);

Map.moveWithAnimation принимает на вход аргумент CameraPosition, который полностью задает положение, масштаб, наклон и азимут карты.

Карты по умолчанию поддерживают несколько действий: перемещение, поворот, изменение масштаба и наклон.

Без дополнительной настройки карта будет отображаться с минимально возможным масштабом для экрана пользователя.

Пример карты после изменения положения камеры:

Карта после применения

Шаг 5. Обратите внимание при дальнейшей работе

MapKit хранит слабые ссылки на передаваемые ему Listener-объекты. Необходимо самим хранить ссылку на них в памяти:

final class MapCameraListenerImpl implements MapCameraListener {
  // ......
}

final class SomeMapScopedClass {

  final MapWindow _mapWindow;
  final MapCameraListener _cameraListener = MapCameraListenerImpl();

  SomeMapScopedClass(this._mapWindow);

  void addListener() {
    _mapWindow.map.addCameraListener(_cameraListener);
  }
}

Примечание

По умолчанию методы всех Listener-объектов и платформенных интерфейсов вызываются на главном потоке, если в документации метода не сказано обратное.

Шаг 6. Отображение метки на карте

Изменим приложение таким образом, чтобы вы могли показывать на карте кликабельную метку.

  1. Добавьте в проект ресурс png для изображения метки.

    Например, есть изображение, и оно доступно по идентификатору assets/ic_pin.png.

    Значок метки

  2. Добавьте метку для коллекции Map.mapObjects в определенное место.

    Используйте ImageProvider.fromImageProvider, чтобы создать экземпляр ImageProvider для изображения метки.

    final imageProvider = ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png"));
    final placemark = mapWindow.map.mapObjects.addPlacemark()
      ..geometry = Point(latitude: 59.935493, longitutde: 30.327392)
      ..setICon(imageProvider);
    
  3. Чтобы подписаться на нажатия на созданную метку, используйте метод MapObject.addTapListener.

    final class MapObjectTapListenerImpl implements MapObjectTapListener {
    
      @override
      bool onMapObjectTap(MapObject mapObject, Point point) {
        log("Tapped the point ${point.longitude}, ${point.latitude}");
        return true;
      }
    }
    
    final listener = MapObjectTapListenerImpl();
    placemark.addTapListener(listener);
    

Соберите и запустите приложение. На карте есть метка с вашим изображением. Коснитесь метки, и появится всплывающее сообщение:

Карта после нажатия метки

Предыдущая
Следующая