最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How to add a dash component as a dash-leaflet custom control? - Stack Overflow

programmeradmin5浏览0评论

I'm slowly discovering the dash-leaflet interface coming from ipyleaflet widget lib and there are still some tasks that I don't manage to achieve.

Here I would like to add a dash componenent (in this case a dropdown select) and place it on the map as control so it fits consistently with the leaflet layout when the map is resized.

Here is a map:

import dash_leaflet as dl
from dash import Dash

colorscale = ['red', 'yellow', 'green', 'blue', 'purple']  # rainbow
app = Dash()
app.layout = dl.Map(
    [dl.TileLayer()], 
    center=[56, 10], 
    zoom=6,  
    style={'height': '100vh'},
)

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

And here is the little select that I would like to place on it:

from dash import dcc

dropdown = dcc.Dropdown(
    component_label="toto-label",
    id="toto-id",
    options=[
        {"label": "NDVI (8)", "value": "ndvi8"},
        {"label": "NDVI (16)", "value": "ndvi16"},
    ],
    value="ndvi16",
)

EDIT

to clarify exactly what I'm looking for, I want to mimick what the WidgetControl is doing in ipyleaflet i.e. placing the component in the controls hierarchy with something like "topleft" and without creating dedicated css styling.

I'm slowly discovering the dash-leaflet interface coming from ipyleaflet widget lib and there are still some tasks that I don't manage to achieve.

Here I would like to add a dash componenent (in this case a dropdown select) and place it on the map as control so it fits consistently with the leaflet layout when the map is resized.

Here is a map:

import dash_leaflet as dl
from dash import Dash

colorscale = ['red', 'yellow', 'green', 'blue', 'purple']  # rainbow
app = Dash()
app.layout = dl.Map(
    [dl.TileLayer()], 
    center=[56, 10], 
    zoom=6,  
    style={'height': '100vh'},
)

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

And here is the little select that I would like to place on it:

from dash import dcc

dropdown = dcc.Dropdown(
    component_label="toto-label",
    id="toto-id",
    options=[
        {"label": "NDVI (8)", "value": "ndvi8"},
        {"label": "NDVI (16)", "value": "ndvi16"},
    ],
    value="ndvi16",
)

EDIT

to clarify exactly what I'm looking for, I want to mimick what the WidgetControl is doing in ipyleaflet i.e. placing the component in the controls hierarchy with something like "topleft" and without creating dedicated css styling.

Share Improve this question edited Apr 1 at 8:18 Pierrick Rambaud asked Apr 1 at 5:36 Pierrick RambaudPierrick Rambaud 2,5112 gold badges26 silver badges74 bronze badges 4
  • Could you use different image for these dropdown {"label": "NDVI (8)", "value": "ndvi8"}, {"label": "NDVI (16)", "value": "ndvi16"},? – Subir Chowdhury Commented Apr 1 at 8:32
  • Or could you provide url for each dropdown options? – Subir Chowdhury Commented Apr 1 at 8:41
  • the dropdown is the smallest example I could think about for something much more complicated. In the real use case, I need to add a dropdown, a datepicker and a select that actually triggers the computation of the tile on the GEE servers on the fly. so no creating multiple images for each combination of my parameters is not an option. – Pierrick Rambaud Commented Apr 1 at 8:43
  • Please review the updated code if it works for you. – Subir Chowdhury Commented Apr 1 at 8:47
Add a comment  | 

1 Answer 1

Reset to default 2
import dash
import dash_leaflet as dl
from dash import html, dcc, Output, Input

app = dash.Dash()

dropdown = dcc.Dropdown(
    id="layer-dropdown",
    options=[
        {"label": "OpenStreetMap", "value": "https://{s}.tile.openstreetmap./{z}/{x}/{y}.png"},
        {"label": "Stamen Terrain", "value": "https://stamen-tiles.a.ssl.fastly/terrain/{z}/{x}/{y}.jpg"},
        {"label": "Stamen Toner", "value": "https://stamen-tiles.a.ssl.fastly/toner/{z}/{x}/{y}.png"},
        {"label": "CartoDB Dark", "value": "https://{s}.basemaps.cartocdn/dark_all/{z}/{x}/{y}{r}.png"},
    ],
    value="https://{s}.tile.openstreetmap./{z}/{x}/{y}.png",
    style={"width": "200px"},
)

dropdown_control = html.Div(
    dropdown,
    style={
        "position": "absolute",
        "top": "10px",   # Adjust this to move it lower or higher
        "right": "10px",  # Position it like a Leaflet control
        "zIndex": "1000",  # Ensure it appears above the map
        "background": "white",
        "padding": "5px",
        "border-radius": "5px",
        "box-shadow": "2px 2px 5px rgba(0,0,0,0.3)",
    },
)

app.layout = html.Div(
    [
        html.Div(
            [
                dl.Map(
                    [
                        dl.TileLayer(id="base-layer", url=dropdown.value),  # Dynamic Tile Layer
                    ],
                    id="map",
                    center=[56, 10],
                    zoom=6,
                    style={"height": "100vh", "width": "100%"},
                ),
            ],
            style={"position": "relative"},
        ),
        dropdown_control,  # Add the dropdown separately on top of the map
    ],
    style={"position": "relative"},
)

@app.callback(
    Output("base-layer", "url"),  # Update the TileLayer URL
    Input("layer-dropdown", "value"),
)
def update_map_layer(selected_layer):
    return selected_layer

if __name__ == "__main__":
    app.run(debug=True)
发布评论

评论列表(0)

  1. 暂无评论