基于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 相关文章推荐
24款非常有用的 jQuery 插件分享
Apr 06 Javascript
文本域中换行符的替换示例
Mar 04 Javascript
浅谈 jQuery 事件源码定位问题
Jun 18 Javascript
node.js中的fs.readFile方法使用说明
Dec 15 Javascript
JavaScript中的toDateString()方法使用详解
Jun 12 Javascript
Google 地图API Map()构造器详解
Aug 06 Javascript
关于JavaScript中事件绑定的方法总结
Oct 26 Javascript
JS运动特效之链式运动分析
Jan 24 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
Sep 05 Javascript
解决layui动态加载复选框无法选中的问题
Sep 20 Javascript
layer.open提交子页面的form和layedit文本编辑内容的方法
Sep 27 Javascript
vue v-on:click传递动态参数的步骤
Sep 11 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
php 高性能书写
2010/12/11 PHP
PHP间隔一段时间执行代码的方法
2014/12/02 PHP
php生成图片验证码-附五种验证码
2015/08/19 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
BOM与DOM的区别分析
2010/10/26 Javascript
JavaScript 模式之工厂模式(Factory)应用介绍
2012/11/15 Javascript
Javascript 加载和执行-性能提高篇
2012/12/28 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
JavaScript怎么判断图片是否加载完成以便获取其尺寸
2014/05/08 Javascript
判断iframe里的页面是否加载完成
2014/06/06 Javascript
node.js使用require()函数加载模块
2014/11/26 Javascript
JS+DIV实现的卷帘效果示例
2017/03/22 Javascript
gulp解决跨域的配置文件问题
2017/06/08 Javascript
搭建一个nodejs脚手架的方法步骤
2019/06/28 NodeJs
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
javascript设计模式 ? 状态模式原理与用法实例分析
2020/04/22 Javascript
python黑魔法之参数传递
2016/02/12 Python
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
利用python实现简单的循环购物车功能示例代码
2017/07/05 Python
在Python web中实现验证码图片代码分享
2017/11/09 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
对python周期性定时器的示例详解
2019/02/19 Python
python处理自动化任务之同时批量修改word里面的内容的方法
2019/08/23 Python
python json.dumps中文乱码问题解决
2020/04/01 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
python图片合成的示例
2020/11/09 Python
纯CSS实现的大小渐变、渐远效果
2014/04/15 HTML / CSS
斯凯奇美国官网:SKECHERS美国
2016/08/20 全球购物
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
活动宣传策划方案
2014/05/23 职场文书
党的群众路线教育实践活动个人自我剖析材料
2014/10/07 职场文书
夫妻忠诚协议书范本
2014/11/17 职场文书
赡养老人协议书范本
2015/08/06 职场文书
穷人该怎么创业?谨记以下几点
2019/07/11 职场文书
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle
Python使用pyecharts控件绘制图表
2022/06/05 Python