angular中使用openlayer画运动轨迹从初始化开始

angular中使用openlayer画运动轨迹从初始化开始

初始化地图

mapBasicLayerSource = new OSM({
  warpX: true
});//加载街道地图
routeCoords = [
    [102.3662707918166, 29.233057577468536],
    [102.95566898358834, 29.979673112610453],
    [103.10564651280956, 30.068605295035848],
    [103.5015264278803, 30.183655962483723],
    [103.83079867892431, 30.31694162614948],
    [104.02724352786919, 30.579441557719907]
  ]
// 初始化地图
initMap() {
    const view = new View({
      center: [],
      zoom: this.zoomLevel,
      projection: 'EPSG:4326',
      minZoom: this.MinZoom,
      maxZoom: this.MaxZoom
    })
    // projection
    const projection = 'EPSG:4326';
    const layers = [];

    this.mapOptions = {
      target: 'mainMap',
      projection,
      layers,
      view,
      controls: [
        // new MousePosition(
        //   {
        //     target: document.getElementById('mouse-position')
        //   }
        // )
      ],
    };
    try {
      this.map = new OLMAP(this.mapOptions);
    } catch (ex) {
    }
    //  //实例化全屏显示控件
    //  var fullScreenControl = new FullScreen();
    //   //将全屏显示控件加载到map中
    //   this.map.addControl(fullScreenControl);
  }

加载图层

 const mapBasicLayer = new TileLayer({
   title: 'basicMap',
   source: this.mapBasicLayerSource
 });
 // 把图层放入LAYERS集合中
this._layersMap.set('BASIC_LAYER', mapBasicLayer);
for (const [key, layer] of this._layersMap.entries()) {
   this.map.addLayer(layer);
}

将两点之间分割成多个点,使得运动速度更平滑

    const splitNumberQuick = 50// 分割点控制速度
    const splitNumber = 300// 分割点控制速度
    var tempPath = JSON.parse(JSON.stringify(this.routeCoords))
    var pathResults = []
    var tempPoint = [0, 0]
    if (tempPath.length > 1) {
      for (let i = 0; i < tempPath.length - 1; i++) { // 每两个点之间分割出splitNumber个点
        pathResults.push(tempPath[i])
        if (i == 0) {
          for (let j = 0; j < splitNumber; j++) {
            tempPoint[0] = (tempPath[i + 1][0] - tempPath[i][0]) * (j + 1) / splitNumber + tempPath[i][0]
            tempPoint[1] = (tempPath[i + 1][1] - tempPath[i][1]) * (j + 1) / splitNumber + tempPath[i][1]
            pathResults.push(JSON.parse(JSON.stringify(tempPoint)))
          }
        } else {
          for (let j = 0; j < splitNumberQuick; j++) {
            tempPoint[0] = (tempPath[i + 1][0] - tempPath[i][0]) * (j + 1) / splitNumberQuick + tempPath[i][0]
            tempPoint[1] = (tempPath[i + 1][1] - tempPath[i][1]) * (j + 1) / splitNumberQuick + tempPath[i][1]
            pathResults.push(JSON.parse(JSON.stringify(tempPoint)))
          }
        }

      }
      pathResults.push(tempPath[tempPath.length - 1])
      this.routeCoords = pathResults
      }

绘制路径和点

// lineString出现坐标点显示不全时 把坐标加上parseFloat,原因就是没有把float类型的坐标利用parseFloat强转,导致默认的泛数据类型精确度不够,经纬度小数点后末尾几位就会被忽略,于是造成数据失效,描出的线就会有问题。
var route = new LineString(this.routeCoords);
    var routeLength = this.routeCoords.length;
    this.routeFeature = new Feature({
      type: 'route',
      geometry: route,
    });
    this.geoMarker = /** @type Feature<import("../src/ol/geom/Point").default> */ (new Feature(
      {
        type: 'geoMarker',
        geometry: new Point(this.routeCoords[0]),
      }
    ));
    var startMarker = new Feature({
      type: 'icon',
      geometry: new Point(this.routeCoords[0]),
    });
    var endMarker = new Feature({
      type: 'icon',
      geometry: new Point(this.routeCoords[routeLength - 1]),
    });
    var stopMakers = [];
    const routeCoords = [
      [],//经纬度
    ]
    var stopText = []
    for (var i = 0; i < routeCoords.length; i++) {
      var s = new Feature({
        type: 'stop',
        geometry: new Point(routeCoords[i])
      });
      stopMakers.push(s);
    }
    for (var i = 0; i < routeCoords.length; i++) {
      var s = new Feature({
        type: 'text',
        geometry: new Point(routeCoords[i]),
        name: this.stopNameList[i]
      });
      stopText.push(s);
    }
    const that = this
    this.stylesMap = {
      'route': function (feature) {
        var geometry = feature.getGeometry();
        var length = geometry.getLength();//获取线段长度 
        var radio = length * 0.08;

        var dradio = 10000;//投影坐标系,如3857等,在EPSG:4326下可以设置dradio=10000 
        var styles = [
          new Style({
            stroke: new Stroke({
              color: "green",
              width: 6,
            })
          })
        ];
        for (var i = 0; i <= 1; i += radio) {
          var arrowLocation = geometry.getCoordinateAt(i);
          geometry.forEachSegment(function (start, end) {
            if (start[0] == end[0] || start[1] == end[1]) return;
            var dx1 = end[0] - arrowLocation[0];
            var dy1 = end[1] - arrowLocation[1];
            var dx2 = arrowLocation[0] - start[0];
            var dy2 = arrowLocation[1] - start[1];
            if (dx1 != dx2 && dy1 != dy2) {
              if (Math.abs(dradio * dx1 * dy2 - dradio * dx2 * dy1) < 0.001) {
                var dx = end[0] - start[0];
                var dy = end[1] - start[1];
                var rotation = Math.atan2(dy, dx);
                styles.push(new Style({
                  geometry: new Point(arrowLocation),
                  image: new Icon({
                    src: '',
                    anchor: [0.75, 0.5],
                    rotateWithView: false,
                    rotation: -rotation + Math.PI,
                    scale: 0.3
                  })
                }));
              }
            }
          });
        }
        return styles;
      },
      'icon': new Style({
        image: new Icon({
          anchor: [0, -0.1],
          scale: 0.2,
          src: '',
        }),
      }),
      'geoMarker': new Style({
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({ color: '#000' }),
          stroke: new Stroke({
            color: 'white',
            width: 2,
          }),

        }),
      }),
      'stop': new Style({
        image: new Icon({
          anchor: [0.8, 1.9],
          scale: 0.5,
          src: '',
        }),

      }),
      'text': function (feature) {
        var styles = [
          new Style({
            text: new Text({
              font: '12px sans-serif',
              text: feature.getProperties().name,
              offsetX: -6,
              offsetY: -20,
              textBaseline: "top",
              textAlign: "center",
              fill: new Fill({
                color: "#000",
              }),
              stroke: new Stroke({ color: "rgba(255,255,255,0)" }),
            })
          })
        ];
        return styles
      }
      };

    this.vectorLayer = new VectorLayer({
      source: new VectorSource({
        features: [this.routeFeature, startMarker, this.geoMarker, ...stopMakers, ...stopText, endMarker],
      }),
      style: function (feature) {
        if (that.animating && feature.get('type') === 'geoMarker') {
          return null;
        }
        const myStyle = that.stylesMap[feature.get('type')];
        if (myStyle instanceof Function) {
          return myStyle(feature);
        }
        return myStyle;
      },
    });
    this.map.addLayer(this.vectorLayer);
    // 动画以及监听是否点击播放
    var moveFeature = function (event) {
      var vectorContext = getVectorContext(event);
      var frameState = event.frameState;
      if (that.animating) {
        var elapsedTime = frameState.time - that.now;
        var index = Math.round((that.speed * elapsedTime) / 100);
        if (index >= routeLength) {
          stopAnimation(true);
          return;
        }
        let currentPoint = new Point(that.routeCoords[index])
        var feature = new Feature(currentPoint);
        vectorContext.drawFeature(feature, that.stylesMap.geoMarker);

      }
      that.map.render();
    };
    function startAnimation() {
      if (that.animating) {
        stopAnimation(false);
      } else {
        that.animating = !that.animating;
        that.now = new Date().getTime();
        that.speed = 5;
        that.geoMarker.setStyle(null);
        that.vectorLayer.on('postrender', moveFeature);
        that.map.render();
      }
    }
    function stopAnimation(ended) {
      that.play = !ended
      that.animating = false;
      var coord = ended ? that.routeCoords[routeLength - 1] : that.routeCoords[0];
      var geometry = that.geoMarker.getGeometry();
      geometry.setCoordinates(coord);
      //移除监听
      that.vectorLayer.un('postrender', moveFeature);
    }
    document.getElementById('play').addEventListener('click', startAnimation, false)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值