Объекты карты

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

Метки

Добавьте пользовательские метки изображения на карту с помощью метода MapObjectCollection.addPlacemark из поля Map.mapObjects.

Метод создает экземпляр метки на карте, который можно сконфигурировать: указать Point с координатами для метки и иконку с помощью класса ImageProvider, для инициализации которого используются ассеты

final placemark = map.mapObjects.addPlacemark()
  ..geometry = Point(latitude: 59.935493, longitude: 30.327392)
  ..setIcon(ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png")));

С помощью приведенного выше кода создается экземпляр класса PlacemarkMapObject, который расширяет интерфейс MapObject.

Интерфейс MapObject представляет каждый видимый объект на карте. Существует несколько способов настройки объектов карты: изменение видимости, разрешение перетаскивания, изменение z-индекса, настройка обработчика событий касания или перетаскивания и многое другое.

Подробнее об этом можно почитать в разделе MapObject.

Настройка текста

Вы можете создавать текстовые надписи рядом с метками. Для этого используйте метод PlacemarkMapObject.setText.

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

placemark
  ..setText("Special place")
  ..setTextStyle(TextStyle(/* args */));

Стили значков

Вы можете настроить представление значков меток с помощью класса IconStyle. Он позволяет изменять положение привязки, размер, тип поворота, z-индекс, кликабельные области, видимость и плоскость по отношению к карте.

placemark.setIconStyle(
  IconStyle(
    anchor: Point(0.5, 1.0)
    scale: 0.6
    zIndex: 10.0
  )
);

Составные значки

Объедините несколько значков, чтобы создать составной.

  1. Создайте значок по умолчанию с помощью MapObjectCollection.addPlacemark.

  2. Используйте PlacemarkMapObject.useCompositeIcon, чтобы создать составной значок.

  3. Используйте CompositeIcon.setIcon, чтобы добавить новый значок к составному значку.

Полный пример кода для создания составного значка:

final placemark = map.mapObjects.addPlacemark()
  ..geometry = Point(latitude: 59.935493, longitude: 30.327392)
  ..setText("Special place")
  ..setTextStyle(
      TextStyle(
        size: 8.0,
        placement: TextStylePlacement.Right,
        offset: 5.0,
      )
    );

placemark.useCompositeIcon()
  ..setIcon(
      ImageProvider.fromImageProvider(const AssetImage("assets/ic_dollar_pin.png", id: "pin")),
      IconStyle(
        anchor: Point(0.5, 1.0),
        scale: 0.9,
      )
    )
  ..setIcon(
      ImageProvider.fromImageProvider(const AssetImage("assets/ic_circle.png", id: "point")),
      IconStyle(
        anchor: PointF(0.5, 0.5)
        flat: true
        scale: 0.05f
      )
    );
}

Результат:

Пример составного значка

Анимированные метки

Вы можете создать анимированную метку из анимированного PNG-файла.

  1. Создайте метку с помощью MapObjectCollection.addPlacemark.

    final placemark = map.mapObjects.addPlacemark()
      ..geometry = Point(latitude: 59.935493, longitude: 30.327392);
    
  2. Используйте метод PlacemarkMapObject.useAnimation для создания объекта анимации. Задать ресурс анимации можно при помощи экземпляра AnimatedImageProvider.

    final animation = placemark.useAnimation()
      ..setIcon(AnimatedImageProvider.fromAsset("assets/animation.png"));
    
  3. Запустите анимацию, управляя ею с помощью объекта PlacemarkAnimation.

    animation.play();
    

Коллекции меток

Коллекции меток используются для группировки нескольких меток в новую коллекцию вложенных объектов карты.

  1. Чтобы создать коллекцию вложенных объектов карты, используйте метод MapObjectCollection.addCollection.

    final pinsCollection = map.mapObjects.addCollection();
    
  2. Теперь вы можете использовать новую коллекцию pinsCollection для отображения меток и других объектов карты.

    final points = [
        Point(latitude: 59.935493, longitude: 30.327392),
        Point(latitude: 59.938185, longitude: 30.32808),
        Point(latitude: 59.937376, longitude: 30.33621),
        Point(latitude: 59.934517, longitude: 30.335059),
    ];
    
    val imageProvider = ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png"));
    
    points.forEach((point) {
      pinsCollection.addPlacemark()
        ..geometry = point
        ..setIcon(imageProvider);
    });
    

    Примечание

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

    Как это выглядит после добавления меток в коллекцию новых объектов карты:

    Карта с коллекцией меток

После создания коллекции pinCollection вы можете добавить в нее пины так же, как и для объектов Map.mapObjects, поскольку они имеют тот же тип MapObjectCollection.

Примечание

Интерфейс MapObjectCollection расширяет MapObject, поэтому допускается создавать вложенные коллекции и добавлять их в другие.

Все методы, имеющие интерфейс MapObject, также доступны в MapObjectCollection.

Вы можете итерироваться по элементам MapObjectCollection, используя метод BaseMapObjectCollection.traverse.

Геометрии

MapKit SDK позволяет рисовать на карте примитивные геометрические объекты, такие как полигоны, полилинии и круги. Все они настраиваемые и реализуют интерфейс MapObject.

Полигоны

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

  1. Начните с создания экземпляра Polygon.

    final points = [
        Point(latitude: 59.935493, longitude: 30.327392),
        Point(latitude: 59.938185, longitude: 30.32808),
        Point(latitude: 59.937376, longitude: 30.33621),
        Point(latitude: 59.934517, longitude: 30.335059),
    ];
    
    final polygon = Polygon(LinearRing(points), []);
    
  2. Используйте метод MapObjectCollection.addPolygon для создания полигонального объекта карты.

    final polygonMapObject = map.mapObjects.addPolygon(polygon);
    

    После завершения сборки вы увидите полигон в стиле по умолчанию:

    Карта с полигоном по умолчанию

  3. Задайте внутренние точки при создании полигона, чтобы исключить часть внутри него.

    final points = [
        Point(latitude: 59.935493, longitude: 30.327392),
        Point(latitude: 59.938185, longitude: 30.32808),
        Point(latitude: 59.937376, longitude: 30.33621),
        Point(latitude: 59.934517, longitude: 30.335059),
    ];
    
    final innerPoints = [
        Point(latitude: 59.937487, longitude: 30.330034),
        Point(latitude: 59.936688, longitude: 30.33127),
        Point(latitude: 59.937116, longitude: 30.33328),
        Point(latitude: 59.937704, longitude: 30.331842),
    ];
    
    final polygon = Polygon(LinearRing(points), listOf(LinearRing(innerPoints)))
    

    Полигон с внутренними точками:

    Карта с полигоном с использованием внутренних точек

  4. Измените цвет заливки и обводки по умолчанию, используя созданный экземпляр PolygonMapObject.

    polygonMapObject
      ..strokeWidth = 1.5
      ..strokeColor = Colors.greenAccent
      ..fillColor = Colors.green;
    

    Карта со стилизованным полигоном

Подробнее про настройку полигонов см. в разделе PolygonMapObject.

Полилинии

Полилинии часто используются для отображения маршрутов и траекторий.

  1. Создайте экземпляр Polyline с искомой геометрией и добавьте на карту объект полилинейной карты с помощью метода MapObjectCollection.addPolylineWithGeometry.

    final points = [
        Point(latitude: 59.935493, longitude: 30.327392),
        Point(latitude: 59.938185, longitude: 30.32808),
        Point(latitude: 59.937376, longitude: 30.33621),
        Point(latitude: 59.934517, longitude: 30.335059),
    ];
    final polyline = Polyline(points);
    
    final polylineObject = map.mapObjects.addPolyline(polyline);
    
  2. Настройте стили полилиний, используя переменную PolylineMapObject.

    polylineObject
      ..strokeWidth = 5.0
      ..setStrokeColor = Colors.grey
      ..outlineWidth = 1.0
      ..outlineColor = Colors.black;
    

    Результат после добавления полилинии на карту:

    Карта с добавленной полилинией

Подробнее об этом можно почитать в разделе PolylineMapObject.

Круги

Круги используются для отображения круглых областей.

  1. Создайте экземпляр Circle с искомой геометрией: центральной точкой и радиусом в метрах.

    final circle = Circle(
      Point(latitude: 59.935493, longitude: 30.327392),
      radius: 400.0,
    );
    
  2. С помощью метода MapObjectCollection.addCircle добавьте на карту объект круга.

    map.mapObjects.addCircle(circle)
      ..strokeWidth = 2.0
      ..strokeColor = Colors.red
      ..fillColor = Colors.redAccent;
    

    Результат после добавления круга на карту:

    Карта с кругом

Подробнее о том, как настроить круговой объект карты, можно почитать в разделе CircleMapObject.

Кластеры

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

  1. Начните с создания ClusterListener с одним методом ClusterListener.onClusterAdded, который управляет внешним видом кластера на карте.

    final class ClusterListenerImpl implements ClusterListener {
    
      @override
      void onClusterAdded(Cluster cluster) {
        cluster.appearance.setView(
          ViewProvider(builder: () => ClusterView()..setText("${cluster.placemarks.length}"))
        );
      }
    }
    
    final clusterListener = ClusterListenerImpl();
    

    Свойство Cluster.appearance возвращает объект PlacemarkMapObject. В нашем примере мы используем метод PlacemarkMapObject.setView, чтобы изменить внешний вид кластера.

    ClusterView — это определяемый пользователем класс. Чтобы узнать, как он реализован, посмотрите код в нашем репозитории на GitHub.

  2. Создайте новую вложенную коллекцию с помощью метода MapObjectCollection.addClusterizedPlacemarkCollection.

    final clusterizedPlacemarkCollection = map.mapObjects.addClusterizedPlacemarkCollection(clusterListener);
    
  3. Добавьте несколько меток в новый clusterizedCollection.

    final points = [
        Point(latitude: 59.935493, longitude: 30.327392),
        Point(latitude: 59.938185, longitude: 30.32808),
        Point(latitude: 59.937376, longitude: 30.33621),
        Point(latitude: 59.934517, longitude: 30.335059),
    ];
    
    val imageProvider = ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png"));
    
    points.forEach((point) {
      clusterizedCollection.addPlacemark()
        ..geometry = point
        ..setIcon(imageProvider);
    });
    
  4. Вызовите метод ClusterizedPlacemarkCollection.clusterPlacemarks. Он принимает два аргумента:

    • clusterRadius — минимальное расстояние в единицах между объектами, которые остаются в отдельных кластерах.
    • minZoom — минимальный уровень масштабирования, отображающий кластеры.
    clusterizedPlacemarkCollection.clusterPlacemarks(clusterRadius: 60.0, minZoom: 15);
    

    Важно

    ClusterizedPlacemarkCollection.clusterPlacemarks следует вызывать явно каждый раз, когда метки добавляются в кластеризованные коллекции или удаляются из них.

    Иначе кластеризованные метки не будут повторно отображаться.

    Кластеризованные метки с разным масштабом:

    Кластеры