使用openlayers扩展插件ol-ext设置地图指定区域高亮
最近要实现一个从底图向上发光的功能,着实纠结了好久,起初像是使用polygon 颜色透明度来实现,但毕竟底图不亮,增加图层效果不理想呀
一、ui设计是这样
二、绘制面
为底图增加一个MultiPolygon来实现效果,
代码片段
import {styleSwitch} from '@/components/common/set_style'; mapInit(){
this.mapObj = new Map({
target: el,
view: view
});
// 初始geoJson
var vectorSource = new VectorSource({
features: (new GeoJSON()).readFeatures(self.geojsonObject)
}); var vectorLayer = new VectorLayer({
renderMode: "image",
source:vectorSource,
style:self.styleFunction,
maxResolution: 2,
zIndex:2
});
this.mapObj.addLayer(vectorLayer);
},
styleFunction(feature, resolution) { return styleSwitch(feature.getGeometry().getType(), resolution, feature)
},
set_style.js
import {Fill, Stroke, Style, RegularShape, Text, Icon,Circle,} from 'ol/style';
import { DEVICE_PIXEL_RATIO } from "ol/has";
/**
* 主要景区 polygon ,multipolygon, line , multiline 样式设置
* 根据geojson类型设置地图样式
* @param type
* @param resolution
* @param feature
* @return {string}
*/
export function styleSwitch(type, resolution, feature) {
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
// Generate a rainbow gradient
let gradient = (() => {
let grad = context.createLinearGradient(
220*DEVICE_PIXEL_RATIO,20*DEVICE_PIXEL_RATIO,4220*DEVICE_PIXEL_RATIO,220*DEVICE_PIXEL_RATIO
);
// 设置开始结束颜色
grad.addColorStop(0, "rgba(0,192,50,0.4)");
grad.addColorStop(0.5, "rgba(0,192,50,0.2)");
grad.addColorStop(1, "rgba(1,134,82,0.5)"); return grad;
})(); var text = resolution < 0.0054931640625 ? feature.get('name') : ''; //根据分辨率控制文字显示级别
let styleItem = [];
switch (type) {
case 'Point':
case 'MultiPoint':
styleItem = [
new Style({
image: new Icon({
src: 'images/left_module/police/police_topSmallIcon_second.png',
size: [24, 26],
color: '#ff0000'
}),
text: new Text({
offsetX: 14,
offsetY: 10,
font: '12px Calibri,sans-serif',
text: text,
fill: new Fill({
color: '#DC143C'
}),
stroke: new Stroke({
color: '#fff',
width: 3
})
})
})
]
break;
case 'MultiLineString':
case 'LineString':
styleItem = [
new Style({
stroke: new Stroke({
color: 'rgba(247,246,46, 0.2)',
lineDash: [5],
width: 8
})
}),
new Style({
stroke: new Stroke({
color: "rgba(247,246,46, 1)",
lineDash: [5],
width: 3
}),
})
]
break;
case 'Polygon':
case 'MultiPolygon': styleItem = [
new Style({
// fill: new Fill({
// color: gradient
// }),
stroke: new Stroke({
color: "rgba(255,255,255,0.1)",
width: 2
}),
zIndex: 0
}),
new Style({
stroke: new Stroke({
color: 'rgba(245,255,250, 0.2)',
lineCap: 'round',
lineJoin:'bevel',
width: 10
})
}),
new Style({
stroke: new Stroke({
color: "rgba(0,149,32,0.1)",
lineCap: 'round',
lineJoin:'bevel',
width: 2
})
}), // new Style({
// fill: new Fill({
// color: [0,149,32, 0.8]
// })
// }),
]
break;
case 'GeometryCollection':
styleItem = [
new Style({
stroke: new Stroke({
color: 'magenta',
width: 2
}),
fill: new Fill({
color: 'magenta'
}),
image: new Icon({
src: 'images/left_module/police/police_topSmallIcon_second.png',
size: [24, 26],
color: '#ff0000'
}),
text: new Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new Fill({
color: '#DC143C'
}),
stroke: new Stroke({
color: '#fff',
width: 3
})
})
})
]
break;
case 'Circle':
styleItem = [
new Style({
stroke: new Stroke({
color: 'red',
width: 2
}),
fill: new Fill({
color: 'rgba(255,0,0,0.2)'
}),
image: new Icon({
src: 'images/left_module/police/police_topSmallIcon_second.png',
size: [24, 26],
color: '#ff0000'
}),
text: new Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new Fill({
color: '#DC143C'
}),
stroke: new Stroke({
color: '#fff',
width: 3
})
})
})];
break;
} return styleItem;
}
效果如下
三、使用.Render3D
后来想是否少了3D效果 ? 这又引用了ol-ext.layer.Render3D
,
效果如下
四、使用.Colorize
看还是相距胜远;于是想到了为底图增加透明色,于是引入了ol-ext.filter.Colorize
,
效果如下
颜色是着上了,可是 看源码得知
ol_filter_Colorize.prototype.postcompose = function(e) {
// Set back color hue
var ctx = e.context;
var canvas = ctx.canvas; ctx.save();
if (this.get('operation')=='enhance')
{ var v = this.get('value');
if (v)
{ var w = canvas.width;
var h = canvas.height;
ctx.globalCompositeOperation = 'color-burn'
ctx.globalAlpha = v;
ctx.drawImage (canvas, 0, 0, w, h);
ctx.drawImage (canvas, 0, 0, w, h);
ctx.drawImage (canvas, 0, 0, w, h);
}
}
else
{ ctx.globalCompositeOperation = this.get('operation');
ctx.fillStyle = this.get('color');
ctx.fillRect(0,0,canvas.width,canvas.height);
}
ctx.restore();
}
五、 使用.Mask 加 .Crop
这直接是使用canvas
绘制的一个面,很明显是方的了,最后想来想去想到使用ol-ext.filter.Colorize
来为底图着色,再使用ol-ext.filter.Mask
和ol-ext.filter.Crop
来根据坐标绘制凸显的面同时为地图增加蒙层,但是又遇到了ol-ext.filter.Mask
绘制的面和layerVector
位置不合问题
预览效果是这样的
canvas绘制和layerVector绘制的面偏移较多 | 但地图缩放时更明显 | 但地图缩放时更明显 |
代码片段
<script type="text/ecmascript-6">
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import {XYZ, Vector as VectorSource} from 'ol/source';
import {Fill} from 'ol/style';
import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
import GeoJSON from 'ol/format/GeoJSON';
import olExtColorize from 'ol-ext/filter/Colorize'
import olExtCrop from 'ol-ext/filter/Crop'
import olExtMask from 'ol-ext/filter/Mask'
import MultiPolygon from 'ol/geom/MultiPolygon'; export default = {
methods:{
mapInit(polygonCoordiantes) {
let self = this;
let proj = 'EPSG:4326';
let el = this.$refs.map;
let padLeft = (val, num, radix) => {
let str = val.toString(radix || 10);
return (new Array(num).join('0') + str).slice(-num);
}
var view = new View({
projection: proj,
center: [103.37324413479338, 29.544684360197113],
minZoom: 10,
zoom: 13,
maxZoom: 15,
extent: [102.1000671387,28.7086486816,104.7244262695,30.0448608398],
}); this.mapObj = new Map({
target: el,
view: view
}); var leshan_tile = this.initLeshanTile(proj, padLeft); this.mapObj.addLayer(leshan_tile);
// 點亮地圖
this.lingUpTheMap(leshan_tile); this.drawPolygonAndAddMask(leshan_tile,polygonCoordiantes)
},
/**
*
* 乐山瓦片加载
*/
initLeshanTile(proj, padLeft) {
// 乐山 瓦片图层
let layers_leshan = new TileLayer({
source: new XYZ({
crossOrigin: "anonymous",
projection: proj,
url: 'http://localhost:808/image_map/_alllayers/', tileUrlFunction: function (tileCoord, pixelRatio, proj) {
var x = 'C' + padLeft(tileCoord[1], 8, 16);
var y = 'R' + padLeft(tileCoord[2] -1, 8, 16);
var z = 'L' + padLeft(tileCoord[0], 2, 10);
var Newurl = 'http://localhost:808/image_map/_alllayers/' + z + '/' + y + '/' + x + '.png';
return Newurl;
}
}),
visible: true
}); return layers_leshan;
},
/**
*
* 點亮地圖
*/
lingUpTheMap(osm,){
// Enhance filter
var enhance = new olExtColorize({ operation:'enhance'});
osm.addFilter(enhance); // Custom filter
var filter = new olExtColorize();
osm.addFilter(filter); enhance.setActive(false);
filter.setActive(true);
filter.setFilter({
operation:'color',
red:Number('0'),
green: Number('192'), blue: Number('50'),
value: Number('1'),
});
},
/**
* 绘制面,同时增加蒙层
* @param osm {Object} tile 对象
* @param coordinatesOfPolygon {Array[[]]} 面的坐标数据
*/
drawPolygonAndAddMask(osm,coordinatesOfPolygon){ var f = new Feature(new MultiPolygon(coordinatesOfPolygon));
var crop = new olExtCrop({
feature: f,
inner: false
});
osm.addFilter(crop);
var mask = new olExtMask({
feature: f,
inner: false,
fill: new Fill({
color: [255, 255, 255, 0.8]
})
});
osm.addFilter(mask); mask.set('inner',false);
crop.set('inner', false);
mask.fillColor_ = 'rgba(0,0,0,0.8)';
// Activate
mask.set('active', true);
crop.set('active', false);
},
} }
</script>
六、处理canvas 绘制偏移问题
如上虽然实现了底图着色但是绘制的元素偏移这么多,这显然不是我想要的结果
后来测试了不知道多少遍,查了不知道多少资料没有一个是我要的答案!
最后没办法再次查看ol-ext.filter.Mask.js
源码
一遍又一遍看其中重要 的drawFeaturePath_
属性方法
/** Draw the feature into canvas */
ol_filter_Mask.prototype.drawFeaturePath_ = function(e, out)
{ var ctx = e.context;
var canvas = ctx.canvas;
var ratio = e.frameState.pixelRatio;
// Transform
var m = e.frameState.coordinateToPixelTransform;
var tr = function(pt)
{ return [
(pt[0]*m[0]+pt[1]*m[1]+m[4])*ratio,
(pt[0]*m[2]+pt[1]*m[3]+m[5])*ratio
];
}
// Old ol version
if (!m)
{ m = e.frameState.coordinateToPixelMatrix;
tr = function(pt)
{ return [
(pt[0]*m[0]+pt[1]*m[1]+m[12])*ratio,
(pt[0]*m[4]+pt[1]*m[5]+m[13])*ratio
];
}
}
// Geometry
var ll = this.feature_.getGeometry().getCoordinates();
if (this.feature_.getGeometry().getType()=="Polygon") ll = [ll];
ctx.beginPath();
if (out)
{ ctx.moveTo (0,0);
ctx.lineTo (canvas.width, 0);
ctx.lineTo (canvas.width, canvas.height);
ctx.lineTo (0, canvas.height);
ctx.lineTo (0, 0);
}
for (var l=0; l<ll.length; l++)
{ var c = ll[l];
for (var i=0; i<c.length; i++)
{ var pt = tr(c[i][0]);
ctx.moveTo (pt[0], pt[1]);
for (var j=1; j<c[i].length; j++)
{ pt = tr(c[i][j]);
ctx.lineTo (pt[0], pt[1]);
}
}
}
}
如下这句代码引起了我的注意
var ratio = e.frameState.pixelRatio;
查看API
大概意思是 帧的像素比率
这个方法明细是使用canvas
根据当前feature
的坐标结合当前像素 帧 来绘制元素的, 然 帧的像素比率 会根据地图缩放而发生改变,所以绘制的面元素也随着像素变法不停发生偏移,最后想得到不根据帧的像素比率 来绘制元素他的位置不就对了吗!最后去掉 ratio
;修噶代码为
// Transform
var m = e.frameState.coordinateToPixelTransform;
var tr = function(pt)
{ return [
(pt[0]*m[0]+pt[1]*m[1]+m[4]),
(pt[0]*m[2]+pt[1]*m[3]+m[5])
];
}
再运行看效果
这次效果终于要好点了,但是还有待改进,毕竟离ui设计图还有一些距离,加油继续…
最后附上官网地址便于查阅
使用openlayers扩展插件ol-ext设置地图指定区域高亮的更多相关文章
- OpenLayers 3 扩展插件收集
OpenLayers 3 扩展插件 Awesome-OpenLayers OL3扩展 ol3-ext 很酷的一组 OpenLayers 3 (ol3) 扩展: 编辑-选择控件.CSS popup(弹出 ...
- 地图 SDK 系列教程-在地图上展示指定区域(转载)
腾讯位置服务地图SDK是一套提供多种地理位置服务的应用程序接口.通过调用该接口,开发者可以在自己的应用中加入地图相关的功能(如地图展示.标注.绘制图形等),轻松访问腾讯地图服务和数据,构建功能丰富.交 ...
- jupyter notebook设置主题背景,字体和扩展插件
windows上安装Anaconda (IPython notebook) Anaconda是一个包与环境的管理器,一个Python发行版,以及一个超过1000多个开源包的集合.它是免费和易于安装的, ...
- 100个精选zencart扩展插件
100个精选zencart扩展插件 特别推荐 1. 数据库备份 2. 产品横向布局. 3. 邮件订阅Newsletter Subscribe. 4. google 翻译google_translate ...
- Sharepoint 2013列表视图和字段权限扩展插件(免费下载)!
记得2014年春节期间,有博客园的网友通过QQ向我咨询Sharepoint 2013列表视图和字段权限扩展,因为之前他看到我博客介绍Sharepoint 2010列表视图和字段的权限控制扩展使用,问有 ...
- ExtJS4.2学习(13)基于表格的扩展插件---rowEditing
鸣谢:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-24/182.html --------------- ...
- Angular TypeScript开发环境集成jQuery扩展插件
集成步骤: 1.安装jquery极其扩展插件库ts定义文件 npm install jquery --save npm install --save-dev @types/jquery npm ins ...
- 那些离不开的 Chrome 扩展插件
虽然Chrome浏览器是个吃内存的怪兽,但是,它却因为启动速度.调试功能等成为了程序猿的必备浏览器!今天有时间,整理一下自己最常用的一些Chrome扩展吧: 常用网页浏览非开发类扩展: Tamperm ...
- Echarts 设置地图上文字大小及颜色
Echarts 设置地图上文字大小及颜色,效果如下: 上代码:关键代码用红色 series: [ { //name: '香港18区人口密度', type: 'map', mapType: 'jiang ...
- vs2010(vs2012)好用的扩展插件介绍
一直以来只使用番茄vs助手(https://www.wholetomato.com/downloads/default.asp)辅助写代码,也都忘了是谁介绍的,不过确实好用. 相比原始的vs,它提供了 ...
随机推荐
- 在wxpython框架写的GUI中调用GIF格式图片,显示在指定行列的方法
#首先需要从 wx.adv 模块导入 Animation, AnimationCtrl方法 from wx.adv import Animation, AnimationCtrl #然后在面板实现过程 ...
- 当基础设施故障后,声网 SD-RTN™ 如何保障 RTE 服务的高可用性
云计算的出现为企业的管理.业务开展.资源整合等带来了极大的便利性,也是数字化建设的核心基建之一,然而局部宕机或者大面积宕机事件对于云厂商来说却也无法避免,全球领先的计算平台也不例外.例如,美国东部时间 ...
- 小知识:SQL Monitor Report的使用
在上一篇 优化利器In-Memory开启和效果 中,提到的两个SQL对比,使用的是传统的dbms_xplan.display_cursor方式来查看执行计划,好处是文本输出的通用性强,基本信息也都有. ...
- Salesforce LWC学习(十二) Dependence Picklist实现
本篇可参看: Salesforce LWC学习(六) @salesforce & lightning/ui*Api Reference salesforce零基础学习(八十七)Apex 中Pi ...
- Docker常用软件安装
jdk dockere pull openjdk:11 docker run -d -t --name java-11 openjdk:11 MySQL 可以从docker hup中查找自己想要安装的 ...
- VUE3.x之Proxy 我们为什么要使用Proxy
Object.defineProperty 劫持数据 只是对对象的属性进行劫持 无法监听新增属性和删除属性 需要使用 vue.set, vue.delete 深层对象的劫持需要一次性递归 劫持数组时需 ...
- Helm 安装 Kubernetes 监控套件
Helm 安装 Grafana Prometheus Altermanager 套件 安装helm # 安装helm工具 curl -fsSL -o get_helm.sh https://raw.g ...
- Kubernetes(k8s)集群安装JupyterHub以及Lab
背景 JupyterHub 为用户组带来了笔记本的强大功能.它使用户能够访问计算环境和资源,而不会给用户带来安装和维护任务的负担.用户--包括学生.研究人员和数据科学家--可以在他们自己的工作空间中完 ...
- ChatGPT 与 Midjourney 强强联手,让先秦阿房宫重现辉煌!
Midjourney 是一款非常特殊的 AI 绘画聊天机器人,它并不是软件,也不用安装,而是直接搭载在 Discord 平台之上,所有的功能都是通过调用 Discord 的聊天机器人程序实现的.要想使 ...
- Redis 数据类型 Set
Redis 数据类型 Set(集合) Redis 常用命令,思维导图 >>> Redis 的 Set 是 String 类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复 ...