当我们遇到问题的时候改如何解决
本文不讲技术,不撸代码,只讲思路。
一、问题
在Openlayers中展示风速风向图,共分为以下两个阶段:
加载PNG图片→加载SVG图片
二、解决
1、加载PNG图片
问题 在Openlayer3中直接加载PNG图片,在API中提供了ImageStatic可以将图片展示出来,但是如何设置图片的imageExtent让图片能够在地图的正确位置展示成了问题的关键。
解决 首先,看到官方的demo里面有个加载ImageStatic的例子,于是就看了一下,官方的例子是通过proj定义了图片的坐标,这样通过坐标转换的方式将静态图片叠加到了地图上。(此过程,我的理解遥感里面做影像的纠正的原理类似。)
有了上面代码的思路,我就想如果我的输出的图片是按照地图的坐标输出的话是不是就可以直接叠加上去而不用做图片的投影了。接下来,就在Arcmap里面打开了一个tif数据,将其直接通过Export Data导出为PNG,并查看其属性获取到图象的四至。
再在代码里面根据输出的PNG和四至信息做测试,哎,思路是对的,能够完美的叠加到地图上。
实现代码
var bounds = [63.9796331669,14.7451916725, 140.181255914,55.4673388687];
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees'
});
var image = new ol.layer.Image({
source: new ol.source.ImageStatic({
url: "img/china.png",
imageExtent: bounds
})
});
有了上面的测试,终于明白了OL3中StaticImage的加载逻辑。
2、加载SVG图片
由于是PNG图片,在地图放大后会有马赛克现象,特别影像视觉效果,所以为了让展示的效果更加美观,所以就考虑将PNG图片换乘SVG图片。换完之后,首先是在Leaflet中做的测试,比PNG的效果好很多。可当我将SVGyizhi到Openlayers中的时候傻眼了,效果如下:
这个不是臣妾想要的,我想要高清,不要模糊!!!
所以,就开始了研究如何展示SVG。百度、谷歌、必应了一圈后,发现Openlayers的开发者给大家的回复是OL3的版本没法加载SVG!WHAT???没法加载,这不是逗我呢??不过呢,我想这个问题我一定可以解决的!!
后来一直在思考这个问题,有一天突然灵光一现:我可以在地图上面那直接叠加一层SVG的,类似于曾经做过的OL3和echat的结合的逻辑,再绑定地图的事件刷新不就OK了,没错,就是这个思路,哦,此时觉的我就是个天才!
可是当我写好代码,运行代码的时候,发现地图动不了了?怎么办???怎么办???可不能这样啊!!!还好我机智,瞄了一眼OL4的源码,发现地图的时间是在Map这个div上面触发的,所以我就想到了把这个img放到map div里面,代码如下:
self.image = new Image();
self.image.src = self._url;
self._map.getViewport().appendChild(self.image);
再测试,哈哈,妥了,再加点地图事件,就搞定了!此刻深深的被我的聪明才智折服。
但是,我就是这样一个perfect的人,为了更加好用所以我将此扩展成了一个类,源码如下:
/**
* @author lzugis
* 2017-10-20
* @param option, 默认参数如下
{
map:null,
extent:[],
url:"",
opacity:1,
visible:true
}
*/
ol.layer.SvgImageLayer = function(option){
this._option = {
map:null,
extent:[],
url:"",
opacity:1,
visible:true
};
this._init(option);
};
ol.layer.SvgImageLayer.prototype = {
image:null,
_init:function(option){
//将option合并
for(var opt in option){
this._option[opt] = option[opt];
}
this._map = this._option.map;
this._extent = this._option.extent;
this._url = this._option.url;
this._opacity = this._option.opacity;
this._visible = this._option.visible;
},
addToMap:function(){
if(this._map) {
var self = this;
self.image = new Image();
self.image.src = self._url;
self._map.getViewport().appendChild(self.image);
self._updateImgStyle();
self._addMapEvent();
}
else{
alert("map参数定义不正确!");
}
},
updateImage: function(option){
this._init(option);
if(option.url)this.image.src = this._url;
this._updateImgStyle();
},
hide: function(){
this.image.style.display = "none";
},
show: function(){
this.image.style.display = "";
},
destroy: function(){
this.image.remove();
},
_updateImgStyle: function(){
var self = this;
var _min = [self._extent[0], self._extent[1]],
_max = [self._extent[2], self._extent[3]],
_topLeft = [self._extent[0], self._extent[3]];
var _scrMin = self._toScreenPoint(_min),
_scrMax = self._toScreenPoint(_max),
_scrTopLeft = self._toScreenPoint(_topLeft);
var _w = Math.round(_scrMax[0] - _scrMin[0]),
_h = Math.round(_scrMin[1] - _scrMax[1]),
_left = _scrTopLeft[0],
_top = _scrTopLeft[1];
var cssText = "";
var styles = {
"opacity": self._opacity,
"z-index": 0,
"position":"absolute",
"width":_w+"px",
"height":_h+"px",
"top":_top+"px",
"left":_left+"px"
};
for(var style in styles){
cssText+=style+":"+styles[style]+";"
}
self.image.style.cssText = cssText;
self._visible?self.show():self.hide();
},
_addMapEvent:function(){
var self = this;
self._map.on("precompose",function(evt){
evt.stopPropagation();
self._updateImgStyle();
});
},
_toScreenPoint: function(mapPoint){
var srcPoint = this._map.getPixelFromCoordinate(mapPoint);
return srcPoint;
}
};
ol.inherits(ol.layer.SvgImageLayer, ol.layer.base);
实现后,效果如下,心理满满的成就感。。。
正当我沉溺在满满的成就感的时候,有一天,突然发现,我的WMS图层怎么被盖住了???Oh, NO!!!!Kill me!!OL4中map所有的图层都是绘制在一个canvas画布里面的,我叠上去一个图层势必会挡住的,肿么办?what can I do for you??不行,我不能坐以待毙,要是让客户发现这个问题就惨了,客户是我们的衣食父母,这个时候就必须体现我们的专业性和我的钻研性了。
于是乎,上git,扒源码,看了好一阵,都没找到头绪,怎么办,我可不是就此放手的人。恩,先看看API再说,突然,看到了imageSize,凭我的直觉,他应该就是我要找的,这个时候就又不得不发挥我的主观能动性了,计算了一个大小就贴上去,wonderful!!!
附上源码如下:
var bounds = [12836027.844390793, 4745190.4650304755, 13098185.245208949, 5069741.1276835548];
var source = new ol.source.ImageStatic({
url: "bjoutput/wind.svg",
imageExtent: bounds,
imageSize:getImageSize(bounds)
});
image.setSource(source);
//获取图片大小
function getImageSize(bounds){
var _min = [bounds[0], bounds[1]],
_max = [bounds[2], bounds[3]],
_topLeft = [bounds[0], bounds[3]];
var _scrMin = map.getPixelFromCoordinate(_min),
_scrMax = map.getPixelFromCoordinate(_max);
var _w = Math.round(_scrMax[0] - _scrMin[0]),
_h = Math.round(_scrMin[1] - _scrMax[1]);
return [_w, _h];
}
三、总结
写此篇的目的是为了告诉大家姿势的正确解锁方式,要善于思考,勤于动手,问题才会解决。
山重水复疑无路,柳暗花明又一村
- 有趣的rownum测试(r10笔记第49天)
- 【Go 语言社区】关于Golang 数据缓存到redis内存数据库遇到的问题
- go中的读写锁RWMutex
- Centos7.4 版本环境下安装Mysql5.7操作记录
- 你必须知道的23个最有用的Elasticseaerch检索技巧
- Elasticsearch Jest实战深入详解
- 在oracle中计算时间差
- 【Go 语言社区】GO中怎么处理URL编码?
- C语言库函数rename
- Oracle 12c DG新特性Far Sync(r10笔记第67天)
- iOS微信特殊字符保护方案
- 简单易学的机器学习算法——谱聚类(Spectal Clustering)
- oracle数据库 如何查询某个表的约束条件
- 结构体存入文件并且取出
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android WorkManager浅谈
- 详解Android 8.0以上系统应用如何保活
- 秒级去重:ClickHouse在腾讯海量游戏营销活动分析中的应用
- android studio 3.4配置Android -jni 开发基础的教程详解
- android TextView中识别多个url并分别点击跳转方法详解
- Android WebView支持input file启用相机/选取照片功能
- 谈谈RxJava2中的异常及处理方法
- Android Koin2基本使用的那件事儿
- 一篇文章弄懂kotlin的扩展方法
- 浅谈Android客户端与服务器的数据交互总结
- Android 连接匿名WiFi的示例代码
- Android自定义图文跑马灯效果
- Android自定义View实现可展开、会呼吸的按钮
- Android仿google now效果的呼吸按钮
- Kotlin中双冒号::使用方法