基于leaflet.js实现修改地图主题样式的流程分析


Posted in Javascript onMay 15, 2020

今天遇到了一点点的小情况,我自己根据leaflet.js做了一个离线地图,公司要用来做态势,但是地图的底图用的是高德的原图,样式是下面这样的:

基于leaflet.js实现修改地图主题样式的流程分析

但是态势的主题是如下的这种淡蓝色:

基于leaflet.js实现修改地图主题样式的流程分析

这就造成了本次的需求,需要可以修改样式的主题,由于本人是个后端小佬,前端菜鸡,所以实现起来发生了一些困难,这里简单介绍下实现的路程。
首先看下效果:

基于leaflet.js实现修改地图主题样式的流程分析

然后介绍下艰辛的过程:
首先,需要用到一个基于leaflet.js的插件:
https://github.com/hnrchrdl/leaflet-tilelayer-colorizr
但是在使用这个插件的时候出现了一些问题,这里不赘述了,大致就是我加载的地图瓦片是其他的服务器,但是这个插件似乎不能支持跨域,废了很大的心思我终于解决了这个问题。
这里我先提供解决的方式:

/*
 * L.TileLayer.Colorizr is a regular tilelayer with mapped colors.
 */
(function () {
 // L.TileLayer.Colorizr = 
 var Colorizr = L.TileLayer.extend({
  initialize: function (url, options) {
   options = L.extend({}, L.TileLayer.prototype.options, {
    colorize: function (pixel) {
     return pixel;
    },
    crossOrigin: 'Anonymous'
   }, options);
   L.TileLayer.prototype.initialize.call(this, url, options);
   L.setOptions(this, options);
   this.setColorizr(this.options.colorize);
   this.on('tileload', function (e) {
    this._colorize(e.tile);
   });
  },
  setColorizr: function (colorizrFactory) {
   if (!colorizrFactory || typeof colorizrFactory !== 'function') {
    throw 'The colorize option should be a function and return an object with at least one of "r", "g", "b", or "a" properties. Got:' +
    typeof colorizrFactory;
   } else {
    this.options.colorize = colorizrFactory;
   }
   this.redraw(false);
  },
  _createTile: function () {
   var tile = L.TileLayer.prototype._createTile.call(this);
   tile.crossOrigin = "Anonymous";
   return tile;
  },
  _colorize: function (img) {
   if (img.getAttribute('data-colorized')) {
    img.hidden = false;
    return;
   }else {
    img.hidden = true;
   }
   var _img = img;
   var img = new Image();
   img.crossOrigin = 'Anonymous';
   img.src = _img.src;
   var _this = this;
   img.onload = function () {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var pix = imgd.data;
    for (var i = 0, n = pix.length; i < n; i += 4) {
     var pixel = _this.options.colorize({r: pix[i], g: pix[i + 1], b: pix[i + 2], a: pix[i + 3]});
     if (!!!pixel || pixel !== Object(pixel) || Object.prototype.toString.call(pixel) === '[object Array]') {
      if (i === 0) {
       throw 'The colorize option should return an object with at least one of "r", "g", "b", or "a" properties.';
      }
     } else {
      if (pixel.hasOwnProperty('r') && typeof pixel.r === 'number') {
       pix[i] = pixel.r;
      }
      if (pixel.hasOwnProperty('g')) {
       pix[i + 1] = pixel.g;
      }
      if (pixel.hasOwnProperty('b')) {
       pix[i + 2] = pixel.b;
      }
      if (pixel.hasOwnProperty('a')) {
       pix[i + 3] = pixel.a;
      }
     }
    }
    ctx.putImageData(imgd, 0, 0);
    _img.setAttribute('data-colorized', true);
    _img.src = canvas.toDataURL();
   };
  }
 });
 (function (factory, window) {
  // define an AMD module that relies on 'leaflet'
  if (typeof define === 'function' && define.amd) {
   define(['leaflet'], factory);
   // define a Common JS module that relies on 'leaflet'
  } else if (typeof exports === 'object') {
   module.exports = factory(require('leaflet'));
  }
  // attach your plugin to the global 'L' variable
  if (typeof window !== 'undefined' && window.L) {
   window.L.tileLayer.colorizr = factory(L);
  }
 }(function (L) {
  return function (url, options) {
   return new Colorizr(url, options);
  };
 }, window));
})()

 

用上面的代码直接顶替掉下面这个js插件中的所有代码

基于leaflet.js实现修改地图主题样式的流程分析

以下是使用的方式:

var map = L.map("map", {
  center: [34.694, 113.587],
  renderer: L.svg(),
  zoom: 16,
  zoomControl: false, // + -号放大缩小
  attributionControl: false // 右下角leaflet.js图标
 });
 // http://192.168.0.105:9090/img/{z}/{x}/{y}.png // 这个是瓦片地图的地址
 L.tileLayer.colorizr("http://localhost:9090/img/{z}/{x}/{y}.png", {
  maxZoom: 18,
  minZoom: 3,
  colorize: function (pixel) {
   // 这个方法用来调整所有的图片上的rgb值,pixel是图片原有的rgb值
   pixel.r += 13;
   pixel.g += 17;
   pixel.b += 90;
   return pixel;
  }
 }).addTo(map);

需要注意的是,可以配合着给图片加滤镜来做:

.leaflet-zoom-animated img {
   -webkit-filter: invert(50%) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important;
   -ms-filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important;
   -moz-filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important;
   filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(1%) !important;
  }

通过修改colorize的返回值就可以实现修改地图的样式了。
总结下实现思路: 这种方法主要是通过拦截地图瓦片数据,然后通过canvas(本人后端,不是太懂,反正这东西能操作图片)操作图片来修改图片的rgb值,从而达到修改地图样式的目的。
最后,感谢下友好的国际友人(虽然没能帮到我),嘻嘻。
可以看看我们有趣的聊天记录

最后的最后,给大家附上一个我自己基于leaflet。js实现的离线地图服务器(下载与部署一体)

总结

到此这篇关于基于leaflet.js实现修改地图主题样式的文章就介绍到这了,更多相关leaflet.js修改地图主题样式内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js no-repeat写法 背景不重复
Mar 18 Javascript
js操作输入框提示信息且响应鼠标事件
Mar 25 Javascript
checkbox勾选判断代码分析
Jun 11 Javascript
如何编写高质量JS代码
Dec 28 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
Feb 25 Javascript
JavaScript中各种引用类型的常用操作方法小结
May 05 Javascript
详解使用jQuery.i18n.properties实现js国际化
May 04 jQuery
详解如何从零开始搭建Express+Vue开发环境
Jul 17 Javascript
如何根据业务封装自己的功能组件
Apr 19 Javascript
js定义类的方法示例【ES5与ES6】
Jul 30 Javascript
微信小程序封装多张图片上传api代码实例
Dec 30 Javascript
逐行分析鸿蒙系统的 JavaScript 框架(推荐)
Sep 17 Javascript
uni-app从安装到卸载的入门教程
May 15 #Javascript
Vue数据双向绑定原理实例解析
May 15 #Javascript
JavaScript鼠标悬停事件用法解析
May 15 #Javascript
JavaScript enum枚举类型定义及使用方法
May 15 #Javascript
Vue如何基于es6导入外部js文件
May 15 #Javascript
JavaScript onclick事件使用方法详解
May 15 #Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
May 15 #Javascript
You might like
基于simple_html_dom的使用小结
2013/07/01 PHP
php实例分享之html转为rtf格式
2014/06/02 PHP
PHP实现redis限制单ip、单用户的访问次数功能示例
2018/06/16 PHP
Yii框架学习笔记之session与cookie简单操作示例
2019/04/30 PHP
js 去除字符串第一位逗号的方法
2014/06/07 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
2014/09/03 Javascript
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
jQuery prototype冲突的2种解决方法(附demo示例下载)
2016/01/21 Javascript
AngularJS基础 ng-include 指令简单示例
2016/08/01 Javascript
JavaScript 对象详细整理总结
2016/09/29 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
JS排序算法之希尔排序与快速排序实现方法
2017/12/12 Javascript
vue弹窗组件的实现示例代码
2018/09/10 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
uni-app 组件里面获取元素宽高的实现
2019/12/27 Javascript
Vue-CLI 3 scp2自动部署项目至服务器的方法
2020/07/24 Javascript
javascript开发实现贪吃蛇游戏
2020/07/31 Javascript
[12:29]2018国际邀请赛 开幕秀
2018/08/22 DOTA
[55:56]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
[01:01:14]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第一场 11.21
2020/11/23 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
一步步教你用Python实现2048小游戏
2017/01/19 Python
详解python中requirements.txt的一切
2017/03/03 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
2017/11/06 Python
Python使用三种方法实现PCA算法
2017/12/12 Python
Django在pycharm下修改默认启动端口的方法
2019/07/26 Python
Python切图九宫格的实现方法
2019/10/10 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
Python数组并集交集补集代码实例
2020/02/18 Python
keras导入weights方式
2020/06/12 Python
美国眼镜网站:LensCrafters
2020/01/19 全球购物
销售演讲稿范文
2014/01/08 职场文书
学术会议邀请函范文
2014/01/22 职场文书
新闻编辑专业毕业自荐书范文
2014/02/05 职场文书
质量负责人岗位职责
2015/02/15 职场文书
世界上超棒的8种逻辑思维
2019/08/06 职场文书