前言
在开发调试过程当中,如果引入的是公司内部的Gis地图信息或者一些第三方定制来的Gis地图数据,当某一些地图块数据缺失的时候,要打开F12去一个个找那些链接(去找对应的xy与layer)失效、那么你可能需要使用以下插件帮你实现瓦片路径、层级可视化
leaflet-map-block
该插件封装了一个 Leaflet 的网格图层 LeafletMapBlockLayer
,用于在地图上渲染带有网格和文字标记的瓦片。支持自定义网格线样式和网格文字显示。安装和使用都非常简单,代码如下:
npm i leaflet-map-block
使用:
typescript
import {LeafletMapBlockLayer} from 'leaflet-map-block/dist/LeafletMapBlock';
map.addLayer(new LeafletMapBlockLayer({lineDash: [2, 2]}));
其中LeafletMapBlockLayer
是一个类,他的构造函数可以传递一个对象,这个对象就是对这个插件进行的一个配置
键 | 值类型 | 默认值 | 说明 |
---|---|---|---|
strokeStyle |
string |
'red' | 线颜色 |
lineWidth |
number |
2 |
线宽 |
lineDash |
number[] |
[5,5] |
线的虚线样式:[0,0] 为实线 |
showGridText |
boolean |
true |
是否显示网格文字 |
gridTextColor |
string |
'black' | 网格文字颜色 |
gridFont |
string |
'12px Arial' | gridFont |
比方说我们使用的是天地图的瓦片,那么我们的地图URL就是:http://t1.tianditu.gov.cn/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=tk
,那么当那一块缺了的时候没有渲染出来就可以拿地图上的xyz放到这个链接的xyz值中就可以快速定位到了

或者说我们有自己的地图的话,那也是一样的替换URL当中的xyz验证一下是不是真的图片缺失,是的话就去对应的文件系统找这个图片就好了

源码解析
授人以鱼不如授人以渔,这也是在一次机缘巧合之下发生的问题,使用内部地图但是缺失了一些块不好定位的时候,正好再看leaflet官方文档找的。
也就是这个GridLayer图层,我们知道地图渲染是按照瓦片一块块贴到canvas上面,然后渲染一个canvas实现的
一个冷姿势:在leaflet这个官网里面是英文的,如果想看中文版的,把
.com
改成.cn
就可以了
那么正好:来开始封装吧:
- 定义一个类,继承L.GridLayer
- 实现构造,用来传递options配置
- createTile方法会在
map.addLayer()
将该图层添加到地图的时候调用,返回一个canvas元素【也就是单个的地图瓦片】 - 既然可以拿到每一次渲染的地图瓦片,那么我们就可以给它添加一些内容了
- 创建一个canvas元素,这个canvas元素是和地图瓦片一样的大小
- 给这个canvas元素添加内容【边框和文字】其中层级和定位信息在coords当中可以取到
- 最后返回这个canvas对象tile就完成了
ts
import L from 'leaflet';
interface CanvasLayerOptions extends L.GridLayerOptions {
// 线颜色
strokeStyle?: string;
// 线宽
lineWidth?: number;
// 线的虚线样式:[0,0]为实线
lineDash?: number[];
// 是否显示网格文字
showGridText?: boolean;
// 网格文字颜色
gridTextColor?: string;
// 网格文字大小、字体等配置
gridFont?: string;
}
let options: CanvasLayerOptions = {};
export class LeafletMapBlockLayer extends L.GridLayer {
constructor(data?: CanvasLayerOptions) {
super(data);
options = {
strokeStyle: 'red',
lineWidth: 2,
lineDash: [5, 5],
showGridText: true,
gridTextColor: 'black',
gridFont: '12px Arial',
...data
};
}
createTile(coords: any): HTMLCanvasElement {
const tile = L.DomUtil.create('canvas', 'my-leaflet-tile') as HTMLCanvasElement;
const size = this.getTileSize();
tile.width = size.x;
tile.height = size.y;
const ctx = tile.getContext('2d');
const {
strokeStyle = '',
lineWidth = 0,
lineDash = [0, 0],
showGridText = true,
gridTextColor = 'black',
gridFont = '12px Arial'
} = options;
if (ctx) {
ctx.strokeStyle = strokeStyle;
ctx.lineWidth = lineWidth;
ctx?.setLineDash(lineDash);
ctx?.strokeRect(0, 0, tile.width, tile.height);
if (showGridText) {
ctx.fillStyle = gridTextColor;
ctx.font = gridFont;
ctx.fillText(`x:${coords.x}, y:${coords.y}, z:${coords.z}`, 5, 15);
}
}
return tile;
}
}
npm publish
既然封装好了,那么也打包发布到npm上吧
- 修改package.json文件,需要指定
- name:项目名
- version:版本号
- description:项目描述
- main:入口文件
- module:es6模块入口文件
- types:ts类型声明文件
- keywords:关键字
- author:作者
- license:协议
- scripts:打包脚本
- 执行打包命令:
npm run build-lib
,打包完成之后会生成dist目录 - 登录npm:
npm login
- 发布到npm:
npm publish
就这样也就发布到了npm上。