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

Leaflet应用中JQuery+Flask过滤GeoJSON图层失效问题求助

Leaflet复选框过滤GeoJSON无响应问题解决

问题描述

在Leaflet中使用复选框过滤GeoJSON图层,图层可正常显示,但点击复选框后无任何反应。Flask服务器显示请求已被接收,数据来自PostgreSQL,需修改Python代码实现地图显示过滤后的信息。

相关代码

JS代码

function refreshroutesfermees(whr) {   
    if (whr) {
        var objData = {tbl:'routes_fermees_adn', flds:"id, cpx_numero, cpx_gestio, fermeture, dep", where:whr};
    } else {
        var objData = {tbl:'routes_fermees_adn', flds:"id, cpx_numero, cpx_gestio, fermeture, dep"};
    }
    $.ajax({
    url: '/routes_fermees', ///retrieve my data from app.py
    data: objData,
    type: 'POST',          
    success: function (response) {
         if (response=="ERROR"){
            alert (response);
        } else { 
        arProjectIDs=[];
        if (lyrroutesfermees) {
            ctlLayers.removeLayer(lyrroutesfermees);
            lyrroutesfermees.remove();
        }
        lyrroutesfermees = L.geoJSON(response, 
        {style:styleroutesfermees, onEachFeature:processroutesfermees});
        ctlLayers.addOverlay(lyrroutesfermees, "routes fermées");
        arProjectIDs.sort(function(a,b){return a-b});
        }
},
    error: function (xhr, status, error) {
        alert("ERROR: " + error);
    }
});
}

HTML复选框代码

$("#btnFilterroutesfermees").click(function(){
              var arTypes=[];
              var cntChecks=0;
                $("input[name=fltferme]").each(function(){
                    if (this.checked) {
                        if(this.value=='ferm 38'){
                            arTypes.push("'38'");
                            cntChecks++;
                        }
                        if(this.value=='ferm 73'){
                            arTypes.push("'73'");
                            cntChecks++;
                        }
                        if(this.value=='ferm 74'){
                            arTypes.push("'74'");
                            cntChecks++;
                        }
                    }
                });
              //  alert(cntChecks);
                if (cntChecks==0) {
                    refreshroutesfermees("1=2");
                } else if (cntChecks==3){ ////le nombre de checkbox
                    refreshroutesfermees();
                } else {
                //    alert("type IN ("+arTypes.toString()+")");
                refreshroutesfermees("dep IN ("+arTypes.toString()+")");
                }
            });

app.py原代码

@app.route('/routes_fermees', methods=["POST", "GET"])
def routes_fermees():
        cur = con.cursor()
        cur.execute("""
            select json_build_object(
                'type', 'FeatureCollection',
                'features', json_agg(ST_AsGeoJSON(routes_fermees_adn.*)::json)
            ) as geojson
            from routes_fermees_adn
            """)
        return cur.fetchone()[0]

Flask生成的请求链接

GET /routes_fermees?tbl=routes_fermees_adn&flds=id%2C%20cpx_numero%2C%20cpx_gestio%2C%20fermeture%2C%20dep

问题原因

原app.py代码未处理前端传递的where过滤参数,无论前端发送什么过滤条件,后端始终返回全量数据,导致复选框点击后地图无变化。

修改方案

修改app.py代码,接收前端过滤条件并动态构造SQL查询,同时处理空结果和异常:

from flask import request, jsonify

@app.route('/routes_fermees', methods=["POST", "GET"])
def routes_fermees():
    cur = con.cursor()
    # 获取前端传递的where参数,默认空字符串
    where_clause = request.form.get('where', '')
    # 基础SQL语句
    sql = """
        select json_build_object(
            'type', 'FeatureCollection',
            'features', json_agg(ST_AsGeoJSON(routes_fermees_adn.*)::json)
        ) as geojson
        from routes_fermees_adn
    """
    # 追加WHERE子句(如果有过滤条件)
    if where_clause:
        sql += f" WHERE {where_clause}"
    
    try:
        cur.execute(sql)
        result = cur.fetchone()[0]
        # 无匹配数据时返回空的FeatureCollection,避免Leaflet报错
        if result is None:
            return jsonify({"type": "FeatureCollection", "features": []})
        return result
    except Exception as e:
        con.rollback()
        return "ERROR"
    finally:
        cur.close()

额外提示

  1. SQL注入风险:当前直接拼接where_clause存在安全隐患,建议优化为参数化查询。例如前端传递dep数组,后端用IN (%s)并传入参数列表。
  2. 请求方式一致性:JS代码设置type: 'POST'但实际请求显示为GET,需确保前后端请求方式统一,若改为GET则需用request.args.get获取参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:57:14