> For the complete documentation index, see [llms.txt](https://docs.fleaflet.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fleaflet.dev/layers/marker-layer.md).

# Marker Layer

You can add single point features - including arbitrary widgets - to maps using `MarkerLayer` and `Marker`s.

{% hint style="success" %}
No more image only markers! [Unlike *other* ](https://github.com/flutter/flutter/issues/24213)😉[^1][ popular mapping libraries](https://github.com/flutter/flutter/issues/24213), we allow usage of any widget as the marker.
{% endhint %}

<figure><img src="https://852902308-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSFuYRJZsfLx0EidjdMud%2Fuploads%2FbAf2OvB3xZmDlW0ml8pY%2FMarker%20Demo.png?alt=media&amp;token=3a28caac-2b65-44f8-87e0-a51cbe1c296b" alt=""><figcaption><p>A variety of <code>Marker</code>s on a rotated map</p></figcaption></figure>

{% embed url="<https://pub.dev/documentation/flutter_map/latest/flutter_map/MarkerLayer-class.html>" %}

{% embed url="<https://pub.dev/documentation/flutter_map/latest/flutter_map/Marker-class.html>" %}

```dart
MarkerLayer(
  markers: [
    Marker(
      point: LatLng(30, 40),
      width: 80,
      height: 80,
      child: FlutterLogo(),
    ),
  ],
),
```

## Size

The `height` and `width` parameters are required to enable the positioning and culling of the markers to work correctly.

The marker child will be sized to these parameters, which default to 30 logical pixels. If the child will change size, set the size to the largest size and control the size of the child within a widget which allows it to be smaller than the constraints set.

## Alignment & Counter-Rotation

By default, the marker's child is centered over the `point`, and will always remain upright relative to the North when the map is rotated.

This can be changed using `alignment` and `rotate`.&#x20;

To keep the child upright relative to the screen (counter-rotate it compared to any map rotation), set `rotate` to `true`.

To change the pivot point for the counter-rotation and the alignment of the child to the `point`, set the `alignment` accordingly.

For example:

```dart
Marker(
    rotate: true,
    alignment: Alignment.topCenter,
    // ...
),
```

These parameters can also be set directly on the `MarkerLayer` to change the default for all of its markers.

{% hint style="info" %}
There is no built-in support to rotate markers to a specific degree. However, this is easy to implement through a rotating widget, such as `Transform.rotate`.
{% endhint %}

## Handling State

{% hint style="danger" %}
`Marker`s with `key`s set will cause the map to crash if the same marker appears at the same time across multiple worlds. Follow issue [#2229](https://github.com/fleaflet/flutter_map/issues/2229) for more information.
{% endhint %}

Often, marker children do not have their own internal state (they are `StatelessWidget`s). However, some use-cases may require them to be stateful.

{% hint style="warning" %}
Markers are culled when they go offscreen, and the marker child is not built when culled. Therefore, any widget state is lost when culling.

When multiple of the same marker is visible at once, across multiple worlds, the marker child is built multiple times. Therefore, the widget states are not synchronized, and any keys in the child subtree may not be unique.
{% endhint %}

Therefore, children should not be `StatefulWidget`s, unless:

* It is safe for the state to be reset when being rebuilt after culling, and
* It is safe for the state of the same marker in different worlds to be different

Instead, the state should be detached and moved up in the tree, using an inherited approach. For example, a state management package, or Flutter's built-in options like `InheritedWidget` or `ValueNotifier` - remember that `FlutterMap.children` can contain widgets wrapped around layers like this.

Then, some map should be kept linking a unique property of the marker (its `point` could be suitable and easily accessed in most dynamic marker layer systems) to its state. The child can then lookup this state.

For example:

{% code expandable="true" %}

```dart
children: [
    // TileLayer(), etc...
    
    MyInheritedStateApproach(
        states: <LatLng, MyMarkerState>{
            LatLng(0, 0): MyMarkerState(),
            // These could be dynamically generated from a source,
            // for example using `Map.fromEntries`
        },
        child: MarkerLayer(
            markers: [
                Marker(
                    point: LatLng(0, 0),
                    child: MyMarker(point: LatLng(0, 0)),
                ),
                // These could be dynamically generated from a source,
                // for example using `List.generate`
            ],
        ),
    ),
],

// ...

class MyMarker extends StatelessWidget {
    const MyMarker({
        super.key,
        required this.point,
    });
    
    final LatLng point;
    
    @override
    Widget build(BuildContext context) {
        final MyMarkerState state = MyInheritedStateApproach.of(context).state[point];
        return GestureDetector(
            onTap: () {},
            child: Text(state.label),
        );
    }
}
```

{% endcode %}

{% hint style="info" %}
The maintainer team is looking into improving the `MarkerLayer` to improve this situation:

* Providing a 'keep alive' facility\
  This requires a massive change and a lot of implementation work, as it requires very custom render objects - it may also not resolve the issue of states of the same marker across worlds being different (although this needs further investigation), and its impact on performance is uncertain
* Painting a marker multiple times across worlds while only building it once\
  As far as we are aware, this is not possible unless it can be assured that the child tree does not contain any widgets like `RepaintBoundary` which change the way render layers are composited. We would appricate your help if you know how this could be implemented: get in touch with us!

Any contributors would be appreciated!
{% endhint %}

## Handling Gestures

If you need to, for example, handle taps and presses on your marker's child, it's easy! Just wrap the child in something like a `GestureDetector`, or a button.

If you need to be able to drag the marker, check out the community maintained plugin '[flutter\_map\_dragmarker](https://github.com/ibrierley/flutter_map_dragmarker)'.\
Alternatively if you need more control, build it yourself. Because of the way flutter\_map handles gestures, the [following workaround](https://github.com/fleaflet/flutter_map/issues/1729#issuecomment-3768956345) may be required to allow the marker to capture the necessary gesture events:

> Use a `RawGestureDetector` and custom `PanGestureRecognizer` than declares victory in the [gesture arena](https://docs.flutter.dev/ui/interactivity/gestures#gesture-disambiguation). For example:
>
> {% code expandable="true" %}
>
> ```dart
> class EagerPanGestureRecognizer extends PanGestureRecognizer {
>   @override
>   void handleEvent(PointerEvent event) {
>     // Immediately claim victory for this pointer
>     if (event is PointerMoveEvent) resolve(GestureDisposition.accepted);
>     super.handleEvent(event);
>   }
> }
>
> // Inside your marker's child builder:
>
> final gestures = <Type, GestureRecognizerFactory>{};
> if (onDragStart != null || onDragUpdate != null || onDragEnd != null) {
>   gestures[EagerPanGestureRecognizer] =
>       GestureRecognizerFactoryWithHandlers<EagerPanGestureRecognizer>(
>           EagerPanGestureRecognizer.new,
>           (SingleEagerPanGestureRecognizer instance) {
>     instance.onStart = onDragStart;
>     instance.onUpdate = onDragUpdate;
>     instance.onEnd = onDragEnd;
>   });
> }
>
> return RawGestureDetector(
>   gestures: gestures,
>   child: child,
> );
> ```
>
> {% endcode %}

[^1]: [Google Maps \*wink \*wink](https://github.com/flutter/flutter/issues/24213)
