03-从一个点到一张图:Leaflet 加载水利对象 GeoJSON 实战

从一个点到一张图:Leaflet 加载水利对象 GeoJSON 实战

TL;DR :几十上百个水库、堤防、水闸怎么批量上图?一份 GeoJSON(点线面 + properties)+ L.geoJSON 三个回调搞定,还能按类型自动换样式、做图层开关。


水利对象在 GeoJSON 里长什么样

水利一张图管的对象正好对应 GeoJSON 三种几何:点 (水库、水闸、测站)、线 (河流、堤防)、面 (蓄滞洪区、管理范围)。业务档案放在 properties 里:

water-features.geojson

json 复制代码
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [114.148, 22.584] },
      "properties": { "name": "深圳水库", "type": "reservoir", "capacity": 46 }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [[114.045, 22.528], [114.062, 22.522], [114.078, 22.515]]
      },
      "properties": { "name": "深圳河", "type": "river" }
    }
  ]
}

⚠️ 坐标顺序 :GeoJSON 标准规定坐标是 [经度, 纬度],而 Leaflet 全用 [纬度, 经度]。这个方向问题最容易踩。


三行渲染:按类型自动换样式

把数据交给 L.geoJSON,三个回调解决三件事:style 决定怎么画线面,pointToLayer 决定点怎么画,onEachFeature 决定弹什么:

javascript 复制代码
L.geoJSON(waterFeatures, {
  // 线/面:按对象类型上色
  style: (f) => {
    if (f.properties.type === 'river')
      return { color: '#1976d2', weight: 3 }
    if (f.properties.type === 'embank')
      return { color: '#b45309', weight: 2, dashArray: '4' }
  },
  // 点:水库/水闸画成蓝色圆点
  pointToLayer: (f, latlng) => L.circleMarker(latlng, {
    radius: 6, color: '#1976d2',
    fillColor: '#42a5f5', fillOpacity: 0.8
  }),
  // 每个对象挂业务弹窗
  onEachFeature: (f, layer) => {
    const p = f.properties
    layer.bindPopup(`<b>${p.name}</b><br>类型:${p.type}`)
  }
}).addTo(map)

真实项目里数据是接口吐的,前面加个 fetch 就是完整流程:数据底板服务返回 GeoJSON → 前端渲染 → 业务弹窗。


一张图标配:对象分组、图层开关

业务人员经常要「只看水库、藏掉河流」。把不同类型丢进不同图层组,交给右上角图层面板:

javascript 复制代码
// 按类型建两个图层组
const reservoirLayer = L.layerGroup()
const riverLayer = L.layerGroup().addTo(map)

// filter 按 properties.type 分流
L.geoJSON(waterFeatures, {
  filter: (f) => f.properties.type === 'reservoir'
}).addTo(reservoirLayer)

// 右上角图层面板
L.control.layers(null, {
  '水库 / 水闸': reservoirLayer,
  '河流 / 堤防': riverLayer
}).addTo(map)

⚠️ 三个坑

1. GeoJSON 坐标是 经度, 纬度,Leaflet 要 纬度, 经度。 标准规定,不是 Leaflet 的锅。前端自己拼 GeoJSON 时最容易写反。

2. properties 里别塞监测时序数据。 GeoJSON 只放对象档案(名称、类型、库容);实时水位、雨量这种高频变化数据,点弹窗时再单独请求接口,否则一个 GeoJSON 文件几十 MB,首屏卡死。

3. Polygon 首尾坐标要闭合。 蓄滞洪区这类面状要素,最后一个点要和第一个点相同。Leaflet 会帮你补,但其他服务端工具不一定。


小结

回调 作用
style 线/面按类型上色
pointToLayer 点用 circleMarker 而非默认图钉
onEachFeature 挂业务弹窗
filter 分流到不同图层组
L.control.layers 右上角开关面板

📦 本文是《智慧水利 GIS 实战》系列第 3 篇,完整代码见仓库 leafletjs-demo/。

相关推荐
ClouGence2 天前
Playwright 热门替代方案:Cypress、Selenium、CueCast 等 7 款自动化测试工具
前端框架·开源·测试
梅如你2 天前
中国2026年路网数据
arcgis·gis·遥感
时间的情敌2 天前
《回顾 2019 前端:React Hooks 问世,前端工程化爆发的一年》
前端·react.js·前端框架
我才是银古2 天前
GeoLibre 技术架构与实现解析
3d·ai·gis
Java后端的Ai之路2 天前
前端框架Vue-07_原生的Vue.js
前端·vue.js·前端框架
多客:duokelijie2 天前
婚恋交友小程序合规梳理:上线运营需要准备哪些资质与许可手续?
后端·mysql·微信小程序·前端框架·uni-app·php·持续部署
高晶3 天前
Android 通讯录应用开发实战:从零搭建 SQLite 数据持久化完整项目
android·设计模式·前端框架
Java后端的Ai之路3 天前
19-ReactJS最佳实践
前端·react.js·前端框架
我才是银古4 天前
OpenGIS 技能插件开发与使用:在 DeepSeek Harness 里按需加载 GIS 知识
ai·gis·dsh