Openlayers 距离环绘制
思路:利用layer的StyleFunction 来使地图移动或者放缩的时候,使圆保持在地图中心
/**
* 绘制距离环
* @param {number} distance 每环间隔距离,单位:米
* @param {array} texts 要显示的内容
* @description 创建了个layer,然后在layer的styleFunction中做了配置,这里搞了6个环,每两个是一组;搞两个的原因是为了在左侧和右侧都显示当前环的尺寸
*/
export function drawDistanceRing(distance, texts) {
const map = window.map
const layer = new VectorLayer({
source: new VectorSource(),
zIndex: 999,
projection: 'EPSG:4326',
style: function (feature) {
const center = map.getView().getCenter()
const proj = map.getView().getProjection()
const [offsetL1, offsetR1, offsetL2, offsetR2, offsetL3, offsetR3] = calcDistanceRingTextOffset(center, distance * 0.9) // 计算每个环标签像素偏移量
return [
new Style({ // 每个style都是一个环
geometry: circular(center, distance * 1, 128),
text: new Text({
text: texts[0],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL1[0],
offsetY: offsetL1[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 1, 128),
text: new Text({
text: texts[0],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR1[0],
offsetY: offsetR1[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 2, 128),
text: new Text({
text: texts[1],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL2[0],
offsetY: offsetL2[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 2, 128),
text: new Text({
text: texts[1],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR2[0],
offsetY: offsetR2[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 3, 128),
text: new Text({
text: texts[2],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL3[0],
offsetY: offsetL3[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 3, 128),
text: new Text({
text: texts[2],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR3[0],
offsetY: offsetR3[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
]
}
})
const feature = new Feature(fromExtent(map.getView().getProjection().getExtent())) // layer得有feature,不然不显示
layer.getSource().addFeature(feature)
map.addLayer(layer)
}
/**
* 移除距离环
*/
export function removeDistanceRing(layer) {
if (layer) {
layer.getSource().clear()
window.map.removeLayer(layer)
}
}
/**
* 计算距离环文字偏移量
* @param {array} location 距离环圆心坐标
* @param {number} distance 每个环间距
* @returns 六个环偏移量
*/
function calcDistanceRingTextOffset(location, distance) {
const point = turf.point(location) // 用到了turf这个库
const destination1R = turf.destination(point, distance, 90, 'meters' ).geometry.coordinates
const destination1L = turf.destination(point, distance, 270, 'meters' ).geometry.coordinates
const destination2R = turf.destination(point, distance * 2, 90, 'meters' ).geometry.coordinates
const destination2L = turf.destination(point, distance * 2, 270, 'meters' ).geometry.coordinates
const destination3R = turf.destination(point, distance * 3, 90, 'meters' ).geometry.coordinates
const destination3L = turf.destination(point, distance * 3, 270, 'meters').geometry.coordinates
const pixelCenter = getPixelFromCoordinate(location)
const pixel1R = getPixelFromCoordinate(destination1R)
const pixel1L = getPixelFromCoordinate(destination1L)
const pixel2R = getPixelFromCoordinate(destination2R)
const pixel2L = getPixelFromCoordinate(destination2L)
const pixel3R = getPixelFromCoordinate(destination3R)
const pixel3L = getPixelFromCoordinate(destination3L)
const offsetR1 = [pixel1R[0] - pixelCenter[0] - 5, pixel1R[1] - pixelCenter[1]]
const offsetL1 = [pixel1L[0] - pixelCenter[0], pixel1L[1] - pixelCenter[1]]
const offsetR2 = [pixel2R[0] - pixelCenter[0], pixel2R[1] - pixelCenter[1]]
const offsetL2 = [pixel2L[0] - pixelCenter[0], pixel2L[1] - pixelCenter[1]]
const offsetR3 = [pixel3R[0] - pixelCenter[0], pixel3R[1] - pixelCenter[1]]
const offsetL3 = [pixel3L[0] - pixelCenter[0], pixel3L[1] - pixelCenter[1]]
return [offsetL1, offsetR1, offsetL2, offsetR2, offsetL3, offsetR3]
}
效果图:

感谢
Openlayers 距离环绘制的更多相关文章
- OpenLayers学习笔记(八)— 类似比例尺的距离环(二)
openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环. 这篇是上一篇 ...
- OpenLayers学习笔记(七)— 类似比例尺的距离环(一)
openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环.注意,根据地图 ...
- Floyd判圈算法(判断是否有环)
介意转吗博主~~http://blog.csdn.net/thestoryofsnow/article/details/6822576,我知道不介意啦~ 问题:如何检测一个链表是否有环,如果有,那么如 ...
- WebGL绘制有宽度的线
WebGL中有宽度的线一直都是初学者的一道门槛,因为在windows系统中底层的渲染接口都是D3D提供的,所以无论你的lineWidth设置为多少,最终绘制出来的只有一像素.即使在移动端可以设置有宽度 ...
- 通过openlayers加载dwg格式的CAD图并与互联网地图叠加
Openlayers介绍 Openlayers是一个基于Javacript开发,免费.开源的前端地图开发库,使用它,可以很容易的开发出WebGIS系统.目前Openlayers支持地图瓦片.矢量数 ...
- 【leetcode】Linked List Cycle II (middle)
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- Programming Assignment 5: Kd-Trees
用2d-tree数据结构实现在2维矩形区域内的高效的range search 和 nearest neighbor search.2d-tree有许多的应用,在天体分类.计算机动画.神经网络加速.数据 ...
- 学习记录 java 链表知识
01.import java.util.HashMap; 02.import java.util.Scanner; 03.import java.util.Stack; 04. 05./** 06. ...
- 一个完整openlayer的例子,包括marker,popup等
整理转自:http://www.blogjava.net/siriusfx/archive/2007/11/26/163104.html openlayers提供了几十个示例,虽然每个示例都很简单,但 ...
- 浅谈canvas绘画王者荣耀--雷达图
背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了, ...
随机推荐
- C#使用CsRedis操作Redis
C#使用CsRedis操作Redis 转:脚本之家(https://www.jb51.net/article/201034.htm) 现在流行的redis连接客户端有StackExchange.Red ...
- vue开发一个简单的组件
首先在项目中新建一个js文件 在文件内创建一个对象,对象内创建install方法,将对象用export default暴漏出去 export default{ install(){ console.l ...
- Git因换行符不一致导致反复有修改记录
前情 Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理,我公司目前都是基于Git来管理项目代码. 坑位 最近刚刚入职一家新公司,本地环境都配好 ...
- Python开发一个Instant Messaging(IM)(即时通讯)聊天工具:从理论到实践
一.引言 在现代社会中,即时通讯工具已经成为人们日常沟通的重要工具.开发一个IM聊天工具不仅能够提高我们的编程技能,还能让我们更好地理解即时通讯系统的原理.本文将详细介绍如何开发一个简单的IM聊天工具 ...
- 从底层源码深入分析Bean的实例化
生命周期的整体流程 Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁. ...
- Flutter之GetX之路由管理
GetX之路由管理 GetX有一套完整的路由管理,并且不需要context上下文,API非常简洁 直接导航 导航到新的页面 Get.to(NextScreen()); 返回,此方法可以用于关闭Snac ...
- WinDbg: SOSEX 下载,加载和使用帮助
SOSex 是 SOS 的扩展,由 Steve Johnson 开发,他是微软的一个员工,开发并免费提供了 SOSex for download 的下载,但该软件并不开源. 通常,该扩展不能与其他 D ...
- 2024年1月Java项目开发指南8:统一数据返回格式
有时候返回一个字符串,有时候返回一串数字代码,有时候返回一个对象-- 不过怎么说,我们返回的内容往往具有三个 1.消息代码 code 2.消息内容 msg 3.数据内容 data 接下来,我们要编写一 ...
- containerd 导入镜像
containerd 导入镜像 containerd而非docker,需要离线导入镜像 解决原理https://segmentfault.com/a/1190000019534913ctr --nam ...
- Android保活从入门到放弃:乖乖引导用户加白名单吧(附7大机型加白示例)
1.引言 IM在Android上的保活问题经常在即时通讯网的论坛和技术群里被讨论,自从Android 8.0后系统大大降低了后台运行应用的保活容忍度(详见<Android P正式版即将到来:后台 ...