Leaflet是一个适用于移动端交互地图的开源JavaScript库。
对移动设备很友好,gzip压缩JS代码大约38 KB,它提供了大多数开发人员所需要的所有地图功能。
扩展性强、插件资源丰富,文档清晰的API,源代码简单、易读。
本文用简单的示例,引导新手快速使用leaflet快速开始、加载天地图、加载arcgis服务、自定义4490坐标系,将天地图扩展到19级。
一、快速开始
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quick Start - Leaflet</title>
<link rel="stylesheet" href="./css/leaflet.css">
<style>
*{
margin: 0;
padding: 0;
}
#map {
height: 100vh;
width: 100vw;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="./js/leaflet-src.js"></script>
<script>
var map = L.map('map').setView([39.736861245030326, 116.13991336098002], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);
L.marker([39.736861245030326, 116.13991336098002]).addTo(map)
.bindPopup('marker')
.openPopup();
</script>
</body>
</html>
示例效果
以上代码实现了Leaflet的引入,地图的加载及marker的简单用法,接下来开始加载天地图。
二、加载天地图
1.去天地图官网获取天地图服务许可(Key)
2.引入leaflet.ChineseTmsProviders
3.将leaflet.ChineseTmsProviders中的key换成自己申请的key
4.初始化地图实例并加载天地图
<script>
const tileOptions = {
minZoom: 1,
maxZoom: 19
}
// 定义矢量地图
var normalm = L.tileLayer.chinaProvider('TianDiTu.Normal.Map', tileOptions)
// 定义矢量注记
var normala = L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion', tileOptions)
// 组合地图和注记
var normal = L.layerGroup([normalm, normala])
var map = L.map('map', {
center: [39.736861245030326, 116.13991336098002],
zoom: 16,
layers: [normal]
})
let marker = L.marker([39.736861245030326, 116.13991336098002]).addTo(map)
</script>
示例效果
三、加载Arcgis服务
1.引入esri-leaflet.js和esri-leaflet-renderers.js
<script src="./js/esri-leaflet.js"></script>
<script src="./js/esri-leaflet-renderers.js"></script>
2.加载arcgis服务
<script>
const tileOptions = {
minZoom: 1,
maxZoom: 19
}
// 定义矢量地图
var normalm = L.tileLayer.chinaProvider('TianDiTu.Normal.Map', tileOptions)
// 定义矢量注记
var normala = L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion', tileOptions)
// 组合地图和注记
var normal = L.layerGroup([normalm, normala])
var map = L.map('map', {
center: [39.736861245030326, 116.13991336098002],
zoom: 16,
layers: [normal]
})
let marker = L.marker([39.736861245030326, 116.13991336098002]).addTo(map)
const mapServerUrl = 'http://你项目的arcgis服务地址/MapServer/0'
let mapLayer = L.esri.featureLayer({
url: mapServerUrl
}).addTo(map)
</script>
示例效果
四、自定义4490坐标(Leaflet默认为EPSG3857)
1.引入proj4-src.js和proj4leaflet.js
<script src="./js/proj4-src.js"></script>
<script src="./js/proj4leaflet.js"></script>
2.定义缩放比例和原点(参数可以在https://epsg.io/4490参看,定义其他坐标系同理)
const CRS_4490 = new L.Proj.CRS(
'EPSG:4490',
'+proj=longlat +ellps=GRS80 +no_defs', {
resolutions: [
1.40625,
0.703125,
0.3515625,
0.17578125,
0.087890625,
0.0439453125,
0.02197265625,
0.010986328125,
0.0054931640625,
0.00274658203125,
0.001373291015625,
6.866455078125e-4,
3.4332275390625e-4,
1.71661376953125e-4,
8.58306884765625e-5,
4.291534423828125e-5,
2.1457672119140625e-5,
1.0728836059570312e-5,
5.364418029785156e-6,
2.682209064925356e-6,
1.3411045324626732e-6,
6.705522662313365e-7,
],
origin: [-180, 90],
}
)
3.在地图实例中赋值自定义的坐标系
var map = L.map('map', {
center: [39.736861245030326, 116.13991336098002],
zoom: 16,
layers: [normal],
crs: CRS_4490
})
4.修改leaflet.ChineseTmsProviderst.js文件,将天地图墨卡托投影改成经纬度(因为4490是地理坐标系),也就是将上文加载天地图模块的第三点,改成下面这段代码,w代表墨卡托,c代表经纬度
TianDiTu: {
Normal: {
Map:
'https://t{s}.tianditu.gov.cn/vec_c/wmts?layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
Annotion:
'https://t{s}.tianditu.gov.cn/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
},
Satellite: {
Map:
'https://t{s}.tianditu.gov.cn/img_c/wmts?layer=img&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
Annotion:
'https://t{s}.tianditu.gov.cn/cia_c/wmts?layer=cia&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
},
Terrain: {
Map:
'https://t{s}.tianditu.gov.cn/ter_c/wmts?layer=ter&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
Annotion:
'https://t{s}.tianditu.gov.cn/cta_c/wmts?layer=cta&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&tileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}',
},
Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
key: "自己在天地图官网申请的key"
},
五、拓展天地图到19级
1.修改leaflet-src.js源码
将createTile方法中的tile.src = this.getTileUrl(coords)修改如下:
if(coords.z == 19) {
let coords_18 = new Point(Math.floor(coords.x / 2), Math.floor(coords.y / 2), 19)
let tileUrl = this.getTileUrl(coords_18)
tileUrl = tileUrl.replace('tileMatrix=19', 'tileMatrix=18')
// 加载18级图片回来,进行切割,四等份
let img = new Image()
img.src = tileUrl +'&v='+ Math.random()
img.crossOrigin = 'anonymous'
img.onload = function() {
let c = document.createElement('canvas');
let ctx = c.getContext('2d');
c.width = 256;
c.height = 256;
ctx.drawImage(img, coords.x % 2 *128, coords.y % 2 * 128, 128, 128, 0, 0, 256, 256);
tile.src = c.toDataURL() // 默认为 PNG 格式。图片的分辨率为96dpi。
}
} else {
tile.src = this.getTileUrl(coords);
}
原理:将18级瓦片进行2次方切割,用canvas重画,同理拓展到20级的时候进行2的2次方切割,21级时进行2的3次方切割,以此类推,这样处理可以打破天地图18级的限制,但由于是将18级的瓦片切割放大的,带来的弊端是级别越大,地图越模糊。
2.修改maxZoom,本文将天地图拓展到19级,因此设最大缩放级别为19。各位可根据项目需求进行相应修改。
const tileOptions = {
minZoom: 1,
maxZoom: 19
}