mapbox跑马灯

1. 效果

跑马灯

2. RoouteRunning

import * as turf from "@turf/turf"

export default class RouteRunning{
    map: any

    routejson: any

    data: Array

    timeData: Array

    VLayer: any

    VLayerTwo: any

    lineOptions: object

    animationOptions: object

    constructor(map: any, routejson: any, lineOptions: object, animationOptions: object) {
        this.map = map
        this.routejson = routejson
        this.data = []
        this.timeData = []

        this.VLayer = null

        this.VLayerTwo = null

        this.lineOptions = {
            strokeStyle: lineOptions.strokeStyle || 'rgba(0,255,255,1)',
            shadowColor: lineOptions.shadowColor || 'rgba(125,125,125,0.2)',
            shadowBlur: lineOptions.shadowBlur || 3,
            lineWidth: lineOptions.lineWidth || 3,
            globalAlpha: lineOptions.globalAlpha || 1,
            globalCompositeOperation: 'lighter',
            coordType: 'bd09mc',
            draw: 'simple'
        }

        this.animationOptions = {
            fillStyle: animationOptions.fillStyle || 'rgba(255,255,241,0.2)',
            coordType: 'bd09mc',
            globalCompositeOperation: 'lighter',
            size: animationOptions.size || 3,
            animation: animationOptions.animation || {
                stepsRange: {
                    start: 0,
                    end: 50
                },
                trails: this.map.getZoom() > 10 ? 5 : 3,
                duration: 2
            },
            draw: 'simple'
        }

        this.init()
    }

    init() {
        let lineList = []
        // 动态点密集程度
        let density = {
            7:1,
            8: 0.5,
            9: 0.45,
            10: 0.35,
            11: 0.2,
            12: 0.08,
            13: 0.04,
            14: 0.02,
            15: 0.02,
            16: 0.02,
            17: 0.02
        }
        // 当前zoom密集程度
        let currentDensity = density[Math.round(this.map.getZoom())]
        // eslint-disable-next-line no-plusplus
        for (let i = 0; i < this.routejson.length; i++) {
            const pointList = [...this.routejson[i].geometry.coordinates]
            const newPointList = []
            // eslint-disable-next-line no-plusplus
            for (let j = 0; j < pointList.length; j++) {
                if (pointList[j + 1]) {

                    // 计算两点之间距离
                    const from = turf.point(pointList[j])
                    const to = turf.point(pointList[j + 1])
                    const options = { units: 'kilometers' }
                    // @ts-ignore
                    const distance = turf.distance(from, to, options)

                    if (distance > currentDensity) {
                        const midpoint = turf.getCoord(turf.midpoint(from, to))
                        pointList.splice(j + 1, 0, midpoint)
                        // eslint-disable-next-line no-plusplus
                        j--
                    } else {
                        newPointList.push(pointList[j])
                    }
                } else {
                    newPointList.push(pointList[j])
                }
            }
            lineList.push(newPointList)
        }
        const newLineList: any[] = []
        lineList.forEach(i => {
            const arr = i
            const node1 = Math.floor(arr.length * 0.33)
            const node2 = Math.floor(arr.length * 0.66)
            const newArr1 = [...arr.slice(node1), ...arr.slice(0, node1)]
            const newArr2 = [...arr.slice(node2), ...arr.slice(0, node2)]
            newLineList.push(i)
            newLineList.push(newArr1, newArr2)
        })

        // eslint-disable-next-line no-plusplus
        for (let i = 0; i < newLineList.length; i++) {
            let item = newLineList[i]
            let coordinates = []
            for (let j = 0; j < item.length; j += 1) {
                coordinates.push(item[j])

                this.timeData.push({
                    geometry: {
                        type: 'Point',
                        coordinates: item[j]
                    },
                    count: 1,
                    time: j
                })
            }
        }

        // eslint-disable-next-line no-plusplus
        for (let i = 0; i < lineList.length; i++) {
            this.data.push({
                geometry: {
                    type: 'LineString',
                    coordinates: lineList[i]
                }
            })
        }
    }

    drawLine() {
        let options = {
            // size: 5, // 大小值
            // unit: 'm', // 可选px或者m
            // fillStyle: 'rgba(200, 200, 50, 1)', // 填充颜色
            // // strokeStyle: 'rgba(120, 0, 255, 1)', // 描边颜色
            // lineWidth: 4, // 描边宽度
            // globalAlpha: 1, // 透明度
            // globalCompositeOperation: 'lighter', // 颜色叠加方式
            // shadowColor: 'rgba(255, 255, 255, 1)', // 投影颜色
            // shadowBlur: 35, // 投影模糊级数
            // shadowOffsetX: 0,
            // shadowOffsetY: 0,
            // lineCap: 'butt',
            // lineJoin: 'miter',
            // miterLimit: 10,

            strokeStyle: 'rgba(0,255,255,1)',
            coordType: 'bd09mc',
            globalCompositeOperation: 'lighter',
            shadowColor: 'rgba(125,125,125,0.2)',
            shadowBlur: 3,
            lineWidth: 3.0,
            draw: 'simple'
        }
        let options2 = {
            fillStyle: 'rgba(255,255,241,0.2)',
            coordType: 'bd09mc',
            globalCompositeOperation: 'lighter',
            size: this.map.getZoom() > 10 ? 3 : 2,
            animation: {
                stepsRange: {
                    start: 0,
                    end: 50
                },
                trails: this.map.getZoom() > 10 ? 5 : 3,
                duration: 2
            },
            draw: 'simple'
        }

        // 动态图层渲染
        this.VLayer = new mapboxgl.supermap.MapvLayer(
            this.map,
            new mapv.DataSet(this.data),
            this.lineOptions)
        this.VLayerTwo = new mapboxgl.supermap.MapvLayer(
            this.map,
            this.timeData,
            this.animationOptions)

        this.map.addLayer(this.VLayer)
        this.map.addLayer(this.VLayerTwo)
    }

    clear(){
        if(this.VLayer){
            this.VLayer.removeFromMap()
        }
        if(this.VLayerTwo){
            this.VLayerTwo.removeFromMap()
        }
    }

}

3. 使用

running = new RouteRunning(map, routeGeoJson1.features, {}, {})

running.drawLine()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值