前端地图的实现学习
GeoJson
GeoJSON 是一种基于 JSON 的格式,用来表示地理空间数据,如点、线、多边形等,以及与之相关的属性信息。
它是 Web 地图、GIS、可视化和空间计算中广泛使用的标准格式之一,尤其适用于前端框架(如 Leaflet、Mapbox、OpenLayers)和空间计算库(如 Turf.js)。
type有 point LineString Polygon
{
"type": "Polygon",
"coordinates": [
[
[113.1, 23.1],
[113.5, 23.1],
[113.5, 23.5],
[113.1, 23.5],
[113.1, 23.1]
]
]
}
turfjs
是一些空间计算函数的合集
在浏览器中,turf可以做这些
判断是否在某区域内
裁剪GeoJson数据
前端展示一些地图标记、区域等等
性能优化
根据可视范围,只加载可以看到的元素
const bounds = map.getBounds(); // Leaflet 获取当前视口
const bbox = [bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()];
const clipped = turf.bboxClip(geojson, bbox);
结合webworker优化加载
减少定点数,简化几何体
const simplified = turf.simplify(geojson, { tolerance: 0.001, highQuality: false });
使用squarreGrid来预处理地图,生成网格图
turf负责一些标注点的坐标转移、分块、缓冲区生成等等,不负责地图本身的渲染
turf的交互也依赖于地图引擎的交互,
leafLet
一个非常简单好用的前端地图工具。
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('<https://tile.openstreetmap.org/{z}/{x}/{y}.png>', {
attribution: '© <a href="<https://www.openstreetmap.org/copyright>">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([51.5, -0.09]).addTo(map)
.bindPopup('A pretty CSS popup.<br> Easily customizable.')
.openPopup();
预先准备好切分好的地图,并且按照缩放比例,交给leaflet进行动态加载。
内置了懒加载
完整配置如下:
const map = L.map('map', {
crs:// 这里可以指定地理坐标到地图坐标的投影方式
center: [51.505, -0.09], // 中心坐标
zoom: 13, // 初始缩放级别
minZoom: 0, // 最小缩放
maxZoom: 18, // 最大缩放
zoomControl: true, // 是否显示默认缩放控件
attributionControl: true,// 是否显示版权信息
scrollWheelZoom: true, // 是否启用滚轮缩放
doubleClickZoom: true, // 是否启用双击缩放
dragging: true, // 是否允许拖动地图
boxZoom: true, // 框选缩放
keyboard: true, // 键盘控制
inertia: true, // 惯性拖动(移动端)
preferCanvas: false, // 是否使用 canvas
});
// 图层配置(加载瓦片)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
subdomains: ['a', 'b', 'c'], // 子域名优化并发
maxZoom: 19,
minZoom: 0,
tileSize: 256,
opacity: 1.0,
noWrap: false,
detectRetina: false
}).addTo(map);
// 标记配置
L.marker([51.5, -0.09], {
draggable: true, // 可拖动
title: 'My Marker', // 鼠标悬停文字
riseOnHover: true, // 鼠标悬停上浮
icon: customIcon // 自定义图标
}).addTo(map);
// 圆形配置
L.circle([51.508, -0.11], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500 // 半径,单位为米
}).addTo(map);
// 折线配置
L.polyline([
[51.5, -0.1],
[51.51, -0.12],
[51.52, -0.14]
], {
color: 'blue',
weight: 3,
opacity: 0.7,
dashArray: '5, 10', // 虚线样式
}).addTo(map);
// 地理数据配置
L.geoJSON(geojsonData, {
style: function (feature) {
return { color: feature.properties.color };
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.name);
},
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, { radius: 8 });
}
}).addTo(map);
// 缩放控件
L.control.zoom({
position: 'topright'
}).addTo(map);
// 图例控件
const legend = L.control({ position: 'bottomright' });
legend.onAdd = function (map) {
const div = L.DomUtil.create('div', 'info legend');
div.innerHTML = "<i style='background: red'></i>高<br><i style='background: blue'></i>低";
return div;
};
legend.addTo(map);
此外,leaflet还有许多插件可以安装:
地图切分
地图切片(Map Tiling)是指将大型地图或影像数据按照一定的规则切割成多个较小的图块(称为瓦片),并根据缩放级别和用户请求逐步加载这些瓦片,从而提升地图在网络或应用中的显示速度和效率。
一个常见的地图瓦片 URL 模板如下所示:
cpp
复制编辑
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
{s}
是子域(如a
,b
,c
),用于浏览器并发加载优化。{z}
是缩放层级。{x}
是瓦片的列编号。{y}
是瓦片的行编号。
常用工具
MapTiler Desktop / Engine
QGIS + QTiles 插件
自定义脚本 + Python + Pillow
TMS服务
TMS 是一种规定了地图瓦片命名、组织和访问方式的标准格式,用于将地图切片作为 Web 服务提供。 /tiles/{z}/{x}/{y}.png
z
: 缩放等级(zoom level)x
: 水平方向瓦片索引(从左到右)y
: 垂直方向瓦片索引(从下到上,注意与 Google/Leaflet 相反!)
❗️❗️❗️注意点
坐标转换非常重要! 一定要在开发前规划好!
坐标转换非常重要! 一定要在开发前规划好!
坐标转换非常重要! 一定要在开发前规划好!
🔥其他相关库
pixijs
openlayers
mapbox