kakk11
kakk11

Reputation: 918

Dash leaflet get marker location

I'm using the dash dashboard for plotting point locations on the map, so a user can select the point and some additional data is displayed for the location. It works quite well with MapBox, but I cannot find a way inside dash to cluster the locations. However, I found that dash-plotly library is very good at clustering and tried to change my map to leaflet, but now I'm not able to get the marker ID from clicking on it? I'm sure I'm missing something trivial.

So, is there a way to modify this code to return marker ID when clicking on the marker, instead of just returning the coordinate on the map?

import dash
import dash_html_components as html
import dash_leaflet as dl
from dash.dependencies import Input, Output

markers = [dl.Marker(children=dl.Tooltip("test"), position=a) for a in [(11,11),(33,33), 
    (55,55)]]
cluster = dl.MarkerClusterGroup(id="markers", children=markers, options={"polygonOptions": 
    {"color": "red"}})

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div(
        children=[
        html.Div(
            dl.Map([dl.TileLayer(),
                    dl.LayerGroup(id="layer"),
                    cluster
            ],
                   id="map", style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"})),
        html.P("EHEE"),
        html.Div(id='clickdata')
    ])

@app.callback(Output("clickdata", "children"),
              [Input("map", "click_lat_lng")])
def map_click(click_lat_lng):
    return "{}".format(click_lat_lng)

if __name__ == '__main__':
    app.run_server()

I'd like to keep using the Python interface, I'm not interested in custom work with JavaScript.

Upvotes: 1

Views: 4785

Answers (1)

emher
emher

Reputation: 6024

The simplest way to get the id of the marker, which was clicked, is to listen for property changes on the markers rather than the map itself. With this approach, the maker id information can be extracted from the callback_context. Here is a small example based on your code,

import dash
import dash_html_components as html
import dash_leaflet as dl
from dash.dependencies import Input, Output

positions = [(11, 11), (33, 33), (55, 55)]
markers = [dl.Marker(dl.Tooltip("test"), position=pos, id="marker{}".format(i)) for i, pos in enumerate(positions)]
cluster = dl.MarkerClusterGroup(id="markers", children=markers, options={"polygonOptions": {"color": "red"}})

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([
    html.Div(dl.Map([dl.TileLayer(), cluster], center=(33, 33), zoom=3, id="map",
                    style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"})),
    html.Div(id='clickdata')
])


@app.callback(Output("clickdata", "children"),
              [Input(marker.id, "n_clicks") for marker in markers])
def marker_click(*args):
    marker_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
    return "Hello from {}".format(marker_id)


if __name__ == '__main__':
    app.run_server()

Upvotes: 2

Related Questions