基于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 相关文章推荐
jquery 3D球状导航的文章分类
Jul 06 Javascript
基于JavaScript代码实现pc与手机之间的跳转
Dec 23 Javascript
JS组件中bootstrap multiselect两大组件较量
Jan 26 Javascript
基于MVC+EasyUI的web开发框架之使用云打印控件C-Lodop打印页面或套打报关运单信息
Aug 29 Javascript
jquery——九宫格大转盘抽奖实例
Jan 16 Javascript
基于JSONP原理解析(推荐)
Dec 04 Javascript
JavaScript实现省市联动过程中bug的解决方法
Dec 04 Javascript
浅谈vue的几种绑定变量的值 防止其改变的方法
Mar 01 Javascript
angular4 JavaScript内存溢出问题
Mar 06 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 Javascript
JS如何实现手机端输入验证码效果
May 13 Javascript
Javascript类型判断相关例题及解析
Aug 26 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
一个ORACLE分页程序,挺实用的.
2006/10/09 PHP
php变量作用域的深入解析
2013/06/03 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
2016/09/11 PHP
PHP实现二维数组根据key进行排序的方法
2016/12/30 PHP
php+ajax实现异步上传文件或图片功能
2017/07/18 PHP
php微信开发之图片回复功能
2018/06/14 PHP
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
javascript实现window.print()去除页眉页脚
2014/12/30 Javascript
jQuery实现友好的轮播图片特效
2015/01/12 Javascript
chrome不支持form.submit的解决方案
2015/04/28 Javascript
JavaScript严格模式详解
2015/11/18 Javascript
JavaScript位置与大小(1)之正确理解和运用与尺寸大小相关的DOM属性
2015/12/26 Javascript
使用angularjs创建简单表格
2016/01/21 Javascript
jquery validate表单验证插件
2016/09/06 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
在Js页面通过POST传递参数跳转到新页面详解
2017/08/25 Javascript
js实现图片上传并预览功能
2018/08/06 Javascript
Vue的click事件防抖和节流处理详解
2019/11/13 Javascript
浅析Vue下的components模板使用及应用
2019/11/27 Javascript
[42:52]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[15:20]DOTA2-DPC中国联赛 正赛 Elephant vs Aster 选手采访
2021/03/11 DOTA
Django框架下在URLconf中指定视图缓存的方法
2015/07/23 Python
python设置环境变量的作用和实例
2019/07/09 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
iframe跨域的几种常用方法
2019/11/11 HTML / CSS
英国领先的家庭时尚品牌:Peacocks
2018/01/11 全球购物
乌克兰珠宝大卖场:Zlato.ua
2020/09/27 全球购物
阳光体育活动实施方案
2014/05/25 职场文书
酒店管理失职检讨书
2014/09/16 职场文书
高校群众路线教育实践活动剖析材料
2014/10/10 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
幼儿园辞职书
2015/02/26 职场文书
施工员岗位职责范本
2015/04/11 职场文书
实用干货:敬酒词大全,帮你应付各种场合
2019/11/21 职场文书
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL
Python中tqdm的使用和例子
2022/09/23 Python