Search code examples
pythonleafletplotly-dashfolium

Trying to add on folium map to generate in a Dash App


Trying to create a dash app that takes in latitude, longitude, and zoom, and outputs a map with a marker at the latitude and longitude coordinates.

The problem is that the map will not load and I think the error has to do with adding the marker, because the map loads and works fine with out the code containing the marker.

import dash_leaflet as dl
from dash import Dash, html, dcc
from dash.dependencies import Input, Output, State
import os
import folium 

app = Dash()  
app.layout = html.Div([
    html.H1(id = 'textout'),
    folium.Map(id = "output-state"),
    dcc.Input(id = 'lat', value = 39.298, type = 'number'),
    dcc.Input(id = 'long', value = -76.590, type = 'number'),
    dcc.Input(id = 'zoom', value = 11, type = 'number'),
    html.Button('Submit', id='submit-button')
])

@app.callback(Output('output-state', 'children'),
              Input('submit-button', 'n_clicks'),
              State('lat', 'value'),
              State('long', 'value'),
              State('zoom', 'value'))
def update_output(n_clicks, lat, long, zoom):
    if n_clicks is not None:
        m = folium.Map(location = ['lat', 'long'], zoom_start = 'zoom')
        folium.Marker(['lat', 'long'], popup = "You Are Here!!!").add_to(m)
        return m

@app.callback(Output('textout', 'children'),
              Input('submit-button', 'n_clicks'),
              State('lat', 'value'),
              State('long', 'value'),
              State('zoom', 'value'))
def update_text(n_clicks, lat, long, zoom):    
        return  'Lat {}, Long {},  zoom {}, number of clicks {} times'.format(lat, long, zoom, n_clicks)

Solution

  • I'm new to using dash-leaflet. folium has some answers here. i tried it with folium but it didn't show the map. So i modified the code using a live riley that can handle leaflet in dash, i added dl.Map() as return value of submit and set the graph size, centre position, zoom value, plus tile layer and popup. The hints that led to this came from this answer.

    import dash_leaflet as dl
    from dash import Dash, html, dcc
    from dash.dependencies import Input, Output, State
    
    app = Dash(__name__)
    
    app.layout = html.Div([
        html.H1(id = 'textout'),
        html.Div(id='output-state'),
        dcc.Input(id = 'lat', value = 39.298, type = 'number'),
        dcc.Input(id = 'long', value = -76.590, type = 'number'),
        dcc.Input(id = 'zoom', value = 11, type = 'number'),
        html.Button('Submit', id='submit-button')
    ])
    
    @app.callback(Output('output-state', 'children'),
                  Input('submit-button', 'n_clicks'),
                  State('lat', 'value'),
                  State('long', 'value'),
                  State('zoom', 'value'))
    def update_output(n_clicks, lat, long, zoom):
        if n_clicks is not None:
            return dl.Map([dl.TileLayer(),
                          dl.Marker(position=(lat, long),
                                    children=[dl.Popup('You Are Here!!!')]
                                    )],
                          style={'width': '1000px', 'height': '500px'},
                        center=[lat, long],
                        zoom=zoom)
     
    
    @app.callback(Output('textout', 'children'),
                  Input('submit-button', 'n_clicks'),
                  State('lat', 'value'),
                  State('long', 'value'),
                  State('zoom', 'value'))
    def update_text(n_clicks, lat, long, zoom):    
            return  'Lat {}, Long {},  zoom {}, number of clicks {} times'.format(lat, long, zoom, n_clicks)
    
    if __name__ == "__main__":
        app.run_server(debug=True)
    

    enter image description here