Search code examples
pythonleafletplotly-dashdash-leaflet

Mapping dash-leaflet controls to other buttons outside the map


Dash-leaflet allows adding controls, such as ZoomControl, MeasureControl, or EditControl to map layers. I was wondering if it is possible to use Dash buttons to perform the same actions as these controls.

For example, is it possible to zoom in/out using a couple of Dash buttons placed outside the map?


Solution

  • To use Dash buttons, you would need to create callbacks that perform the desired modifications of the map properties. Here is a small example where Dash buttons mimic the behavior of the ZoomControl,

    import dash_html_components as html
    import dash_leaflet as dl
    from dash_extensions.enrich import Input, Output, State, Dash
    
    zoom_min, zoom_max, zoom0 = 1, 18, 6  # min/max zoom levels might depend on the tiles used 
    app = Dash(prevent_initial_callbacks=True)
    app.layout = html.Div([
        dl.Map(dl.TileLayer(), style={'width': '1000px', 'height': '500px'}, id="map", zoom=zoom0),
        html.Button("Zoom in", id="zoom_in"), html.Button("Zoom out", id="zoom_out")
    ])
    
    
    @app.callback(Output("map", "zoom"), Input("zoom_in", "n_clicks"), State("map", "zoom"))
    def zoom_in(_, zoom):
        return min(zoom_max, zoom + 1)
    
    
    @app.callback(Output("map", "zoom"), Input("zoom_out", "n_clicks"), State("map", "zoom"))
    def zoom_out(_, zoom):
        return max(zoom_min, zoom - 1)
    
    
    if __name__ == '__main__':
        app.run_server()
    

    For more complex controls like the EditControl, it is not trivial to mimic the behavior via Dash buttons. In this case, you could try to change the appearance of the buttons using CSS, or to modify the component in the React layer to fit your needs.