思路:利用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]
}

效果图:



感谢

  1. 狐狸家的鱼 - 类似比例尺的距离环(一)

Openlayers 距离环绘制的更多相关文章

  1. OpenLayers学习笔记(八)— 类似比例尺的距离环(二)

    openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环. 这篇是上一篇 ...

  2. OpenLayers学习笔记(七)— 类似比例尺的距离环(一)

    openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环.注意,根据地图 ...

  3. Floyd判圈算法(判断是否有环)

    介意转吗博主~~http://blog.csdn.net/thestoryofsnow/article/details/6822576,我知道不介意啦~ 问题:如何检测一个链表是否有环,如果有,那么如 ...

  4. WebGL绘制有宽度的线

    WebGL中有宽度的线一直都是初学者的一道门槛,因为在windows系统中底层的渲染接口都是D3D提供的,所以无论你的lineWidth设置为多少,最终绘制出来的只有一像素.即使在移动端可以设置有宽度 ...

  5. 通过openlayers加载dwg格式的CAD图并与互联网地图叠加

    Openlayers介绍 ​ Openlayers是一个基于Javacript开发,免费.开源的前端地图开发库,使用它,可以很容易的开发出WebGIS系统.目前Openlayers支持地图瓦片.矢量数 ...

  6. 【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 ...

  7. Programming Assignment 5: Kd-Trees

    用2d-tree数据结构实现在2维矩形区域内的高效的range search 和 nearest neighbor search.2d-tree有许多的应用,在天体分类.计算机动画.神经网络加速.数据 ...

  8. 学习记录 java 链表知识

    01.import java.util.HashMap; 02.import java.util.Scanner; 03.import java.util.Stack; 04. 05./** 06. ...

  9. 一个完整openlayer的例子,包括marker,popup等

    整理转自:http://www.blogjava.net/siriusfx/archive/2007/11/26/163104.html openlayers提供了几十个示例,虽然每个示例都很简单,但 ...

  10. 浅谈canvas绘画王者荣耀--雷达图

    背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了, ...

随机推荐

  1. 一个.NET开源、易于使用的屏幕录制工具

    前言 一款高效.易用的屏幕录制工具能够极大地提升我们的工作效率和用户体验,今天大姚给大家分享一个.NET开源.免费.易于使用的屏幕录制工具:Captura. 工具介绍 Captura是一款基于.NET ...

  2. 【MyBatis】学习笔记06:各种查询所返回数据的数据类型

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) [MyBatis]学习笔记04:配 ...

  3. 【转载】 一次生产环境的NOHTTPRESPONSEEXCEPTION异常的排查记录

    https://www.freesion.com/article/41531004212/ 环境: jdk1.8+tomcat8+httpclient4.5.2 主要现象: 项目偶发出现org.apa ...

  4. Qt开源作品39-日志输出增强版V2022

    一.前言 之前已经开源过基础版本,近期根据客户需求和自己的项目需求,提炼出通用需求部分,对整个日志重定向输出类重新规划和重写代码. 用Qt这个一站式超大型GUI超市做开发已经十二年了,陆陆续续开发过至 ...

  5. Qt开源作品3-串口调试助手

    一.前言 这个作品很多年前就做了,经过了长达七八年的完善,当然也不是全身心的投入完善,也就是根据实际项目的需求不断完善的,尤其是模拟设备回复数据的功能,这个在很多用Qt做上位机开发非常实用,毕竟很多软 ...

  6. 一篇文章弄懂 JavaScript 中通过import导入模块的原理

    原文链接: 1.import 2.彻底理解JavaScript ES6中的import和export 3.JavaScript ES6中export.import与export default的用法和 ...

  7. 20. C++快速入门--并发基础

    参考:<Professional c++>,<并发编程实战> 1 基本概念 1.1 竞争 原子性 "原子"(atomic)操作是指一种不可分割的操作, 即在 ...

  8. 前端学习openLayers配合vue3(圆形形状的绘制)

    上节课我们学了加载了矢量图片,这节我们来学绘制圆形 关键代码,第一段呢是设置圆点的操作,第二步是点击地图获取地图位置来设置圆点,ol还有很多类,各种形状的 //设置圆点 // let anchorLa ...

  9. vue基础2

    1.表单 表单里面有单选框,多选框,下拉框,文本域 vue单页应用 SPA:signal page application(单页应用) 多页面:1个url->1个html文件 多个url-> ...

  10. C#正则表达式匹配候选词

    来自文心一言(多次修改才正确的): public App() { string input = "例子文字{备选,:'词1t324|备选词2gdfg,该方法|备选词3dsfdsf}继续{备选 ...