You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Dash Python中无法从Geopandas导出GeoJSON文件的问题求助

解决Dash中导出GeoJSON时的ValueError问题

问题场景

在Dash应用中尝试通过下载按钮,将从GeoJSON读取的GeoPandas数据重新导出为GeoJSON文件时,触发如下错误:

ValueError: Unknown na method <_io.StringIO object at 0x000002A38E2941F0>

原代码如下:

from dash import Dash, dcc, html, Input, Output
import geopandas as gpd

app = Dash(__name__)
app.layout = html.Div(
    [
        html.Button("Download JSON", id="btn_json"),
        dcc.Download(id="download-dataframe-json"),
    ]
)

df = gpd.read_file('GeoJSON Files/blocks.geojson')


@app.callback(
    Output("download-dataframe-json", "data"),
    Input("btn_json", "n_clicks"),
    prevent_initial_call=True,
)
def func(n_clicks):
    return dcc.send_data_frame(df.to_json, "mydf.json")


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

问题原因

dcc.send_data_frame是为普通Pandas DataFrame设计的工具函数,它会自动向传入的导出方法(这里是df.to_json)传递na_rep参数,但GeoPandas的GeoDataFrame.to_json方法并不支持该参数,导致这个参数被错误解析为NA值处理方法,进而触发报错。

解决方案

有两种可行的解决方式:

方法1:使用dcc.send_string直接传递GeoJSON字符串

直接调用GeoDataFrame.to_json()生成字符串,再通过dcc.send_string返回:

from dash import Dash, dcc, html, Input, Output
import geopandas as gpd

app = Dash(__name__)
app.layout = html.Div(
    [
        html.Button("Download JSON", id="btn_json"),
        dcc.Download(id="download-dataframe-json"),
    ]
)

df = gpd.read_file('GeoJSON Files/blocks.geojson')


@app.callback(
    Output("download-dataframe-json", "data"),
    Input("btn_json", "n_clicks"),
    prevent_initial_call=True,
)
def func(n_clicks):
    geojson_str = df.to_json()
    return dcc.send_string(geojson_str, "mydf.geojson")


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

方法2:包装to_json方法,忽略多余参数

创建一个包装函数,过滤掉dcc.send_data_frame传递的na_rep参数:

from dash import Dash, dcc, html, Input, Output
import geopandas as gpd

app = Dash(__name__)
app.layout = html.Div(
    [
        html.Button("Download JSON", id="btn_json"),
        dcc.Download(id="download-dataframe-json"),
    ]
)

df = gpd.read_file('GeoJSON Files/blocks.geojson')

def to_geojson(df, **kwargs):
    # 过滤掉GeoDataFrame.to_json不支持的参数
    kwargs.pop('na_rep', None)
    return df.to_json(**kwargs)

@app.callback(
    Output("download-dataframe-json", "data"),
    Input("btn_json", "n_clicks"),
    prevent_initial_call=True,
)
def func(n_clicks):
    return dcc.send_data_frame(to_geojson, "mydf.geojson", df=df)


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

测试GeoJSON数据

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Block_Name":"East-Block","Status":"Production","Operator":"A","num_wells":20,"sq_km":145.97,"est_reserve":100},"geometry":{"coordinates":[[[96.4001057373053,5.208656351062942],[96.43375136718726,5.221648609300516],[96.46259047851515,5.23737571951817],[96.46121718750072,5.279084831409563],[96.35684707031174,5.279768564031215],[96.35753371582075,5.340617736210092],[96.26140334472717,5.341985064196123],[96.26140334472717,5.261307518914151],[96.32663466796942,5.23053789406255],[96.4001057373053,5.208656351062942]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"West-Block","Status":"Production","Operator":"B","num_wells":50,"sq_km":171.38,"est_reserve":420},"geometry":{"coordinates":[[[96.1500638674625,5.274467547614364],[96.14897384519247,5.419171436272961],[96.01490110586337,5.42134172287426],[96.01526444661994,5.383360416138984],[96.07521567152321,5.3826369393847955],[96.07557901227983,5.355867695999478],[96.03488484749829,5.355867696870973],[96.03452150673985,5.334162042989206],[96.0501451592911,5.327288425995064],[96.06431544881394,5.305219978512483],[96.07812239757834,5.292557397961701],[96.10500961359554,5.285683317057433],[96.13117014809939,5.279894558164472],[96.14025366702509,5.278809159853225],[96.1500638674625,5.274467547614364]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"South-Block","Status":"Exploration","Operator":"A","num_wells":0,"sq_km":48.74,"est_reserve":150},"geometry":{"coordinates":[[[96.15020619743746,5.321413143458614],[96.15075239154925,5.274369183512903],[96.15921840028875,5.269746173698309],[96.19062456174476,5.259684209917438],[96.21137993801023,5.259140315346897],[96.23814344951205,5.262403675642247],[96.26108360222605,5.263763404046799],[96.26108360222605,5.320325462349771],[96.15020619743746,5.321413143458614]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"Center-Block","Status":"Exploration","Operator":"C","num_wells":0,"sq_km":48.98,"est_reserve":120},"geometry":{"coordinates":[[[96.14996393515247,5.321933704052],[96.26084133994107,5.320846023863609],[96.26138753405411,5.3417835292513445],[96.35451363019473,5.340967795663914],[96.35451363019473,5.36924592531598],[96.29224750139701,5.369789722668301],[96.29197440434115,5.401329137491388],[96.33922019505121,5.401057252985197],[96.33922019505121,5.419001368471612],[96.14887154692752,5.419545121233369],[96.14996393515247,5.321933704052]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"North-Block","Status":"Production","Operator":"A","num_wells":30,"sq_km":64.55,"est_reserve":220},"geometry":{"coordinates":[[[96.08469351270912,5.419774728990944],[96.21141054675434,5.419774728990944],[96.33102705734086,5.41868722339008],[96.33048086322776,5.43826202425123],[96.24745935816333,5.438805759641596],[96.24745935816333,5.451311537935112],[96.30644832228882,5.451855261522326],[96.30590212817572,5.467079321826603],[96.15952210608873,5.466535612046528],[96.16006830020183,5.439893228949643],[96.08523970682091,5.440980696292215],[96.08469351270912,5.419774728990944]]],"type":"Polygon"}}]}

内容的提问来源于stack exchange,提问作者naranara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:22:01