components/layer/gpsLayer.js

/*``
 * @Author: tjc
 * @Date:   2017-04-20 17:03:05
 * @Last Modified by:   hydata
 * @Last Modified time: 2018-05-10 17:10:59
 * @Email: 304861063@qq.com
 * @File Path: F:\work\hyMap\src\components\layer\buildingLayer.js
 * @File Name: clustersLayer.js
 * @Descript:GPS图层
 */
import mapboxgl from 'mapbox-gl';
import baseLayer from './baseLayer';
import { getGreatCircleDistance } from '../../tools/mapTools';

/**
 * gps图层
 * @extends baseLayer
 */
class GpsLayer extends baseLayer {
    /**
     * 
     * @param {*} options 
     */
    constructor(options) {

        super(options);
        this.lastPoint = [];
        this.init(options.serie);

    }

    /**
     * 初始化
     * @param {*} serie 
     */
    init(serie) {

        //this.map.getSource('point').setData(pointOnCircle(timestamp / 1000));
        this.lastPoint = serie.data[0].geoCoord;
        //图标信息
        let marker =
            {
                'properties': {
                    'message': 'Foo',
                    'iconSize': [serie.symbolStyle.normal.symbolWidth, serie.symbolStyle.normal.symbolHeight]
                },
                'geometry': {
                    'type': 'Point',
                    'coordinates': this.lastPoint
                }
            };
        //获取图标容器
        let el = document.createElement('gpsLayer_marker');
        el.style.width = marker.properties.iconSize[0] + 'px';
        el.style.height = marker.properties.iconSize[1] + 'px';
        el.style.backgroundImage = 'url(' + serie.symbol + ')';
        el.style.backgroundRepeat = 'no-repeat';

        this.slider = new mapboxgl.Marker(el)
            .setLngLat(this.lastPoint)
            .addTo(this.map);

    }

    /**
     * 更新
     * @param {*} serie 
     */
    update(serie) {

        let lastPoint = this.lastPoint;
        let currentCoordinate = serie.data[0].geoCoord;
        if (!serie.smooth) {

            this.slider.setLngLat(currentCoordinate);

        }
        else {

            let distance = getGreatCircleDistance(lastPoint, currentCoordinate).toFixed(0);
            let speed = serie.speed || 30;

            let count = (distance * 3.6 / speed).toFixed(0) - 0;
            let index = 0;
            const run = () => {

                if (currentCoordinate[0] !== lastPoint[0]) {

                    let k = (currentCoordinate[1] - lastPoint[1]) / (currentCoordinate[0] - lastPoint[0]);
                    this.slider.setLngLat([lastPoint[0] + (currentCoordinate[0] - lastPoint[0]) * index / (count - 1), lastPoint[1] + (currentCoordinate[0] - lastPoint[0]) * k * index / (count - 1)]);

                }
                else {

                    this.slider.setLngLat([lastPoint[0], lastPoint[1] + (currentCoordinate[0] - lastPoint[0]) * index / (count - 1)]);

                }
                index++;

                let loop;
                if (index < count) {

                    loop = window.requestAnimationFrame(run);

                }
                else {

                    window.clearInterval(loop);
                    this.lastPoint = serie.data[0].geoCoord;

                }

            };
            run();

        }

    }
}

export default GpsLayer