Show and Tell - Dash Leaflet

Great, awesome. Thanks for making this possible.

1 Like

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

2 Likes

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:

In my case I would like to show and hide some layers like a checkbox and when I select the ā€œnameā€ of layer that I want to show, map displays this layer (geojson).

The component is here :slight_smile: https://react-leaflet.js.org/docs/en/components#layerscontrol

Excellent package Emil. Thanks for the hard work Emil! Are there plans to implement Marker move event (when draggable=True)?

Hi farry,

yes, that is a good idea. I have just (0.0.20) implemented the feature. Here is a small example,

import dash
import dash_html_components as html
import dash_leaflet as dl
import json

from dash.dependencies import Input, Output

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([
    dl.Map([dl.TileLayer(), dl.Marker(id="marker", draggable=True, position=(56,10))],
           id="map", style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"}),
    html.Div(id="output")
])


@app.callback(Output("output", "children"), [Input("marker", "position")])
def print_position(position):
    return json.dumps(position)


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

Does this support usage of the leaflet iconCreateFunction? I have a custom javascript function from an existing javascript leaflet project that I would like to be able to use in my dash-leaflet implementation.

It would probably require a separate component as you cannot pass function handles from the Python layer to the JS layer. That being said, it would probably be a really simple component, if you already have the icon function.

Thanks Emil. On my computer, the call back seems to be only fired when marker dragging start/finishes. Is that expected? I was expecting a continuous reading of the position.

dash==1.13.4
dash-leaflet ==0.0.20

Yes, that is intended. From a Dash perspective I figured this would be most appropriate. Otherwise, the callback would fire continuously, which might cause performance issues.

Hi Emil,

very impressed with your work.
This is precisely what data-scientists with some programming skills need.
I tried Folium, but need the callbacks.

My question is regarding the Map click events example. I cannot figure out how to add more than one marker to the map (so adding several markers) by clicking. And then the next challenge will be how to delete a marker from the map.
I could do this by rebuilding the map every click, but there must be a better way. Any help?
It would also be great to add the markers as a separate layer, like folium.LayerControl().add_to(map).

I see you are actively working on the project. I hope a heatmap (without callback) will be added, together with the option to turn layers on or off.
Keep up the good work! Much appreciated!

Thanks! One possibility for adding many Marker objects is to append them as children to a Layergroup. The code would be something like,

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

app = dash.Dash()
app.layout = html.Div([
    dl.Map([dl.TileLayer(), dl.LayerGroup(id="container", children=[])], id="map",
           center=(56, 10), zoom=10, style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"})
])

@app.callback(Output("container", "children"), [Input("map", "click_lat_lng")], [State("container", "children")])
def add_marker(click_lat_lng, children):
    children.append(dl.Marker(position=click_lat_lng))
    return children

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

Similarly, you could remove markers by removing children from the Layergroup. Yes, i am still working on the project from time to time. Currently, i am working on a new marker clustering component :slight_smile:

Awesome!
Now trying to remove a marker when clicked upon. Is that possible?
It seems that clicking on an icon is clicking on the container layer instead of on the map, so there is no callback.
So I guess the calback decorator should have something like Input(ā€œcontainerā€, ā€œclick_lat_lngā€), but that doesnā€™t work.

1 Like