我一直在使用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)
在地图下方有一个包含geojson被点击次数的div(我知道初始化时函数会被调用,但这不是这个问题的重点)。第一次单击标记时,div将得到更新并且该数字会增加。然而,如果您尝试再次单击标记,则div不会更新,数字也不会增加。我已经发现只有在单击不同的标记时才会触发事件(您可以向geojson添加坐标并在两个标记之间单击以进行测试)。在该示例中,这是一个计数器,但我正在尝试每次单击地理JSON时过滤我的数据到所点击的位置。因此,我的问题是,在每次单击geojson时,您需要做什么才能过滤数据?
我注意到的另一件小事是,即使我将zoomToBoundsOnClick设置为true,地图也不会缩放到我单击的标记上。这不是什么大问题,但这将是一个很好的功能。因此,如果有人知道如何使其工作,那也将不胜感激。
@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