Black Lives Matter. Please consider donating to Black Girls Code today.

Show and Tell - Dash Leaflet

If you need to change multiple properties of the marker, you can recreate it through a callback as shown here,

If you only need to move the marker, you can update it’s position property from the callback instead.

I am not able to move the marker after updating the position property in callback.I am sharing the code if I have mistaken somewhere please correct me.

import dash
import dash_leaflet as dl
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Output, Input

import pandas as pd

loc=pd.read_csv(“D:\Dash_Arnab##PAGE\in.csv”)
loc1=loc.filter([‘city’, ‘lat’, ‘lng’,‘population’, ‘population_proper’])
app = dash.Dash()

app.layout = html.Div([

                 html.Div([          
                html.H6("Select City:",style={'paddingRight':'30px'}),
                dcc.Dropdown(id='city',
                             options=[{'label':i,'value':i} for i in loc1.city],
                                      value='Mumbai')],
                             style={ 'display': 'inline-block','padding':'100px'}),
                             
                
    
dl.Map(id="map", style={'width': '1000px', 'height': '500px'}, center=[20.5937, 78.9629], zoom=10, children=[
        dl.TileLayer(id="tile"),
        # Marker with tool tip and popup.
        dl.Marker(id='mark',position=[22.56262,88.36304399999999], children=[
            dl.Tooltip("Marker tooltip"),
            dl.Popup([
                html.H1("Marker popup"),
                html.P("with inline html")
            ])
        ])

])
])
#url=“https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
@app.callback(Output(“mark”, “position”),
[Input(“city”, “value”)])

def city_update(sel_city):
loc_city=loc1[loc1.city==sel_city].iloc[:,1:3]

return dl.Marker(position=[loc_city.lat, loc_city.lng])

if name == ‘main’:
app.run_server(debug=False)

Since i don’t have the data, i can’t run the code to examine the exact cause of the error. However, i can see that you are targeting the position property, but returning a Marker object, which is definitely an issue. When you target the position property, you should return the position only, e.g. something like

return [loc_city.lat, loc_city.lng]

https://simplemaps.com/data/in-cities

this is the dataset,I have used in my code.I have tried your solution to return the position but still the marker is not moving and also if you can help me with Tooltip to pop out as city name.

Thank you again for making the python package!
May I ask if it is possible to acquire the user’s location using Leaflet Geo-Location Feature?

Thank you!

Awesome package. I want to know if is there a way to print n markets that are in a pandas dataframe. Thanks!.

I have just added a LocateControl component to enable geolocation, so now it is possible. Here is a small example,

import dash
import dash_html_components as html
import dash_leaflet as dl

app = dash.Dash(external_stylesheets=['https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'])
app.layout = html.Div([
    dl.Map(children=[dl.TileLayer(url="https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), dl.LocateControl()],
           style={'width': "100%", 'height': "100%"}, center=[55.5, 10.5], zoom=8),
], style={"position": "relative", 'width': '1000px', 'height': '500px'})

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

Thanks! Yes, you can add all the marker that you need. The exact code depends on the structure of you dataframe, but here is a small example,

import dash
import dash_html_components as html
import dash_leaflet as dl
import pandas as pd
import numpy as np

# Create example data frame.
lats = [56, 56, 56]
lons = [10, 11, 12]
df = pd.DataFrame(columns=["lat", "lon"], data=np.column_stack((lats, lons)))

# Create markers from data frame.
markers = [dl.Marker(position=[row["lat"], row["lon"]]) for i, row in df.iterrows()]

# Create example app.
app = dash.Dash(external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css'])
app.layout = html.Div([
    dl.Map(children=[dl.TileLayer(url="https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), dl.LayerGroup(markers)],
           style={'width': "100%", 'height': "100%"}, center=[56, 11], zoom=9, id="map"),
], style={'width': '1000px', 'height': '500px'})



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

I have just added a MarkerClusterGroup and a GeoJSON component (version 0.0.12). Furthermore, i have created a documentation page with an interactive example gallery :slight_smile:

2 Likes

This is fantastic. Thank you for your contribution!

1 Like

Great, awesome. Thanks for making this possible.

1 Like

this guy works very hard, and creates awesome possibilities.
Respect.

1 Like

Thanks so much for all the hard work on this!

Quick question - is it possible to use fitBounds with this? We are layering geotiffs and would be great to automatically fit to the image bounds.

Hello everyone
Emil thank you very much for developping this tool! it’s so great!
I am french ad i would like to use geoJson files in leaflet but I have some problems with encoding
Indeed I have some cities that are called Quesnoy-sur-Deûle or also Annœullin and I don’t know how to deal with encoding UTF-8 with dash … I added “meta_tags” in the ‘app’ section but it did not successful. Can you help me please?

Thanks! Yes, the map has a bounds property for this purpose. Here is a small example,

import dash
import dash_leaflet as dl
import dash_html_components as html
from dash.dependencies import Output, Input

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([dl.Map(dl.TileLayer(), style={'width': '1000px', 'height': '500px'}, id="map"),
                       html.Button("Click me", id="btn")])


@app.callback(Output("map", "bounds"), [Input("btn", "n_clicks")])
def func(n_clicks):
    return [(56, 10), (57, 11)]


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

Thanks! Regarding the encoding issue; without seeing the code (and the geojson), it’s hard to tell what is going on. However, it seems to be like it is a more general issue, i.e. not related to Dash Leaflet. To increase the probability that you get help, i would recommend that you post a separate question including some minimal code (and the geojson file).

Hello :slight_smile:
Yes Indeed it was a “problem” with Python because I added 'encoding=‘uttf8’ in the parameters of “with open” when I read geojson file.

However I have another doubt. I would like to display popups when I click on the features so I made a callback like this :
@app.callback(output (‘geojson’,‘feautreOptions’), Input(‘geojson’,'featureHover))
def function(feature):
Feature_option=dict(id=dict(contentPopup=
[feature[‘properties’]['nom]))
return Feature_option

I don’t know if It’s the correct way to make that but I have a message “Nonetype object is not suscriptable”

Hi Emil - Thanks for this. But it seems like you have to programatically determine the bounds? It can’t get it automatically from the geotiff? (I believe FitBounds can figure it out on it’s own.)

No worries if it’s not available at this point - just trying to figure it all out and new to both leaflet and react.

It is great! I would like to know if it’s difficull to added also Control Layer? I don’t know React.js :frowning:

If you can link to a react library (or next best, a leaflet plugin) that provides the control layer that you need and/or describe you usecase, I can take a look :upside_down_face: