leaflet如何更改地图地图颜色--暗黑风格地图

1、原理:

        现在所有的地图其实都是基于canvas,所有归根到底,更换地图底图的颜色就是利用画布的机制去修改图片的颜色然后再重新渲染到地图上---所以这套思路可以应用于cesium、openlayers

2、上效果:

3、实现

        首先我们可以查看一下leaflet加载服务的TileLayer,可以发现该方法是在initialize中绑定的options、在createTile中实现的加载的地图图片。所以我们只需要在createTile中对图片进行修改然后再返回出去就可以使自己渲染的图片替换掉地图影像。

leaflet如何更改地图地图颜色--暗黑风格地图_第1张图片

4、代码

        4.1、继承TileLayer的方法,然后我们手动重写这个两个方法
import * as L from 'leaflet'
var DesignTileLayer:any = L.TileLayer.extend({
    initialize: function (url: any, options: any) {
   
    },

    createTile: function (coords:any) {
   
    }
});
export  default DesignTileLayer
        4.2、重写initialize
    initialize: function (url: any, options: any) {
        this.url = url;
        //@ts-ignore
        L.GridLayer.prototype.initialize.call(this, options);
    },
        4.3、重写createTile
    createTile: function (coords:any) {
        /**获取外部接受的颜色*/
        const {color}=this.options

        // 创建一个用于绘图的  元素
        var tile = L.DomUtil.create('canvas', 'leaflet-tile');

        // 根据选项设置瓦片的宽度和高度
        var size = this.getTileSize();
        tile.width = size.x;
        tile.height = size.y;
   
        // 获得一个 canvas 上下文,并使用 coords.x、coords.y 和 coords.z 在上面画东西
        var ctx: any = tile.getContext('2d');

        // 使用传入的 URL 模板替换变量
        var url = this.url
            .replace('{x}', coords.x)
            .replace('{y}', coords.y)
            .replace('{z}', coords.z+1);


        // 创建一个图像对象来加载瓦片
        var img = new Image();

        img.src = url; // 替换为你的图片路径

        // 当图片加载完成后,绘制到 Canvas 上
        img.onload = function () {
            // 绘制图片到 Canvas 上
            ctx.drawImage(img, 0, 0, tile.width, tile.height);
            // 获取图像的像素数据
            var imageData = ctx.getImageData(0, 0, tile.width, tile.height);
            // 获取原来的图片的像素颜色
            var pixels = imageData.data;
            for (let i = 0; i 
        4.4、完整代码
import * as L from 'leaflet'
var DesignTileLayer:any = L.TileLayer.extend({
    initialize: function (url: any, options: any) {
        this.url = url;
        //@ts-ignore
        L.GridLayer.prototype.initialize.call(this, options);
    },

    createTile: function (coords:any) {
        /**获取外部接受的颜色*/
        const {color}=this.options

        // 创建一个用于绘图的  元素
        var tile = L.DomUtil.create('canvas', 'leaflet-tile');

        // 根据选项设置瓦片的宽度和高度
        var size = this.getTileSize();
        tile.width = size.x;
        tile.height = size.y;
   
        // 获得一个 canvas 上下文,并使用 coords.x、coords.y 和 coords.z 在上面画东西
        var ctx: any = tile.getContext('2d');

        // 使用传入的 URL 模板替换变量
        var url = this.url
            .replace('{x}', coords.x)
            .replace('{y}', coords.y)
            .replace('{z}', coords.z+1);


        // 创建一个图像对象来加载瓦片
        var img = new Image();

        img.src = url; // 替换为你的图片路径

        // 当图片加载完成后,绘制到 Canvas 上
        img.onload = function () {
            // 绘制图片到 Canvas 上
            ctx.drawImage(img, 0, 0, tile.width, tile.height);
            // 获取图像的像素数据
            var imageData = ctx.getImageData(0, 0, tile.width, tile.height);
            // 获取原来的图片的像素颜色
            var pixels = imageData.data;
            for (let i = 0; i 

5、如何使用

import L from 'leaflet';
import DesignTileLayer from '../DesingMapColor/index'

...
function userMap(map: L.Map) {
    let color = { r:12, g: 12, b: 83}
    //VEC_C  ---天地图的地址
    //TK_KEY ---天地图的token
    const customLayer = new DesignTileLayer(VEC_C + TK_KEY, { color: color });
    // 将 customLayer 添加到 Leaflet 地图中
    customLayer.addTo(map);
}
...

gitee地址:https://gitee.com/qwswqwe/leaflet-user-define-theme.giticon-default.png?t=N7T8https://gitee.com/qwswqwe/leaflet-user-define-theme.git

6、可能遇到的问题:

        6.1、图片跨域

这是因为canvas无法处理跨域的图片,解决办法,代理:

        例如我使用的vite.我在vite.config.ts中配置了代理

      server: {
        // open: '/home',
        host: '0.0.0.0',
        proxy: {
          '/tdt': {
            target: 'http://t5.tianditu.gov.cn', //测试环境
            rewrite: path => path.replace(/^\/tdt/, ''),
            changeOrigin: true
          }
        }
      },



.....
    const VEC_C ='/tdt/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='
.....
        6.2、地图不匹配

        leaflet如何更改地图地图颜色--暗黑风格地图_第2张图片

        这是因为缩放等级不匹配,及图片的xyz和你的地图的xyz不匹配,

        解决办法:我手动吧z加上了1


// 使用传入的 URL 模板替换变量
var url = this.url
    .replace('{x}', coords.x)
    .replace('{y}', coords.y)
    .replace('{z}', coords.z+1);

     总结:这个方案的思路其实是截取图片---替换图片的思路。所以我们也可以给图片加上logo,也可以在createTile中实现。如果有不会的加QQ 2933634771,不过我声明,别乱加!!!

你可能感兴趣的:(javascript,开发语言)