Leaflet的zoom层级-天地图层级之间的关系
Leaflet的tileLayer请求地址分析
天地图的瓦片服务地址:
http://t1.tianditu.com/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
真实请求:
http://t1.tianditu.com/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix=2&TileCol=3&TileRow=1&tk=
特别注意的是其中:z是请求的瓦片层级。
在leaflet中tileLayer的请求地址z跟leaflet的zoom层级之间的关系默认是当前zoom层级是多少,则这个z的值就是多少,如果在tileLayer的options参数设置了zoomOffset,则请求的时候,z值会变成当前zoom层级+zoomOffset。
zoom层级跟坐标系的关系
如果在crs中设置的scale层级,则zoom跟sacle层级是一一对应。
天地图服务
天地图的瓦片默认是从第一级开始才有瓦片,则leaflet的zoom层级为0的时候跟天地图加载的时候是有第0级的偏差。
天地图默认调用国际级的可用比例尺的为1到18级 ,而调用省市服务可放大到20级,以下为天地图1到20级的比例尺:
L1 1:295829355.45456564
L2 1:147914677.72728282
L3 1:73957338.863641411
L4 1:36978669.431820706
L5 1:18489334.715910353
L6 1:9244667.3579551764
L7 1:4622333.6789775882
L8 1:2311166.8394887941
L9 1:1155583.419744397
L10 1:577791.70987219852
L11 1:288895.85493609926
L12 1:144447.92746804963
L13 1:72223.963734024815
L14 1:36111.981867012408
L15 1:18055.990933506204
L16 1:9027.9954667531019
L17 1:4513.997733376551
L18 1:2256.9988666882755(20m)
L19 1:1128.4994333441377
L20 1:564.24971667206887(5m)
参考:天地图各级比例尺
解决方案
第一种:
在使用tileLayer叠加天地图的瓦片的时候,设置zoomOffset参数值为1,然后再地图容器zoom层级0的时候,实际是在请求天地图的第1级瓦片。
var map = L.map('map', {
crs: L.CRS.EPSG4326,
minZoom: 0,
maxZoom: 30,
center: [37.1155793103314, 114.47684215156913],//[30.56293487548828, 104.0879058837890],
zoom: 0,
zoomControl: true,
attributionControl: false,
});
// 天地图影像以及影像注记
function initTiandituLayersYX() {
var vector_map = L.tileLayer("http://t1.tianditu.com/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=", {
maxZoom: 17,
tileSize: 256,
zoomOffset: 1
}).addTo(map);
//添加注记
var vector_note = L.tileLayer("http://t1.tianditu.com/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=", {
maxZoom: 17,
tileSize: 256,
zoomOffset: 1,
}).addTo(map);
}
测试结果:
leaflet的zoom的第0级开始有瓦片,但实际请求的地图瓦片地址为第1级的瓦片。
第二种:
设置地图容器的第0级scale为任意的数字,第1级开始跟天地图的层级进行对应。
const resolutions = ["任意数字值站位zoom的第0级"].concat(getTdtResolutions())
let bbox = {
left: -180,
bottom: -90,
right: 180,
top: 90,
};
const crs = getCRS(L.CRS.EPSG4326.code, bbox, resolutions);
map = L.map('map', {
crs: crs,
// crs: L.CRS.EPSG4326,
minZoom: 0,
maxZoom: 30,
center: [37.1155793103314, 114.47684215156913],//[30.56293487548828, 104.0879058837890],
zoom: 0,
zoomControl: true,
attributionControl: false,
});
// 天地图影像以及影像注记
function initTiandituLayersYX() {
var vector_map = L.tileLayer("http://t1.tianditu.com/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=", {
maxZoom: 17,
tileSize: 256,
}).addTo(map);
//添加注记
var vector_note = L.tileLayer("http://t1.tianditu.com/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=", {
maxZoom: 17,
tileSize: 256,
}).addTo(map);
}
测试结果:
在zoom的第0级没有瓦片,从zoom第1级开始有瓦片。
总结
从这个问题来看,重点是要搞清楚leaflet中zoom层级跟tileLayer瓦片请求中z层级参数的关系,以及可以使用zoomOffset参数来进行动态值偏移。同时要请求tile服务中xyz格式的对应关系。