openlayers绘制带箭头的线并根据视角缩放而缩放

103 阅读1分钟

效果图

map.gif

代码实现

// 根据自己项目情况初始化地图,我这个用mapObj保存。部分构造函数名称和官网有出入,原因是我引入时自定义了别名
let mapObj = new Map({ target: this.$refs.mapDom, controls: [] });
let mapView = new View({center});

// 添加线样式的函数
function styleFunction (feature) {
  // feature是通过创建线时new Feature传过来的
 // 河流线缩放系数
  let Scale = 0.002 / mapView.getResolution(); // 0.002根据实际想要的大小来定义
  // 实现最大及最小值
  function calculate () {
    if (Scale >= 60) {
      return 60
    } else if (Scale <= 8) {
      return 8
    } else {
      return Scale
    }
  }
  
  let wdAndHi = calculate()
  const geometry = feature.getGeometry();
  const styles = [
    new Style({
      stroke: new Stroke({
        color: '#e6effb8c',
        width: wdAndHi,
        lineCap: "arrow",
      }),
    }),
  ];
  // 添加箭头
  geometry.forEachSegment(function (start, end) {
    const dx = end[0] - start[0];
    const dy = end[1] - start[1];
    const rotation = Math.atan2(dy, dx);
    const coord = [start[0] + dx / 2, start[1] + dy / 2]
    styles.push(
      new Style({
        geometry: new GeomPoint(coord),
        image: new Icon({
          src: stream, // 使用自己的图片
          anchor: [0.75, 0.5],
          width: wdAndHi,
          height: wdAndHi,
          rotateWithView: true,
          rotation: -rotation,
        }),
      })
    );
  });
  return styles;
};
// 绘制线的函数
function createLine (lineDta) {
// lineDta 里面就是线的坐标,我这里可能会存在多条线,所以是个数组
  const source = new VectorSource();
  const vector = new VectorLayer({
    source: source,
    properties: {
      markType: "line", // 这里必须加上一个自定义属性,方便后续拿到这个图层
    },
  });
  mapObj.addLayer(vector)
  try {
    lineDta.forEach(item => {
      if (item.lineGeom && item.lineGeom.length) {
        const line = new GeomLineString(item.lineGeom)
        const lineFeature = new Feature({
          geometry: line
        })
        lineFeature.setStyle(styleFunction(lineFeature));
        source.addFeature(lineFeature);
      }
    })
  } catch (err) {
    console.log(err);
  }
},

createLine();

// 监听地图的移动和缩放后的回调,这里根据自己业务情况一定要在地图初始化完毕后再执行
mapObj.on("moveend", mapMoveEnd)
// 缩放后的回调
function mapMoveEnd() {
    let layers = mapObj.getLayers().array_ && mapObj.getLayers().array_.length && mapObj.getLayers().array_
    let layer = layers.find(layer=>{
        return layer.getProperties()?.markType == "line"
    })
    let source =layer && layer.getProperties()?.source
    let features = source && source.getFeatures()
    if (features && features.length) {
        features.forEach(f => {
          f.setStyle(styleFunction(f))
        })
    }
}

最后的最后记得销毁地图的监听事件: mapObj && mapObj.un("moveend",mapMoveEnd)