AI摘要
《Leaflet 中文入门教程》,尽量按“能直接上手做项目”的思路来讲。Leaflet 是一个用于构建交互式网页地图的开源 JavaScript 地图库,官方强调它“轻量、简单、移动端友好”,主页目前仍把 1.9.4 标为稳定版;同时官方也已经提供 2.0.0-alpha.1 预发布版本,用于向现代化 ESM 写法过渡。(Leaflet)
一、Leaflet 是什么
你可以把 Leaflet 理解成一个“浏览器里的地图引擎”。
它本身不生产地图数据,而是负责:
- 把底图瓦片显示出来
- 在地图上放点、画线、画面
- 处理缩放、拖拽、点击等交互
- 弹出信息框
- 叠加你自己的业务数据
官方首页给出的核心定位是:交互式地图 JavaScript 库,并强调其体积大约只有 42 KB JS,适合大多数开发者需要的地图功能。(Leaflet)
对于业务系统来说,Leaflet 很适合做这些场景:
- 门店分布图
- 客户分布图
- 设备点位图
- 光缆线路图
- 机房资源 GIS 展示
- 告警地图
- 巡检轨迹地图
- 区域覆盖图
二、先理解 Leaflet 的核心组成
Leaflet 的核心对象并不多,最重要的是这几个。官方 API Reference 中把这些作为基础对象组织。(Leaflet)
1)Map
地图本体,所有东西都挂在它上面。
var map = L.map('map');2)TileLayer
瓦片图层,通常就是底图。
L.tileLayer(urlTemplate, options)常见底图如 OpenStreetMap、高德、天地图、Google 等。
3)Marker
地图上的点位。
L.marker([lat, lng])4)Popup
点击点位后弹出的信息框。
.bindPopup('内容')5)Polyline
线,比如路线、光缆、轨迹。
L.polyline([[lat1, lng1], [lat2, lng2]])6)Polygon
面,比如区域、围栏、行政区块。
L.polygon([...])7)Event
事件机制,比如点击、缩放、拖拽结束。
map.on('click', function(e) { ... })官方 Quick Start 就是围绕这些基础对象来教学的。(Leaflet)
三、5 分钟跑起来一个 Leaflet 页面
官方 Quick Start 给出的最基本接入方式,是在页面里引入 Leaflet 的 CSS 和 JS,然后创建一个地图容器。(Leaflet)
第一步:准备 HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Leaflet 入门示例</title>
<link rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
#map {
width: 100%;
height: 500px;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
var map = L.map('map').setView([30.67, 104.06], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
L.marker([30.67, 104.06])
.addTo(map)
.bindPopup('成都')
.openPopup();
</script>
</body>
</html>这段代码做了三件事:
- 创建地图并把中心点放到成都
- 加载 OSM 底图
- 在成都放一个点,并弹出气泡
这就是 Leaflet 官方 Quick Start 的基本用法套路。(Leaflet)
四、坐标和缩放怎么理解
Leaflet 常见坐标格式是:
[纬度, 经度]注意顺序是:
lat, lng
也就是 纬度在前,经度在后
例如成都大致可以写成:
[30.67, 104.06]设置地图中心与缩放级别的常见方法:
map.setView([30.67, 104.06], 13);其中 13 是缩放级别。数值越大,看得越近。这个写法是官方基础示例的一部分。(Leaflet)
五、最常用的 6 个操作
1)加一个点
var marker = L.marker([30.67, 104.06]).addTo(map);2)给点加弹窗
marker.bindPopup('这是一个点位');3)画一条线
var line = L.polyline([
[30.67, 104.06],
[30.68, 104.08],
[30.70, 104.10]
], {
color: 'blue',
weight: 4
}).addTo(map);4)画一个面
var polygon = L.polygon([
[30.67, 104.06],
[30.68, 104.08],
[30.66, 104.10]
]).addTo(map);5)让地图自动缩放到某个对象
map.fitBounds(line.getBounds());这个非常实用。比如你拿到一条线路,不知道该把地图缩放到什么位置,就直接 fitBounds。
6)监听点击事件
map.on('click', function(e) {
console.log(e.latlng);
});官方 Quick Start 明确演示了 Marker、Polyline、Polygon、Popup、事件等基础能力。(Leaflet)
六、图层的概念一定要掌握
Leaflet 是“图层式”思维。底图是一层,你的业务点位是一层,线路是一层,告警是一层,热力是一层。
常见做法是用 LayerGroup 或 FeatureGroup 来管理。
var deviceLayer = L.layerGroup().addTo(map);
var lineLayer = L.layerGroup().addTo(map);
L.marker([30.67, 104.06]).addTo(deviceLayer);
L.marker([30.68, 104.08]).addTo(deviceLayer);
L.polyline([
[30.67, 104.06],
[30.68, 104.08]
]).addTo(lineLayer);这样做的好处是:
- 便于按类别清空
- 便于做显隐控制
- 便于和业务模块对应
- 便于后续性能优化
API Reference 把图层体系作为 Leaflet 的核心结构之一。(Leaflet)
七、GeoJSON 很重要
如果你要和后端配合,Leaflet 最常见的数据格式之一就是 GeoJSON。
它特别适合传输点、线、面数据。
例如一个点:
var geojson = {
"type": "Feature",
"properties": {
"name": "机房A"
},
"geometry": {
"type": "Point",
"coordinates": [104.06, 30.67]
}
};
L.geoJSON(geojson).addTo(map);注意这里 GeoJSON 坐标顺序是:
[经度, 纬度]而 Leaflet 代码里很多地方常用的是:
[纬度, 经度]这是初学者最容易踩的坑之一。Leaflet 的 API Reference 包含 GeoJSON 支持对象。(Leaflet)
八、做业务地图时的推荐代码结构
如果你后面要做正式项目,不要把所有逻辑都写在一个页面里。建议至少拆成下面几层:
1)map.js
负责地图初始化
export function initMap() {
const map = L.map('map').setView([30.67, 104.06], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
return map;
}2)layers.js
负责图层创建与管理
export function createLayers(map) {
return {
deviceLayer: L.layerGroup().addTo(map),
routeLayer: L.layerGroup().addTo(map),
alarmLayer: L.layerGroup().addTo(map)
};
}3)render.js
负责把后端数据渲染到地图上
export function renderDevices(layer, devices) {
layer.clearLayers();
devices.forEach(item => {
L.marker([item.lat, item.lng])
.bindPopup(item.name)
.addTo(layer);
});
}4)events.js
负责用户交互事件
export function bindMapEvents(map) {
map.on('click', e => {
console.log('点击位置:', e.latlng);
});
}这样后面你做设备地图、线路地图、资源地图、告警地图,代码才不会乱。
九、常见业务案例怎么做
1)设备点位图
适合机房、杆路点位、客户节点、ONU、交换机等。
用 Marker 或自定义图标。
var icon = L.icon({
iconUrl: 'device.png',
iconSize: [24, 24]
});
L.marker([30.67, 104.06], { icon }).addTo(map);2)线路图
适合光缆、传输链路、巡检轨迹。
用 Polyline。
L.polyline(path, {
color: 'green',
weight: 5
}).addTo(map);3)覆盖区域图
适合责任片区、行政区域、机房服务范围。
用 Polygon 或 GeoJSON。
L.polygon(areaCoords).addTo(map);4)点击联动详情
适合点击设备弹出资源详情。
marker.on('click', function() {
// 打开右侧面板或加载详情
});5)自动定位到某条线路
适合工单查看、链路追踪、故障定位。
map.fitBounds(polyline.getBounds());十、初学者最容易踩的坑
1)忘记给地图容器设置高度
这是最常见问题。#map 没高度,地图不会显示。
#map { height: 500px; }官方 Quick Start 在页面准备步骤里就强调了要先准备容器和资源文件。(Leaflet)
2)经纬度顺序写反
Leaflet 常写 [lat, lng],GeoJSON 常写 [lng, lat]。
这个错一旦出现,点位会跑偏到很远的地方。
3)底图地址不可用
有些瓦片服务有跨域、鉴权、访问频率、国内网络可达性问题。
如果项目在国内落地,通常要优先考虑:
- 高德
- 天地图
- 自建瓦片服务
- 企业内部 GIS 服务
4)一次性加载过多 Marker
如果点太多,页面会卡。
这时通常要考虑:
- 点聚合插件
- 服务端裁剪
- 按视野范围加载
- Canvas/WebGL 方案
Leaflet 官方明确说明,很多增强能力依赖插件生态,而插件页就是官方推荐的扩展入口。(Leaflet)
十一、Leaflet 1.9 和 2.0 要怎么选
这是现在很实际的问题。
官方下载页当前写得很清楚:
- 1.9.4:稳定版
- 2.0.0-alpha.1:预发布版(Leaflet)
官方博客和 GitHub Release 说明,Leaflet 2.0 的变化很大,主要包括:
- 去掉 IE 支持
- 改为现代浏览器目标
- 支持 ESM
- 改用 Pointer Events
- 核心包不再默认依赖全局
L - 更强调现代 JavaScript 用法(GitHub)
所以我的建议是:
你是做正式生产项目
优先用 Leaflet 1.9.4。
因为它稳定,插件生态兼容性更成熟。(Leaflet)
你是做新项目实验或现代前端工程
可以研究 2.0 alpha,但要提前检查插件兼容性。官方围绕 2.0 的发布说明也特别提到了插件生态需要适配。(GitHub)
十二、给你一个更像正式项目的完整示例
下面这个例子包含:底图、点、线、点击事件、自动缩放。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Leaflet 业务地图示例</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
var map = L.map('map').setView([30.67, 104.06], 12);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
var devices = [
{ name: '机房A', lat: 30.67, lng: 104.06 },
{ name: '机房B', lat: 30.69, lng: 104.09 },
{ name: '机房C', lat: 30.72, lng: 104.12 }
];
var points = [];
devices.forEach(function(item) {
var marker = L.marker([item.lat, item.lng])
.addTo(map)
.bindPopup(item.name);
marker.on('click', function() {
console.log('点击设备:', item.name);
});
points.push([item.lat, item.lng]);
});
var line = L.polyline(points, {
color: 'blue',
weight: 4
}).addTo(map);
map.fitBounds(line.getBounds());
map.on('click', function(e) {
console.log('地图点击坐标:', e.latlng.lat, e.latlng.lng);
});
</script>
</body>
</html>这份代码已经能作为很多后台管理系统地图页的原型。
十三、如果你要做“资源管理/GIS”类系统,下一步该学什么
按实战顺序,我建议你继续学这几项:
第 1 步:掌握基础对象
- Map
- TileLayer
- Marker
- Popup
- Polyline
- Polygon
- Event
这些都在官方 Quick Start 和 API Reference 的主线里。(Leaflet)
第 2 步:掌握图层组织
- LayerGroup
- FeatureGroup
- 图层显隐
- 数据刷新
第 3 步:掌握 GeoJSON
- 后端返回 GeoJSON
- 前端直接渲染
- 点线面统一处理
第 4 步:掌握业务交互
- 点击点位显示详情
- 点击线路显示属性
- fitBounds 自动定位
- 右侧面板联动
第 5 步:掌握插件
官方插件页就是扩展能力入口。Leaflet 本体刻意保持轻量,所以很多高级功能都依赖插件。(Leaflet)
十四、给你的实用建议
如果你的目标是做企业级 GIS 页面,而不是做地理信息专业平台,我建议你这样选型:
- 先用 Leaflet 1.9.4
- 先把“点、线、面、弹窗、联动”做扎实
- 后端统一输出 GeoJSON 或标准业务 JSON
- 前端按图层分组管理
- 不要一开始就追求复杂插件
- 先把设备点位图、线路图、区域图做通
这样你会很快进入“能交付”的状态。(Leaflet)