基于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 相关文章推荐
YUI 读码日记之 YAHOO.util.Dom - Part.1
Mar 22 Javascript
Ajax搜索结果页面下方的分页按钮的生成
Apr 05 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
Apr 24 Javascript
基于JQuery实现的Select级联
Jan 27 Javascript
js实现最短的XML格式化工具实例
Mar 12 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
Jun 11 Javascript
使用plupload自定义参数实现多文件上传
Jul 19 Javascript
基于javaScript的this指向总结
Jul 22 Javascript
JS匿名函数内部this指向问题详析
May 10 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
Sep 06 Javascript
在vue中使用el-tab-pane v-show/v-if无效的解决
Aug 03 Javascript
JavaScript本地储存:localStorage、sessionStorage、cookie的使用
Oct 13 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
jQuery 源码分析笔记
2011/05/25 PHP
基于preg_match_all采集后数据处理的一点心得笔记(编码转换和正则匹配)
2014/01/31 PHP
php使用session二维数组实例
2014/11/06 PHP
PHP中strpos、strstr和stripos、stristr函数分析
2016/06/11 PHP
PHP二维数组去重实例分析
2016/11/18 PHP
游戏人文件夹程序 ver 3.0
2006/07/14 Javascript
豆瓣网的jquery代码实例
2008/06/15 Javascript
javascript 写类方式之六
2009/07/05 Javascript
利用js的Node遍历找到repeater的一个字段实例介绍
2013/04/25 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
jQuery实现的Div窗口震动效果实例
2015/08/07 Javascript
Bootstrap Modal遮罩弹出层(完整版)
2016/11/21 Javascript
值得分享的Bootstrap Table使用教程
2016/11/23 Javascript
vue分类筛选filter方法简单实例
2017/03/30 Javascript
微信小程序实现侧边分类栏
2019/10/21 Javascript
如何在python中使用selenium的示例
2017/12/26 Python
Python 写入训练日志文件并控制台输出解析
2019/08/13 Python
详解python常用命令行选项与环境变量
2020/02/20 Python
Pytorch环境搭建与基本语法
2020/06/03 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
HTML5中input输入框默认提示文字向左向右移动的示例代码
2020/09/10 HTML / CSS
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
DJI全球:DJI Global
2021/03/15 全球购物
毕业生自我推荐
2013/11/04 职场文书
语文教育专业应届生求职信
2013/11/23 职场文书
蛋糕店的商业计划书范文
2014/01/27 职场文书
教师网络培训感言
2014/03/09 职场文书
团日活动总结
2014/04/28 职场文书
2014最新版群众路线四风整改措施
2014/09/24 职场文书
给上级领导的感谢信
2015/01/22 职场文书
军训个人总结
2015/03/03 职场文书
售后服务质量承诺书
2015/04/29 职场文书
岁月神偷观后感
2015/06/11 职场文书
Pytest中conftest.py的用法
2021/06/27 Python