基于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 相关文章推荐
javascript 不间断的图片滚动并可点击
Jan 15 Javascript
javascript打开word文档的方法
Apr 16 Javascript
纯JS焦点图特效实例(可一个页面多用)
Dec 07 Javascript
jquery无法为动态生成的元素添加点击事件的解决方法(推荐)
Dec 26 Javascript
js实现旋转木马效果
Mar 17 Javascript
详解使用nvm安装node.js
Jul 18 Javascript
详解开源的JavaScript插件化框架MinimaJS
Oct 26 Javascript
webpack+react+antd脚手架优化的方法
Apr 02 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
May 18 Javascript
原生js封装的ajax方法示例
Aug 02 Javascript
Node.js从字符串生成文件流的实现方法
Aug 18 Javascript
Vue数字输入框组件使用方法详解
Feb 10 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
探讨:如何通过stats命令分析Memcached的内部状态
2013/06/14 PHP
10条php编程小技巧
2015/07/07 PHP
PHP中检索字符串的方法分析【strstr与substr_count方法】
2017/02/17 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
Javascript Object.extend
2010/05/18 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
2014/06/09 Javascript
jquery.idTabs 选项卡使用示例代码
2014/09/03 Javascript
js事件处理程序跨浏览器解决方案
2016/03/27 Javascript
JS实现分页浏览横向图片(类轮播)实例代码
2017/11/06 Javascript
NodeJs form-data格式传输文件的方法
2017/12/13 NodeJs
vue v-model动态生成详解
2018/06/30 Javascript
Vue父子组件双向绑定传值的实现方法
2018/07/31 Javascript
vue 自定义右键样式的实例代码
2019/11/06 Javascript
基于vuex实现购物车功能
2021/01/10 Vue.js
利用Python的Twisted框架实现webshell密码扫描器的教程
2015/04/16 Python
在Python中使用Neo4j数据库的教程
2015/04/16 Python
tensorflow更改变量的值实例
2018/07/30 Python
python多进程控制学习小结
2018/10/31 Python
python 一个figure上显示多个图像的实例
2019/07/08 Python
python对象销毁实例(垃圾回收)
2020/01/16 Python
python scatter函数用法实例详解
2020/02/11 Python
Python2手动安装更新pip过程实例解析
2020/07/16 Python
美国性感女装网站:bebe
2017/03/04 全球购物
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
女士时装鞋:Chinese Laundry
2018/08/29 全球购物
建材业务员岗位职责
2013/12/08 职场文书
预备党员思想汇报范文
2014/01/11 职场文书
七年级音乐教学反思
2014/01/26 职场文书
4S店售后客服自我评价
2014/04/09 职场文书
道士塔读书笔记
2015/06/30 职场文书
情人节单身感言
2015/08/03 职场文书
Java如何实现通过键盘输入一个数组
2022/02/15 Java/Android
python数字类型和占位符详情
2022/03/13 Python
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
2022/05/30 NodeJs