百度地图动态绘制台风轨迹

效果图如下:

在这里插入图片描述
在这里插入图片描述

台风测试数据获取

关键代码:

        /**
         * 动态绘制点和线
        */
        drawMakerByAnimate () {
            const pointsMap = typhoneData.points;
            const title = typhoneData.tfid + typhoneData.name;

            if (!pointsMap || pointsMap.length === 0) {
                return;
            }

            if (this.markers.length > 0 && this.baiduMap) {
                this.markers = [];
                this.baiduMap.clearOverlays();
            }
            // console.log(pointsMap.length);
            const linePoints = pointsMap.map((item) => new BMapGL.Point(item.lng, item.lat));

            // 添加第一个点的标签
            if (linePoints.length > 0) {
                const firstPoint = linePoints[0];
                const label = new BMapGL.Label(title, {
                    position: firstPoint,
                    offset: new BMapGL.Size(20, -5)
                });
                label.setStyle({
                    color: '#000',
                    fontSize: '15px',
                    backgroundColor: 'white',
                    border: '1px solid #000',
                    borderRadius: '3px',
                    padding: '0 5px',
                    whiteSpace: 'nowrap'
                });
                this.baiduMap.addOverlay(label);
                this.markers.push(label);
                // 绘制折线和点
                if (linePoints.length === pointsMap.length) {
                    this.animateMarkersAndPolyline(pointsMap, linePoints);
                }

            }
        },

          animateMarkersAndPolyline (pointsMap, linePoints) {
            // 检查 linePoints 是否有数据
            if (!linePoints || linePoints.length === 0) {
                console.error('数据无效或为空');
                return;
            }

            // 创建并添加 GIF 动画元素
            const createTyphoonAnimation = (point) => {
                // 确保之前的动画被移除
                const existingAnimation = document.getElementById('typhoon-animation');
                if (existingAnimation) {
                    existingAnimation.remove();
                }

                const img = document.createElement('img');
                img.src = typhoonImg; // 动图的路径
                img.id = 'typhoon-animation';
                img.style.position = 'absolute';
                img.style.width = '32px'; // 动图的宽度
                img.style.height = '32px'; // 动图的高度
                img.style.zIndex = 1000; // 确保在其他标记之上

                // 添加到地图容器
                document.getElementById('baiduMapLevelTwo').appendChild(img);

                // 更新位置
                const pixel = this.baiduMap.pointToPixel(point);
                img.style.left = `${pixel.x - 16}px`;// 确定图标中心点
                img.style.top = `${pixel.y - 16}px`;// 确定图标中心点
            };

            let index = 0;
            const stepDuration = 50; // 每步的时间间隔(毫秒)
            // console.log(linePoints);
            let newLines = [];
            const showNext = () => {
                if (index < linePoints.length) {
                    // console.log(linePoints[index]);
                    const point = linePoints[index];
                    newLines.push(point);
                    const item = pointsMap[index]; // 直接从 pointsMap 获取 item
                    const powerLevel = Number(item?.power); // 使用可选链确保 item 存在
                    const fillColor = this.getColorByPowerLevel(powerLevel);

                    // 创建并添加标记
                    const marker = new BMapGL.Label('', {
                        position: point,
                        offset: new BMapGL.Size(-6, -6)
                    });
                    marker.setStyle({
                        backgroundColor: fillColor,
                        width: '10px',
                        height: '10px',
                        borderRadius: '50%',
                        border: '1px solid #666',
                        display: 'block',
                        boxSizing: 'border-box'
                    });
                    marker.addEventListener('mouseover', () => {
                        this.showPopup(point, item);
                    });
                    marker.addEventListener('mouseout', () => {
                        this.closePopup();
                    });

                    this.baiduMap.addOverlay(marker);
                    this.markers.push(marker);

                    // 每次创建一个新的 Polyline
                    if (this.polylines) {
                        this.baiduMap.removeOverlay(this.polylines);
                    }

                    this.polylines = new BMapGL.Polyline(newLines, {
                        strokeColor: '#0076C9',
                        strokeWeight: 1,
                        strokeOpacity: 1
                    });
                    this.baiduMap.addOverlay(this.polylines);

                    // 更新台风图标位置
                    createTyphoonAnimation(point);
                    // typhoonMarker.setPosition(point);

                    index++;
                    setTimeout(showNext, stepDuration);
                }
            };

            showNext();
        },
        showPopup (point, item) {
            let popupDiv = document.getElementById('typhoon-popup');

            // 如果不存在,就创建一个新的
            if (!popupDiv) {
                popupDiv = document.createElement('div');
                popupDiv.id = 'typhoon-popup';
                document.body.appendChild(popupDiv);
            }

            // 更新内容
            popupDiv.innerHTML = `
                <div style="padding: 10px; background: white; border: 1px solid #ccc; 
                            box-shadow: 0px 0px 5px rgba(0,0,0,0.3); border-radius: 5px;color:#303334;font-size:14px">
                    <strong>台风时间:</strong> ${item.time}</br>
                    <strong>中心位置:</strong> ${item.lng}°/${item.lat}°</br>
                    <strong>风速风力:</strong> ${item.speed}米/秒,
                    ${item.power}级<label style="color:red">(${item.strong})</label></br>
                    <strong>移速移向:</strong> ${item.movespeed}公里/小时,${item.movedirection}</br>
                </div>
            `;


            // 获取像素坐标
            const pixel = this.baiduMap.pointToPixel(point);
            popupDiv.style.position = 'absolute'; // 确保是悬浮定位
            popupDiv.style.zIndex = '9999';
            popupDiv.style.left = `${pixel.x + 20}px`; // 调整以适应悬浮效果
            popupDiv.style.top = `${pixel.y - 40}px`;
            popupDiv.style.display = 'block';
        },
        closePopup () {
            const popupDiv = document.getElementById('typhoon-popup');
            if (popupDiv) {
                popupDiv.style.display = 'none';
            }
        },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值