前言
在開發調試過程當中,如果引入的是公司內部的Gis地圖信息或者一些第三方定制來的Gis地圖數據,當某一些地圖塊數據缺失的時候,要打開F12去一個個找那些鏈接(去找對應的xy與layer)失效、那么你可能需要使用以下插件幫你實現瓦片路徑、層級可視化
leaflet-map-block
github 地址
npm 地址
該插件封裝了一個 Leaflet 的網格圖層 LeafletMapBlockLayer
,用于在地圖上渲染帶有網格和文字標記的瓦片。支持自定義網格線樣式和網格文字顯示。安裝和使用都非常簡單,代碼如下:
npm i leaflet-map-block
使用:
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就完成了
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上。