Search code examples
pythoncallbackplotly-dashdash-leaflet

Update the positions' property of Polyline in dash-leaflet through a callback


How is it possible to update the positions property of Polyline through a callback? I tried value and data in the callback's Output property, but it seems it did not work.

import dash_leaflet as dl
from dash import Dash, html, dcc, Output, Input, State, callback

app = Dash()
app.layout = html.Div(
    html.Button(id="btn_run"),
    dl.Map(dl.TileLayer(),
           dl.Polyline(positions=[], id='position-data'),
           center=[56, 10], zoom=6, style={'height': '50vh'}))


@app.callback(Output('position-data', 'value'),
              Input("btn_run", "n_clicks"),
              prevent_initial_call=True)
def on_click(n_clicks):
    positions = [[49.799558, 6.712016], [50.58268, 5.549233]]
    return positions


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

Solution

  • first of all there are some errors in your code:

    • The Map object needs a list of elements (the children parameter), so you need to write the parameters like this: Map([dl.TileLayer(...), dl.Polyline(...)]). Also, each object has (often) some properties. In this case you have: center, zoom, style. These properties must be written outside the children parameter because they are property of the web object. So the result is:
    dl.Map([dl.TileLayer(),
           dl.Polyline(positions=[], id='position-data')],
           center=[56, 10], zoom=6, style={'height': '50vh'})
    
    • The same reasoning applies to the Div object:
    app.layout = html.Div([
        html.Button(id="btn_run"),
        dl.Map([dl.TileLayer(),
               dl.Polyline(positions=[], id='position-data')],
               center=[56, 10], zoom=6, style={'height': '50vh'})
    ])
    

    Now, if you want to change the positions property, why didn't you use it directly? So, in the Output callback write positions and the result is the following:

    @app.callback(Output('position-data', 'positions'),
                  Input("btn_run", "n_clicks"),
                  prevent_initial_call=True)
    def on_click(n_clicks):
        positions = [[49.799558, 6.712016], [50.58268, 5.549233]]
        return positions
    

    enter image description here