Dash Leaflet 点击功能事件

3

我一直在使用Dash Leaflet来创建自己的地图仪表板,可以通过交互式地图可视化事物非常棒。然而,有一件事情困扰了我很久 - 如何处理多边形或标记上发生的点击事件。为了解释这个问题,我创建了下面这个简单的示例。

import geopandas as gpd
import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash import Dash, html, Output, Input
import json

location = gpd.GeoDataFrame(geometry=gpd.points_from_xy([-74.0060], [40.7128]))
app = Dash()
app.layout = html.Div(
                    children=[
                        dl.Map(
                            center=[39, -98], 
                            zoom=4, 
                            children=[
                                dl.TileLayer(),
                                dl.GeoJSON(data=dlx.geojson_to_geobuf(json.loads(location.to_json())), format='geobuf', id='locations', zoomToBoundsOnClick=True)], 
                            style={'width': '100%', 'height': '80vh'}, id="map"),
                        html.Div(id='counter')])
counter = 0
@app.callback(Output('counter', 'children'), Input('locations', 'click_feature'))
def update_counter(feature):
    global counter
    counter += 1
    return str(counter)

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

当您首次加载仪表板时,它的外观如下所示: enter image description here

在地图下方有一个包含geojson被点击次数的div(我知道初始化时函数会被调用,但这不是这个问题的重点)。第一次单击标记时,div将得到更新并且该数字会增加。然而,如果您尝试再次单击标记,则div不会更新,数字也不会增加。我已经发现只有在单击不同的标记时才会触发事件(您可以向geojson添加坐标并在两个标记之间单击以进行测试)。在该示例中,这是一个计数器,但我正在尝试每次单击地理JSON时过滤我的数据到所点击的位置。因此,我的问题是,在每次单击geojson时,您需要做什么才能过滤数据?

我注意到的另一件小事是,即使我将zoomToBoundsOnClick设置为true,地图也不会缩放到我单击的标记上。这不是什么大问题,但这将是一个很好的功能。因此,如果有人知道如何使其工作,那也将不胜感激。

1个回答

0
在Dash中,只有当属性发生更改时,回调才会被调用。如果您两次单击相同的功能,则click_feature属性不会更改,因此不会调用回调。如果您想在每次单击时调用回调,可以针对n_clicks属性 - 它在每次单击时递增,因此回调将在每次单击时触发。

阅读完我的问题后,我认为我可能错过了一个重要的组成部分。我正在使用点击来过滤数据,因此n_clicks的问题在于它无法告诉您点击了哪个多边形(或在这种情况下是标记)。我希望每次单击geo_json时都会过滤数据。很抱歉我没有更明确地说明。我将编辑我的问题以包括那个。 - Robert Allan
可以通过将回调配置为'n_clicks'作为'Input'(以确保在每次单击时触发回调)和'click_feature'作为'State'(以获取传递给回调的所需数据)来实现。 - emher
2
我刚试了一下,它有效!为了让其他人也能看到这个,最好在你的答案中包含这个。基本上代码应该是@app.callback(Output('table', 'data'), [Input('locations', 'feature_click'), Input('locations', 'n_clicks')],在此之下你需要写def geo_filter(feature, n_clicks):。在函数中,你需要写return df[(df['lat'] == feature['properties']['lat']) & (df['lon'] == feature['properties']['lon'])] if feature else None。你可以将函数设置为除数据表以外的其他内容,但这是一般的想法。谢谢! - Robert Allan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接