通过回调向Dash Leaflet地图添加新多边形的问题求助
问题分析与解决方案
你的代码核心问题有两个:
- 合并几何时没有构建正确的GeoDataFrame结构,导致生成的GeoJSON无法被Dash Leaflet正确解析;
- 返回的是JSON字符串而非Python字典,不符合
dl.GeoJSON组件data属性的要求。
以下是修正后的完整代码,附带关键修改说明:
import pandas as pd import json from dash import Dash, dcc, html, Input, Output, State import dash_leaflet as dl import geopandas as gpd lat1, lon1 = 36.215487, -81.674006 app = Dash() input_details = html.Div([ html.Div([ html.Div(['Buffer Distance'], style={'width': '37%', 'display': 'inline-block'}), dcc.Input( value=100, id="buffer-distance", type='number', placeholder='Required', ), ]), ]) default_map_children = [ dl.TileLayer(), dl.FeatureGroup([ dl.EditControl(id="edit_control"), ]), dl.GeoJSON(id='map-geojsons', style={"color": "#ff0000", "weight": 2}) # 自定义样式区分图形 ] map_input_results_tab = html.Div( [ html.H2('Add Shapes to Map an Area of Interest'), dl.Map( id='leaflet-map', style={'width': '100%', 'height': '50vh'}, center=[lat1, lon1], zoom=16, children=default_map_children ) ]) app.layout = html.Div([input_details, map_input_results_tab]) @app.callback( Output('map-geojsons', 'data'), Input('edit_control', 'geojson'), State('buffer-distance', 'value'), prevent_initial_call=True # 防止初始空值触发回调 ) def update_estimates(drawn_geojson, perim_clear): if not drawn_geojson.get("features") or perim_clear is None: return None # 加载绘制的GeoJSON为GeoDataFrame gdf = gpd.GeoDataFrame.from_features(drawn_geojson["features"]) gdf = gdf.set_crs(crs=4326) utm_crs = gdf.estimate_utm_crs() if utm_crs is None: # 无法估算UTM坐标系时直接返回原图形 return drawn_geojson gdf_utm = gdf.to_crs(crs=utm_crs) # 生成缓冲后的几何,过滤空几何(避免缓冲距离过大导致图形消失) buffered_gdf = gdf_utm.copy() buffered_gdf['geometry'] = buffered_gdf['geometry'].buffer(-perim_clear) buffered_gdf = buffered_gdf[~buffered_gdf['geometry'].is_empty] # 合并原图形和缓冲后的图形,转回WGS84坐标系 combine_gdf = pd.concat([gdf_utm, buffered_gdf], ignore_index=True).to_crs(crs=4326) # 将GeoDataFrame转为Python字典(而非JSON字符串)返回 return json.loads(combine_gdf.to_json()) if __name__ == '__main__': app.run_server(debug=True, port=8052)
关键修改点说明:
- 修正GeoDataFrame合并逻辑:不再直接合并几何Series,而是复制原GeoDataFrame并替换几何列,确保每个图形都是独立的Feature;
- JSON格式转换:使用
json.loads()将GeoJSON字符串转为Python字典,符合dl.GeoJSON组件的数据要求; - 空几何过滤:添加
buffered_gdf = buffered_gdf[~buffered_gdf['geometry'].is_empty],避免缓冲距离过大导致的无效几何; - UTM坐标系校验:增加对
estimate_utm_crs()返回值的判断,防止无法估算坐标系时出错; - 回调优化:添加
prevent_initial_call=True,避免应用启动时的空值触发回调; - 样式自定义:给
dl.GeoJSON添加默认样式,方便区分原图形和缓冲后的图形。
内容的提问来源于stack exchange,提问作者jhthompson12
相关产品推荐
相关产品推荐

