首页 > 其他分享 >Openlayers 距离环绘制

Openlayers 距离环绘制

时间:2023-08-04 13:47:34浏览次数:47  
标签:pixelCenter distance const geometry text 距离 Openlayers new 绘制

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

效果图:
image
感谢

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

标签:pixelCenter,distance,const,geometry,text,距离,Openlayers,new,绘制
From: https://www.cnblogs.com/echo-lovely/p/17605657.html

相关文章

  • 化学绘图软件ChemDraw Mac版,绘制简单的化学元素
    ChemDraw是一款化学绘图软件,在化学领域中,它可以绘制简单的化学物质的结构,属性和数据,甚至是一些数据图表。它在绘制过程中所展现出来的强大功能是非常适合做精细研究的,并且操作非常简单,它只需要点击一下鼠标就可以进行简单的操作,一步操作就可以完成它。可以制作简单的颜色,形状,图表(......
  • Python绘制多种形式的条形图(柱状图)
    绘图前的准备因为涉及到中文显示,所以需要用两行代码解决中文乱码问题importnumpyasnpfrommatplotlibimportpyplotaspltplt.rcParams['font.sans-serif']=[u'SimHei']#SimHei就是中文字体#因为设置了中文后,负号就乱码了,所以还要设置负号的编码plt.rcParams['axes.......
  • 通过 IMU 绘制物体移动的空间轨迹
    一般IMU由加速度传感器、陀螺仪组成,也叫6轴IMU。还可以外加一个磁力计,构成9轴IMU。关于加速度传感器和陀螺仪的工作原理,可以参考:加速度传感器的原理和应用-手机翻转、失重检测、运动检测、位置识别;MEMS三轴加速计、三轴陀螺仪、三轴磁力计)6轴IMU+磁力计,9轴传感器讲解;......
  • [数据分析与可视化] Python绘制数据地图4-MovingPandas入门指北
    MovingPandas是一个基于Python和GeoPandas的开源地理时空数据处理库,用于处理移动物体的轨迹数据。它提供了一组强大的工具,可以轻松地加载、分析和可视化移动物体的轨迹。通过使用MovingPandas,用户可以轻松地处理和分析移动对象数据,并从中提取有关行为、模式和趋势的见解。无论是处......
  • 常见距离计算的Python实现
    常见的距离有曼哈顿距离、欧式距离、切比雪夫距离、闵可夫斯基距离、汉明距离、余弦距离等,用Python实现计算的方式有多种,可以直接构造公式计算,也可以利用内置线性代数函数计算,还可以利用scipy库计算。1.曼哈顿距离也叫城市街区距离,是两点差向量的L1范数,也就是各元素的绝对值之和......
  • 代码随想录算法训练营第四十三天| 583. 两个字符串的删除操作 72. 编辑距离
    583.两个字符串的删除操作要求:删除最少的步数,来让这两个字符串相等思路:求末尾的最长公共子序列的长度,然后减去他们的长度代码:1//要求:两个字符串,删除任意一个字符后,让这两个字符相等2//dp[n][m]以n-1结尾的字符串变成节点为m-1为子序列的最大个数3//4//求......
  • Android View绘制原理 - SkCanvas
    上一篇文章介绍了在Android框架中的各种Canvas,其中C层的RecordingCanas承上启下,在SkiaRecordingCanvas的绘制方法会通过调用它的mRecorder来记录,而这个mRecorder的类型正好就是SkCanvas,准确的说是它的子类RecordingCanas。而各种绘制方法会对应生成一个Op对象来描述这个绘制操作,Rec......
  • MATLAB plot绘制图像
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • Revit二次开发-用GDI+绘制线样式
      最近有个需求就是将动态讲当前文档中的线样式绘制出来,并且显示在自己的UI上。查阅了一下api文档以及吉米大佬的博客,并且这篇博客中受到启发填充样式绘制然后自己琢磨了一下,成功将线样式绘制出来了。但是目前有个问题就是圆点我在dashpattern里面设置的是1f的单位,如果图片......
  • 2023-07-31 在uniapp使用canvas绘制一个圆角为50%的图片【代码来自chatGpt,稍作修改】
    <template><view><canvasid="myCanvas":style="{width:'200px',height:'200px'}"></canvas></view></template><script>exportdefault{onReady(){this.......