如何在Leaflet中使用字典按分区为城市要素设置着色样式
Leaflet 按城市分区着色实现方案
原代码核心问题
- 语法错误:if 条件的括号范围错误,
if (feature.properties.name) in zone0逻辑完全不符合预期,应该将整个判断逻辑放在括号内 - 运算符误用:JS 中
in运算符用于检测对象属性/数组索引是否存在,不能直接检测数组是否包含指定元素 - 冗余语法:style 函数中 return 后不需要加 break,属于无效语法还会触发报错
- 额外问题:弹窗内容里的 table 标签未正确闭合,会导致弹窗渲染异常
修正方案
我们可以用数组includes方法判断城市名是否属于对应分区,也可以转为映射表提升查询性能,以下是可直接运行的修正代码:
第一步:定义分区与映射规则
// 定义各分区包含的城市列表 const zone0 = ['A', 'B', 'C', 'D', 'R', 'S', 'T']; const zoneI = ['E', 'F', 'G', 'K', 'V', 'Z']; const zoneIII = ['H', 'I', 'M', 'N', 'L'];
第二步:修正GeoJSON的style逻辑
var commune = new L.GeoJSON.AJAX("{% url 'ville' %}", { style: function(feature) { const cityName = feature.properties.name; // 用includes判断城市所属分区 if (zone0.includes(cityName)) { return { color: 'red', fillOpacity: 0.8 }; } if (zoneI.includes(cityName)) { return { color: 'purple', fillOpacity: 0.8 }; } if (zoneIII.includes(cityName)) { return { color: 'green', fillOpacity: 0.8 }; } // 未匹配到分区的默认样式 return { color: 'gray', fillOpacity: 0.5 }; }, onEachFeature: function (feature, layer) { if (feature.properties) { // 修正闭合table标签的错误 var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>Ville</th><td>" + feature.properties.name + "</table>"; layer.on({ click: function (e) { layer.bindPopup(content).openPopup(e.latlng); } }); } } });
兼容与性能优化建议
- 如果需要兼容IE等不支持
includes的旧浏览器,可以把zone0.includes(cityName)替换为zone0.indexOf(cityName) !== -1,效果完全一致 - 如果城市数量较多,可以把分区列表转为键值对映射表,查询时间复杂度从O(n)降到O(1),示例如下:
const zoneMap = { 'A': 'zone0', 'B':'zone0', // 其余zone0城市以此类推 'E': 'zoneI', 'F':'zoneI', // 其余zoneI城市以此类推 'H': 'zoneIII', 'I':'zoneIII' // 其余zoneIII城市以此类推 } // style函数里直接取值判断 const zone = zoneMap[feature.properties.name] if(zone === 'zone0') return {color: 'red', fillOpacity: 0.8}
内容的提问来源于stack exchange,提问作者Saliha Alger
相关产品推荐
相关产品推荐

