Chris Raper
Chris Raper

Reputation: 21

Dash Leaflet Marker Events

I'm trying to get my Dash Leaflet map to respond to when a user clicks on a marker. Below I've made a minimal example app to illustrate my problem. Currently the app does not respond to clicks on the marker. How can I fix this? Note that I'm using a pattern matching callback because the markers will be dynamically added/removed to/from the map rather than statically at start-up.

# import third party packages
from dash import Dash, html, Output, Input, ctx, ALL
import dash_bootstrap_components as dbc
import dash_leaflet as dl
import dash_leaflet.express as dlx

THEME_URL = dbc.themes.LUX
THEME_NAME = "lux" # must be a dbc theme name, lowercase
DBC_CSS = ("https://cdn.jsdelivr.net/gh/AnnMarieW/[email protected]/dbc.min.css")
app = Dash(__name__, external_stylesheets=[THEME_URL, DBC_CSS])

# define app layout major components
navbar = dbc.Navbar([
    # Use row and col to control vertical alignment of logo / brand
    dbc.Row([
        dbc.Col(
            dbc.NavbarBrand("Leaflet Test", className="ms-2 text-white fs-2"),
            width={"size": 3},
            style={"marginLeft": 30}
        ),
    ], align="center"),
], color="primary")

map_page = dbc.Container([
    dbc.Container([
        dbc.Checklist(
            options=[
                {"label": "Place of Birth", "value": "birth"},
                {"label": "Place of Death", "value": "death"},
            ],
            value=["birth"],
            id="place-options",
            inline=True,
            className="mb-2",
        ),
    ], fluid=True),
    dbc.Container(id="map-container", fluid=True)
], fluid=True)

app.layout = html.Div([
    navbar,
    dbc.Tabs([
        dbc.Tab(
            dbc.Card(dbc.CardBody(map_page), style={"border": "none"}),
            label="Map Filter",
            activeTabClassName="fw-bold fst-italic",
            tabClassName="fs-5",
        ),
    ]),
    
    dbc.Modal("Hello", is_open=False, id="bio-modal"),
])


# return leaflet map so it renders properly when app is started
@app.callback(
    Output("map-container", "children"),
    Input("place-options", "value"),
)
def draw_map(_):
    markers = [{
        "lat": 0,
        "lon": 0,
        "name": "marker0",
        "id": {"type": "marker-click", "index": 0}
    }]
    markers = dlx.dicts_to_geojson([{**c, **dict(tooltip=c['name'])} for c in markers])
    children = [dl.TileLayer(), dl.GeoJSON(data=markers, cluster=True)] # zoomToBoundsOnClick=True
    return  dl.Map(children, center=[0,0], zoom=6, style={"height": "78vh", "width": "96vw"}, id="map")


@app.callback(
    Output("bio-modal", "is_open"),
    Input({"type": "marker-click", "index": ALL}, "n_clicks"),
    prevent_initial_call=True,
)
def show_modal(_):
    print(ctx.triggered_id)
    return True


if __name__ == '__main__':
    app.run(debug=True)

Upvotes: 0

Views: 322

Answers (1)

Chris Raper
Chris Raper

Reputation: 21

My problem was resolved with the answer given here: https://community.plotly.com/t/dash-leaflet-click-events/83769/2

Upvotes: 0

Related Questions