Map Objects

The MapKit SDK lets developers display objects on a map. All map objects are customizable, facilitating unique user scenarios tailored to the developer needs.

Placemarks

Add custom image placemarks to the map with the MapObjectCollection.addPlacemark method from the Map.mapObjects field.

The method creates a placemark instance on the map, which you can customize: set the Point with coordinates for the placemark and the icon using the ImageProvider instance, which can be created from an asset.

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

The code above creates an instance of the PlacemarkMapObject class that extends the MapObject interface.

The MapObject interface represents every visible object on the map. There are a few ways to configure map objects: changing visibility, allowing dragging, changing a z-index, setting a tap or drag event listener, and more.

For more details, see the MapObject documentation.

Setting text

You can create text labels near placemarks. Use the PlacemarkMapObject.setText method.

Use TextStyle to change how labels look, including their text size, color, and position relative to the icon.

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

Icon styles

You can customize how placemark icons are presented using the IconStyle class. It lets you change the icon's anchor position, size, rotation type, z-index, tappable area, visibility, and flatness to the map.

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

Composite icons

Combine multiple icons to create a composite one.

  1. Create a default icon using MapObjectCollection.addPlacemark method.

  2. Call PlacemarkMapObject.useCompositeIcon to create a composite icon.

  3. Use CompositeIcon.setIcon to add a new icon to the composite icon.

Complete sample code for creating a composite icon:

final placemark = map.mapObjects.addPlacemark()
  ..geometry = const Point(latitude: 25.1982, longitude: 55.272758)
  ..setText("Special place")
  ..setTextStyle(
      const mapkit.TextStyle(
        size: 10.0,
        color: Colors.black,
        outlineColor: Colors.white,
        placement: TextStylePlacement.Right,
        offset: 5.0,
      )
  );

placemark.useCompositeIcon()
  ..setIcon(
      ImageProvider.fromImageProvider(const AssetImage("assets/ic_dollar_pin.png")),
      const IconStyle(
        anchor: Point(0.5, 1.0),
        scale: 4.0,
      ),
      name: "pin",
    )
  ..setIcon(
      ImageProvider.fromImageProvider(const AssetImage("assets/ic_circle.png")),
      const IconStyle(
        anchor: Point(0.5, 0.5)
        flat: true
        scale: 0.2
      )
      name: "point",
    );
}

The result:

Composite icon example

Animated placemarks

You can create an animated placemark from an animated png file.

  1. Create the placemark using MapObjectCollection.addPlacemark.

    final placemark = map.mapObjects.addPlacemark()
      ..geometry = const Point(latitude: 25.1982, longitude: 55.272758);
    
  2. Call the PlacemarkMapObject.useAnimation method to create an animation object. Set the animation resource using the AnimatedImageProvider instance.

    final animation = placemark.useAnimation()
      ..setIcon(AnimatedImageProvider.fromAsset("assets/animation.png"));
    
  3. Start the animation, managing it with the PlacemarkAnimation object.

    animation.play();
    

Placemark collections

Placemark collections are used to group multiple placemarks into a new collection of nested map objects.

  1. To create a collection of nested map objects, use the MapObjectCollection.addCollection method.

    final pinsCollection = map.mapObjects.addCollection();
    
  2. From now, you can use your new pinsCollection to display placemarks and other map objects.

    final points = [
        Point(latitude: 25.190614, longitude: 55.265616),
        Point(latitude: 25.187532, longitude: 55.275413),
        Point(latitude: 25.196605, longitude: 55.28094),
        Point(latitude: 25.198219, longitude: 55.272685),
    ];
    
    final imageProvider = ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png"));
    
    points.forEach((point) {
      pinsCollection.addPlacemark()
        ..geometry = point
        ..setIcon(imageProvider);
    });
    

    Note

    Use a single ImageProvider instance if you need to display multiple similar placemarks. This will be more efficient than creating a new instance for each placemark.

    What it looks like after placemarks were added to a collection of new map objects:

    Map with placemark collection

After creating pinCollection, you can add pins to it the same way as for Map.mapObjects since they have the same MapObjectCollection type.

Note

The MapObjectCollection interface extends MapObject. That is why it is allowed to create nested collections and add them to another collections.

All methods that have the MapObject interface are also available in MapObjectCollection.

You can iterate through MapObjectCollection elements using the BaseMapObjectCollection.traverse method.

Geometries

The MapKit SDK lets you draw primitive geometric objects like polygons, polylines, and circles on the map. They're all customizable, and they implement the MapObject interface.

Polygons

Use a polygon when you need to display a map area to users.

  1. Start by creating a Polygon instance.

    final points = [
        Point(latitude: 25.190614, longitude: 55.265616),
        Point(latitude: 25.187532, longitude: 55.275413),
        Point(latitude: 25.196605, longitude: 55.28094),
        Point(latitude: 25.198219, longitude: 55.272685),
    ];
    
    final polygon = Polygon(LinearRing(points), []);
    
  2. Use the MapObjectCollection.addPolygon method to create a polygon map object.

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

    After the build is complete, you will see a default-styled polygon:

    Map with default polygon

  3. Define inner points while creating a polygon to exclude a section on the inside of the polygon.

    final points = [
        Point(latitude: 25.190614, longitude: 55.265616),
        Point(latitude: 25.187532, longitude: 55.275413),
        Point(latitude: 25.196605, longitude: 55.28094),
        Point(latitude: 25.198219, longitude: 55.272685),
    ];
    
    final innerPoints = [
        Point(latitude: 25.190978, longitude: 55.273982),
        Point(latitude: 25.191958, longitude: 55.27378),
        Point(latitude: 25.192516, longitude: 55.27204),
        Point(latitude: 25.192015, longitude: 55.271365),
    ];
    
    final polygon = Polygon(LinearRing(points), [LinearRing(innerPoints)])
    

    Polygon with inner points:

    Map with polygon using inner points

  4. Let's change the default fill color and stroke using the PolygonMapObject instance we created.

    polygonMapObject
      ..strokeWidth = 5.0
      ..strokeColor = Colors.green[900]!
      ..fillColor = Colors.green.withAlpha(130);
    

    Map with styled polygon

For more details on how to configure polygons, see the PolygonMapObject documentation.

Polylines

Polylines are often used to display routes and trajectories.

  1. Create a Polyline instance with the geometry you're looking for and add a polyline map object to the map using the MapObjectCollection.addPolylineWithGeometry method.

    final points = [
        Point(latitude: 25.190614, longitude: 55.265616),
        Point(latitude: 25.187532, longitude: 55.275413),
        Point(latitude: 25.196605, longitude: 55.28094),
        Point(latitude: 25.198219, longitude: 55.272685),
    ];
    final polyline = Polyline(points);
    
    final polylineObject = map.mapObjects.addPolylineWithGeometry(polyline);
    
  2. Configure polyline styles using the PolylineMapObject variable.

    polylineObject
      ..strokeWidth = 5.0
      ..setStrokeColor(Colors.grey)
      ..outlineWidth = 2.0
      ..outlineColor = Colors.black;
    

    Once you've added the polyline to the map:

    Map with the added polyline

For more details, see the PolylineMapObject documentation.

Circles

Circles are used to display circular areas.

  1. Create a Circle instance with the geometry you're looking for: a center point and a radius in meters.

    final circle = Circle(
      Point(latitude: 25.1982, longitude: 55.272758),
      radius: 400.0,
    );
    
  2. Using the MapObjectCollection.addCircle method, add a circle object to the map.

    map.mapObjects.addCircle(circle)
      ..strokeWidth = 3.0
      ..strokeColor = Colors.red[700]!
      ..fillColor = Colors.red.withAlpha(130);
    

    After adding a circle to the map:

    Map with the circle

For more details on how to configure a circular map object, see the CircleMapObject documentation.

Clusters

Clusterized collections are used to display multiple placemarks.

  1. Start by creating a ClusterListener with a single ClusterListener.onClusterAdded method that controls the appearance of the cluster on the map.

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

    The Cluster.appearance property returns a PlacemarkMapObject object. In our example, we're using the PlacemarkMapObject.setView method to change how the cluster looks.

    ClusterView is a custom defined class. Check out its implementation in our Github repository.

  2. Create a new nested collection using the MapObjectCollection.addClusterizedPlacemarkCollection method.

    final clusterizedPlacemarkCollection = map.mapObjects.addClusterizedPlacemarkCollection(clusterListener);
    
  3. Add multiple placemarks to the new clusterizedCollection.

    final points = [
        Point(latitude: 25.190614, longitude: 55.265616),
        Point(latitude: 25.187532, longitude: 55.275413),
        Point(latitude: 25.196605, longitude: 55.28094),
        Point(latitude: 25.198219, longitude: 55.272685),
    ];
    
    final imageProvider = ImageProvider.fromImageProvider(const AssetImage("assets/ic_pin.png"));
    
    points.forEach((point) {
      clusterizedCollection.addPlacemark()
        ..geometry = point
        ..setIcon(imageProvider);
    });
    
  4. Call the ClusterizedPlacemarkCollection.clusterPlacemarks method. It accepts two arguments:

    • clusterRadius: the minimum distance in units between objects that remain in separate clusters.
    • minZoom: the minimum zoom level that displays clusters.
    clusterizedPlacemarkCollection.clusterPlacemarks(clusterRadius: 60.0, minZoom: 15);
    

    Warning

    The ClusterizedPlacemarkCollection.clusterPlacemarks should be called explicitly whenever placemarks are added to or removed from clusterized collections.

    Otherwise, clusterized placemarks will be not re-rendered.

    Clusterized placemarks at different zooms:

    Clusters