Skip to content
Advertisement

How to assign multiple inputs and outputs to app.callback with hover_feature or click_feature in dash-leaflet?

I’m having trouble getting multiple inputs and outputs to work in Dash-leaflet. Essentially, I want to do the following: on a mouse click place a marker on the map, and when hovering over a country highlight an area of the map with a polygon and display some information about the country being hovered over in a different pane. I implemented each of those functions in a separate app.callback, as in the below code.

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    dl.Map(children=[dl.TileLayer(), 
                     
                     dl.LayerGroup(id="layer"),
                     
                     
                     dl.GeoJSON(url='https://pkgstore.datahub.io/core/geo-countries/countries/archive/23f420f929e0e09c39d916b8aaa166fb/countries.geojson', id="countries",
                                options=dict(style=dict(opacity=0,fillOpacity=0)),
                                hoverStyle=arrow_function(dict(weight=2, color='red', dashArray='', opacity=1)))
                     ],


            style={'width': '1000px', 'height': '500px'}, zoom=3, id='map'),
    
    html.Div(id='country'),
    
    html.Div(id='Country info pane')

])

@app.callback(Output("layer", "children"), [Input("countries", "click_feature")])
def map_click(feature):

    return [dl.Marker(position=[np.random.randint(-90,90),np.random.randint(-185,185)])]


@app.callback(Output('Country info pane', 'children'),
              Input('countries', 'hover_feature'))
def country_hover(feature):
    if feature is not None:
        country_id = feature['properties']['ISO_A3']

        return country_id

@app.callback(Output('layer', 'children'),
              Input('countries', 'hover_feature'))
def country_hover(feature):
    if feature is not None:
        return(dl.Polygon(positions=[[30,40],[50,60]], color='#ff002d', opacity=0.2))
      


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

While each of those callbacks works in isolation (i.e. if I comment out the other callbacks), none of them work if I run the code with two or more of them active.

If I combine the two hover_feature functions like the below, they seem to work together.

@app.callback(Output('Country info pane', 'children'),
              Output('layer', 'children'),
              Input('countries', 'hover_feature'))
def country_hover(feature):
    if feature is not None:
        country_id = feature['properties']['ISO_A3']

        return country_id, dl.Polygon(positions=[[30,40],[50,60]], color='#ff002d', opacity=0.2)

However, the “map_click” function still does not work along with the “country_hover” function. How can I get all three callbacks to work?

Advertisement

Answer

I found out how to do this, I had to add another dl.LayerGroup to the dl.Map object with a different id, then assigned each function to output to a different layer.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement