高德地图轨迹回放/轨迹播放

news2025/2/27 5:30:38

前言

本篇文章主要介绍高德地图的轨迹回放或播放的实现过程,是基于vue2实现的功能,同时做一些改动也是能够适配vue3的。其中播放条是用的是element UI中的el-slider组件,包括使用到的图标也是element UI自带的。可以实现轨迹的播放、暂停、停止、播放倍数,以及播放拖拽,涉及到的高德地图的相关权限申请,这里就不再赘述,好了,废话不多说,效果图附上。

效果图 


一、地图初始化

首先,需要在组件dom加载完毕后初始化地图,这里小谭直接用的new AMap.Map方法进行初始化,需要在index.html引入高德的服务。

<script src="https://webapi.amap.com/maps?v=2.0&key=你的key"></script>

其次,在引入高德服务之后,需要在单独引入高德AMapUI 组件库,因为轨迹播放是基于该组件库实现的,引入示例:

<!--引入UI组件库(1.1版本) -->
<script src="//webapi.amap.com/ui/1.1/main.js"></script>

最后,就可以进行初始化地图了,注意需要在组件dom加载完毕才能进行初始化!其中this.map是地图实例,附上代码:

 this.map = new AMap.Map('myMap', {
            zoom: 10, //级别
            center:[120.209758, 30.246809], //中心点坐标 默认在杭州
 });

二、轨迹插件初始化

在地图初始化完成之后,可以引入一些需要的插件,这里就不再过多赘述,我们直接引入AMapUI,我们这里用到的是PathSimplifier模块,故只需要引入该模块即可,附上代码:

//加载PathSimplifier,loadUI的路径参数为模块名中 'ui/' 之后的部分
new AMapUI.load(['ui/misc/PathSimplifier'], PathSimplifier => {
    if (!PathSimplifier.supportCanvas) {
        alert('当前环境不支持 Canvas!');
        return;
    }
    if (this.pathList?.length) {
        //启动页面
        this.initPage(PathSimplifier);
    }
});

其中,涉及到的this.pathList是我这边后端返回坐标点信息,this.pathList结构如下:

this.pathList = [
    [
        120.79580028, // 经度
        30.03570354 // 纬度
    ],
    ...
    
];

this.initPage方法如下,需要注意的是,方法内声明的content是轨迹播放时展示的车辆图标,如果不需要可以删掉,PathSimplifier中的配置请参照高德地图轨迹展示的开发文档,还有方法最后调用的this.cruiseInit方法已经放到下一部分了。

initPage(PathSimplifier) {
    let content = PathSimplifier.Render.Canvas.getImageContent(
        '/img/car1.png',
        () => {
            //图片加载成功,重新绘制一次
            this.pathSimplifierIns.renderLater();
        },
        function onerror(e) {
            this.$message({ type: 'error', message: '图片加载失败!' });
        }
    );
    this.pathSimplifierIns = new PathSimplifier({
        zIndex: 100,
        map: this.map,
        getPath: function (pathData, pathIndex) {
            return pathData.path;
        },
        renderOptions: {
            //轨迹线的样式
            getPathStyle: (pathItem, zoom) => {
                return {
                    pathLineStyle: {
                        strokeStyle: "red",
                        lineWidth: 6,
                        dirArrowStyle: true,
                    },
                };
            },
            pathNavigatorStyle: {
                initRotateDegree: 180,
                width: 20,
                height: 35,
                autoRotate: true,
                content,
            },
        },
    });
    this.cruiseInit(); //巡航器初始化
}

三、巡航器初始化

巡航器初始化方法this.cruiseInit代码如下:

cruiseInit() {
    let pathSimplifierIns = [{ path: this.pathList, color: '#28F' }];
    this.pathSimplifierIns.setData(pathSimplifierIns);
    this.pointSum = 0;
    pathSimplifierIns.forEach((item, index) => {
        this.pointSum += item.path.length;
    });

    this.marksIndex = marksIndex;
    this.cruiseStop();//如果已经存在巡航器,则停止播放
}

其中this.pointSum是为了记录巡航器的最终点数,方便对应到播放条的最大值。


四、巡航器的播放暂停等功能

巡航器的播放、暂停以及倍数的方法如下:

// 创建一个巡航器
createdCruise(index) {
    // 判断是否传入index
    let cruiseIndex;
    if (index != undefined) {
        cruiseIndex = index;
        this.cruiseIndex = index;
    } else {
        cruiseIndex = this.cruiseIndex;
    }
    let cruise = this.pathSimplifierIns.createPathNavigator(
        cruiseIndex, //关联第index条轨迹
        {
            loop: false, //循环播放
            speed: this.speedList[this.speedValue].speed, //速度
        }
    );

    if (this.cruise) {
        // 清空走过的路线
        this.cruise.destroy();
        this.cruise = null;
    }

    return cruise;
},
// 开始播放
cruiseStart() {
    this.isPlay = true;

    if (this.cruise && !this.cruise.isCursorAtPathEnd() && !this.cruise.isCursorAtPathStart() && !this.isComplete) {
        // 路段未开始并且没有结束的时候 暂停恢复动画 并且动画没有完成的时候
        this.cruise.resume();
        return;
    }
    this.isComplete = false;
    if (this.cruiseIndex == 0) {
        this.cruiseStop();
        return;
    }

    this.cruise = this.createdCruise();

    // 判断是否传入初始坐标
    if (this.startPoint) {
        this.cruise.start(this.startPoint);
        this.startPoint = 0;
    } else {
        this.cruise.start();
    }
    this.cruise.on('move', e => {
        let idx = this.cruise.cursor.idx;
        let { address, gpsTime, speed } = this.pathList[idx];
        let trackAddress = {
            address,
            gpsTime,
            speed,
        };
        this.$emit('changeData', 'trackAddress', trackAddress);
        let [min, max] = this.marksIndex[this.cruiseIndex];
        this.sliderValue = idx + min;
    });
    // 巡航完成事触发
    this.cruise.on('pause', () => {
        if (this.cruise && this.cruise.isCursorAtPathEnd()) {
            this.cruiseStart();
        }
    });
},

// 暂停播放
cruisePause() {
    this.cruise.pause();
    this.isPlay = false;
},
// 停止播放
cruiseStop() {
    if (this.cruise) {
        // 清空走过的路线
        this.cruise.destroy();
    }
    // 停止播放
    this.isPlay = false;
    this.isComplete = true;
    this.cruiseIndex = -1;
    // 为重新播放准备
    this.cruise = this.createdCruise();
    this.cruiseIndex = -1;
    this.sliderValue = 0;
},
// 速度改变
speedChange() {
    if (this.speedValue == this.speedList.length - 1) {
        this.speedValue = 0;
    } else {
        this.speedValue++;
    }
    this.cruise.setSpeed(this.speedList[this.speedValue].speed);
},

到这里巡航器的基础功能已经实现,还有一部分关于播放器调整对应轨迹改变,这里我们要用的监听器,即vue的watch属性:


五、变量声明以及HTML结构

其中使用到的变量有这些:

data() {
    return {    
        // 地图实例
        map: null,
        cruise: null, //巡航器实例
        cruiseIndex: -1, // 当前播放轨迹下标
        pathSimplifierIns: null, //轨迹实例
        isPlay: false, //是否播放
        isComplete: true, //是否完成
        pointSum: 0, //播放器总数
        sliderValue: 0, //播放器当前数
        startPoint: 0, //下次播放轨迹从当前值开始
        marksIndex: {}, //每段路的起止坐标
        pathList: [],// 轨迹坐标
        speedValue: 3,// 当前播放速度下标
        // 速度列表,可自定义配置
        speedList: [
            { value: 0.5, speed: 100 },
            { value: 1, speed: 200 },
            { value: 2, speed: 400 },
            { value: 4, speed: 1600 },
            { value: 8, speed: 12800 },
            { value: 16, speed: 25600 },
        ],
    };
},

HTML结构:

<template>
    <div class="workTrack">
        <div id="myMap"></div>
        <div class="sliderBar" v-show="pathList.length">
            <span @click="cruiseStart()" v-if="!isPlay">
                <i class="el-icon-video-play"></i>
            </span>
            <span @click="cruisePause" v-else>
                <i class="el-icon-video-pause"></i>
            </span>
            <span @click="cruiseStop">
                <i class="el-icon-error"></i>
            </span>
            <el-slider :disabled="isPlay" v-model="sliderValue" :max="pointSum" :show-tooltip="false"></el-slider>
            <b @click="speedChange">
                <i class="el-icon-d-arrow-right"></i>
                <span>×{{ speedList[speedValue].value }}</span>
            </b>
        </div>
    </div>
</template>

css:

.workTrack {
    width: 100%;
    position: relative;
    height: 100%;
    #myMap {
        width: 100%;
        height: 100%;
    }
    .sliderBar {
        position: absolute;
        bottom: 30px;
        user-select: none;
        width: 100%;
        padding: 10px 2%;
        background-color: #00000064;
        border-radius: 400px;
        backdrop-filter: blur(5px);
        z-index: 99;
        width: 80%;
        right: 0;
        left: 0;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
        .el-slider {
            flex: 1;
            transform: translateY(1px);
            margin: 0 15px;
        }
        ::v-deep .el-slider__runway {
            pointer-events: none;
            background-color: #00000021;
            margin: 0;
            .el-slider__bar {
                background-color: #1682e6;
            }
            .el-slider__stop {
                background-color: #1682e6;
                border-radius: 0;
                width: 2px;
            }
            .el-slider__button-wrapper {
                pointer-events: auto;
            }
            .el-slider__marks-text {
                white-space: nowrap;
                color: #fff;
                font-size: 0;
            }
        }
        > span {
            flex-shrink: 0;
            transform: translateY(1px);
            color: #eee;
            cursor: pointer;
            margin: 0 5px;
            transition: 0.3s;
            font-size: 20px;
            &:hover {
                opacity: 0.5;
            }
        }
        > b {
            flex-shrink: 0;
            color: #eee;
            font-weight: normal;
            margin: 0 5px;
            cursor: pointer;
            border-radius: 3px;
            border: 1px solid #eee;
            padding: 0px 10px;
            transition: 0.3s;
            user-select: none;
            > span {
                vertical-align: middle;
                font-size: 14px;
                display: inline-block;
                transform: translateY(-2px);
            }
            i {
                vertical-align: middle;
                font-size: 16px;
                display: inline-block;
                transform: translateY(-1px);
            }
            &:hover {
                opacity: 0.5;
            }
        }
    }
  
}

六:完整代码

完整代码如下:

<!-- 
 * @description 轨迹回放
 * @fileName: track.vue 
 * @author: tan 
 * @date: 2024-06-17 10:02:28
!-->
<template>
    <div class="workTrack">
        <div id="myMap"></div>
        <div class="sliderBar" v-show="pathList.length">
            <span @click="cruiseStart()" v-if="!isPlay">
                <i class="el-icon-video-play"></i>
            </span>
            <span @click="cruisePause" v-else>
                <i class="el-icon-video-pause"></i>
            </span>
            <span @click="cruiseStop">
                <i class="el-icon-error"></i>
            </span>
            <el-slider :disabled="isPlay" v-model="sliderValue" :max="pointSum" :show-tooltip="false"></el-slider>
            <b @click="speedChange">
                <i class="el-icon-d-arrow-right"></i>
                <span>×{{ speedList[speedValue].value }}</span>
            </b>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            // 地图实例
            map: null,
            cruise: null, //巡航器实例
            cruiseIndex: -1, // 当前播放轨迹下标
            pathSimplifierIns: null, //轨迹实例
            isPlay: false, //是否播放
            isComplete: true, //是否完成
            pointSum: 0, //播放器总数
            sliderValue: 0, //播放器当前数
            startPoint: 0, //下次播放轨迹从当前值开始
            marksIndex: {}, //每段路的起止坐标
            // 轨迹坐标
            pathList: [
                // [经度,纬度] 可再次放置测试数据
                [120.79573938, 30.03576463],
            ],
            speedValue: 3, // 当前播放速度下标
            // 速度列表,可自定义配置
            speedList: [
                { value: 0.5, speed: 100 },
                { value: 1, speed: 200 },
                { value: 2, speed: 400 },
                { value: 4, speed: 1600 },
                { value: 8, speed: 12800 },
                { value: 16, speed: 25600 },
            ],
        };
    },
    mounted() {
        this.map = new AMap.Map('myMap', {
            zoom: 10, //级别
            center: [120.209758, 30.246809], //中心点坐标 默认在杭州
        });
        this.$nextTick(() => {
            this.loadMap();
        });
    },
    methods: {
        // 加载地图
        loadMap() {
            return new Promise((reslove, reject) => {
                //加载PathSimplifier,loadUI的路径参数为模块名中 'ui/' 之后的部分
                new AMapUI.load(['ui/misc/PathSimplifier'], PathSimplifier => {
                    if (!PathSimplifier.supportCanvas) {
                        alert('当前环境不支持 Canvas!');
                        return;
                    }
                    if (this.pathList?.length) {
                        //启动页面
                        this.initPage(PathSimplifier);
                    }
                });

                reslove();
            });
        },
        initPage(PathSimplifier) {
            let content = PathSimplifier.Render.Canvas.getImageContent(
                '/img/car1.png',
                () => {
                    //图片加载成功,重新绘制一次
                    this.pathSimplifierIns.renderLater();
                },
                function onerror(e) {
                    this.$message({ type: 'error', message: '图片加载失败!' });
                }
            );
            this.pathSimplifierIns = new PathSimplifier({
                zIndex: 100,
                map: this.map,
                getPath: function (pathData, pathIndex) {
                    return pathData.path;
                },

                renderOptions: {
                    //轨迹线的样式
                    getPathStyle: (pathItem, zoom) => {
                        return {
                            pathLineStyle: {
                                strokeStyle: 'red',
                                lineWidth: 6,
                                dirArrowStyle: true,
                            },
                        };
                    },
                    pathNavigatorStyle: {
                        initRotateDegree: 180,
                        width: 20,
                        height: 35,
                        autoRotate: true,
                        content,
                    },
                },
            });
            this.cruiseInit();
        },
        // 巡航器初始化
        cruiseInit() {
            let pathSimplifierIns = [{ path: this.pathList, color: '#28F' }];
            this.pathSimplifierIns.setData(pathSimplifierIns);
            this.pointSum = 0;
            let marksIndex = {};
            pathSimplifierIns.forEach((item, index) => {
                this.pointSum += item.path.length;
                marksIndex[index] = [0, this.pointSum];
            });

            this.marksIndex = marksIndex;
            this.cruiseStop();
        },
        // 创建一个巡航器
        createdCruise(index) {
            this.cruiseIndex++;
            // 判断是否传入index
            let cruiseIndex;
            if (index != undefined) {
                cruiseIndex = index;
                this.cruiseIndex = index;
            } else {
                cruiseIndex = this.cruiseIndex;
            }
            let cruise = this.pathSimplifierIns.createPathNavigator(
                cruiseIndex, //关联第index条轨迹
                {
                    loop: false, //循环播放
                    speed: this.speedList[this.speedValue].speed, //速度
                }
            );

            if (this.cruise) {
                // 清空走过的路线
                this.cruise.destroy();
                this.cruise = null;
            }

            return cruise;
        },
        // 开始播放
        cruiseStart() {
            this.isPlay = true;

            if (this.cruise && !this.cruise.isCursorAtPathEnd() && !this.cruise.isCursorAtPathStart() && !this.isComplete) {
                // 路段未开始并且没有结束的时候 暂停恢复动画 并且动画没有完成的时候
                this.cruise.resume();
                return;
            }
            this.isComplete = false;
            if (this.cruiseIndex == 0) {
                this.cruiseStop();
                return;
            }

            this.cruise = this.createdCruise();

            // 判断是否传入初始坐标
            if (this.startPoint) {
                this.cruise.start(this.startPoint);
                this.startPoint = 0;
            } else {
                this.cruise.start();
            }
            this.cruise.on('move', e => {
                let idx = this.cruise.cursor.idx;
                let { address, gpsTime, speed } = this.pathList[idx];
                let trackAddress = {
                    address,
                    gpsTime,
                    speed,
                };
                this.$emit('changeData', 'trackAddress', trackAddress);
                let [min, max] = this.marksIndex[this.cruiseIndex];
                this.sliderValue = idx + min;
            });
            // 巡航完成事触发
            this.cruise.on('pause', () => {
                if (this.cruise && this.cruise.isCursorAtPathEnd()) {
                    this.cruiseStart();
                }
            });
        },

        // 暂停播放
        cruisePause() {
            this.cruise.pause();
            this.isPlay = false;
        },
        // 停止
        cruiseStop() {
            if (this.cruise) {
                // 清空走过的路线
                this.cruise.destroy();
            }
            // 停止播放
            this.isPlay = false;
            this.isComplete = true;
            this.cruiseIndex = -1;
            // 为重新播放准备
            this.cruise = this.createdCruise();
            this.cruiseIndex = -1;
            this.sliderValue = 0;
        },

        speedChange() {
            if (this.speedValue == this.speedList.length - 1) {
                this.speedValue = 0;
            } else {
                this.speedValue++;
            }
            this.cruise.setSpeed(this.speedList[this.speedValue].speed);
        },
    },
    watch: {
        sliderValue(val) {
            // 正在播放禁止拖拽播放器
            if (!this.cruise || this.isPlay) return;
            this.cruise.moveToPoint(val);
            this.startPoint = val;
            this.pathSimplifierIns.render();
        },
    },

    beforeDestroy() {
        if (this.pathSimplifierIns) this.pathSimplifierIns.clearPathNavigators();
        if (this.pathSimplifierIns) this.pathSimplifierIns.setData([]);
        if (this.cruise) this.cruise.destroy();
        if (this.map) this.map.destroy();
    },
};
</script>

<style lang="scss" scoped>
.workTrack {
    width: 100%;
    position: relative;
    height: 100%;
    #myMap {
        width: 100%;
        height: 100%;
    }
    .sliderBar {
        position: absolute;
        bottom: 30px;
        user-select: none;
        width: 100%;
        padding: 10px 2%;
        background-color: #00000064;
        border-radius: 400px;
        backdrop-filter: blur(5px);
        z-index: 99;
        width: 80%;
        right: 0;
        left: 0;
        margin: auto;
        display: flex;
        justify-content: center;
        align-items: center;
        .el-slider {
            flex: 1;
            transform: translateY(1px);
            margin: 0 15px;
        }
        ::v-deep .el-slider__runway {
            pointer-events: none;
            background-color: #00000021;
            margin: 0;
            .el-slider__bar {
                background-color: #1682e6;
            }
            .el-slider__stop {
                background-color: #1682e6;
                border-radius: 0;
                width: 2px;
            }
            .el-slider__button-wrapper {
                pointer-events: auto;
            }
            .el-slider__marks-text {
                white-space: nowrap;
                color: #fff;
                font-size: 0;
            }
        }
        > span {
            flex-shrink: 0;
            transform: translateY(1px);
            color: #eee;
            cursor: pointer;
            margin: 0 5px;
            transition: 0.3s;
            font-size: 20px;
            &:hover {
                opacity: 0.5;
            }
        }
        > b {
            flex-shrink: 0;
            color: #eee;
            font-weight: normal;
            margin: 0 5px;
            cursor: pointer;
            border-radius: 3px;
            border: 1px solid #eee;
            padding: 0px 10px;
            transition: 0.3s;
            user-select: none;
            > span {
                vertical-align: middle;
                font-size: 14px;
                display: inline-block;
                transform: translateY(-2px);
            }
            i {
                vertical-align: middle;
                font-size: 16px;
                display: inline-block;
                transform: translateY(-1px);
            }
            &:hover {
                opacity: 0.5;
            }
        }
    }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1841600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

这三种电容在PCB设计中怎么摆放?

电容在高速 PCB 设计中起着重要的作用&#xff0c;通常也是 PCB 上用得多的器件。在 PCB 中&#xff0c;电容通 常分为滤波电容、去耦电容、储能电容等。 1 电源输出电容&#xff0c;滤波电容 我们通常把电源模块输入、输出回路的电容称为滤波电容。简单理解就是&#xff0c;…

56岁张卫健前任貌突然回春大进化?自曝婚礼前夕流产

现年56岁的江欣燕于1985年以18岁之龄参加第4届新秀歌唱大赛入行&#xff0c;曾拍过多部无线经典电视剧&#xff0c;包括《娱乐插班生》、《同事三分亲》及《女人俱乐部》等。现时甚少作幕前演出的江欣燕日前在社交平台上载分享了新短片&#xff0c;当中更以Deep V上阵&#xff…

Nacos 2.x 系列【14】临时实例、永久实例

文章目录 1. 概述2. 注册实例2.1 SDK2.2 Open API2.3 Spring Cloud 3. 临时实例4. 永久实例 1. 概述 Nacos 提供了两种服务类型供用户注册实例时选择&#xff1a; 临时实例&#xff1a;只是临时存在于注册中心中&#xff0c;会在服务下线或不可用时被注册中心剔除&#xff0c…

HTML基本标签使用【超链接标签、表格标签、表单标签、input标签】

目录 一、基本介绍1.1 概念1.2 HTML的核心特点 二、HTML基本标签三、超链接标签四、表格标签✌<table> 标签属性✍<tr> 标签属性✌ <td> 和 <th> 标签属性演示注意事项 五、表单标签综合应用 最后 一、基本介绍 1.1 概念 HTML&#xff0c;全称为超文…

AutoDL Python实现 自动续签 防止实例过期释放 小脚本 定时任务 apscheduler requests

背景介绍 平常对模型进行训练、微调的时候&#xff0c;我在 AutoDL 有一台主机。 但是有些主机环境我配置好了&#xff0c;又不想让它过期&#xff0c;可能过段时间还会再用。 我一不留神就会超过15天&#xff0c;导致我的机器给释放了很难受。 所以写了一个Python的小脚本&…

玩手游多开还停留在模拟器阶段?不如试试云手机

在手游的世界里&#xff0c;尤其是回合制和资源类游戏&#xff0c;采用多开账号以获取更多游戏资源或者体验不同的游戏策略&#xff0c;是许多玩家的需求。但其实&#xff0c;目前大多数玩家在实现手游多开时&#xff0c;还停留在使用模拟器的阶段。但实际上&#xff0c;有一种…

直播平台美颜技术分析:视频美颜SDK功能实现原理

本篇文章&#xff0c;笔者将深入分析视频美颜SDK的功能实现原理&#xff0c;探讨其在直播平台中的应用。 一、视频美颜技术概述 通过这些功能&#xff0c;用户可以在直播过程中呈现更加理想的自己&#xff0c;从而提高观众的观看体验和互动积极性。 二、视频美颜SDK的功能 1…

Java多线程基础知识-1

什么是程序&#xff1f; 可执行的文件。 什么是进程&#xff1f; 进程是程序一次动态执行的过程&#xff0c;它是资源分配与管理的基本单位。 什么线程&#xff1f; 线程是进程创建的&#xff0c;它是调度和执行的基本单位。线程不拥有系统资源&#xff0c;只拥有一点必不可…

YOLOv10训练自己的数据集(图像目标检测)

目录 1、下载代码 2、环境配置 3、准备数据集 4、yolov10训练 可能会出现报错&#xff1a; 1、下载代码 源码地址&#xff1a;https://github.com/THU-MIG/yolov10 2、环境配置 打开源代码&#xff0c;在Terminal中&#xff0c;使用conda 创建虚拟环境配置 命令如下&a…

Echarts各类图表常用配置项说明,附示例代码

前言&#xff1a; 哈喽&#xff0c;大家好&#xff0c;我是前端菜鸟的自我修养&#xff01;今天给大家分享【 Echarts各类图表常用配置项说明 】&#xff0c;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;原创不易&#xff0c;如果能帮助到带大家&#xff0…

剖析影响大米码垛机性能的关键因素

在现代化粮食加工产业链中&#xff0c;大米码垛机以其高效、精准的自动化操作&#xff0c;成为提升生产效率、降低劳动强度的得力助手。然而&#xff0c;要想充分发挥大米码垛机的性能优势&#xff0c;我们必须深入了解影响其性能的关键因素。星派将深入剖析这些关键因素&#…

Vue的学习(6.20)

一、Vue的特点 1.采用组件化模式&#xff08;xxx.vue包含htmlcssjs&#xff09; 2.声明式编码&#xff0c;编码人员无需直接操作DOM&#xff0c;提高开发效率 3.使用虚拟DOM优秀的DIFF算法&#xff08;DIFF是用于新旧虚拟DOM的比较&#xff09;&#xff0c;尽量复用DOM节点 …

数学建模理论学习:线性规划模型

三要素&#xff1a;目标函数、约束条件&#xff08;s.t.&#xff09;、决策变量&#xff08;x&#xff09; 目标函数&#xff1a;z ax1 bx2 cx3 ... 其中c为一个序列&#xff0c;从左到右依次从x1到xn的系数 解决下面的线性规划问题&#xff1a; % 目标函数系数&#xf…

人工智能指数报告

2024人工智能指数报告&#xff08;一&#xff09;&#xff1a;研发 前言 全面分析人工智能的发展现状。 从2017年开始&#xff0c;斯坦福大学人工智能研究所&#xff08;HAI&#xff09;每年都会发布一份人工智能的研究报告&#xff0c;人工智能指数报告&#xff08;AII&…

java收徒 java辅导 java试用期辅导 java零基础学习

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末报名辅导&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家…

全面升级,票据识别新纪元:合合信息TextIn多票识别2.0

票据识别 - 自动化业务的守门员 发票、票据识别&#xff0c;是OCR技术和RPA、CMS系统结合的一个典型场景&#xff0c;从覆盖率、覆盖面的角度来说&#xff0c;应该也是结合得最成功的场景之一。 产品简介 国内通用票据识别V2.0&#xff08;简称“多票识别2.0”&#xff09;是…

顶级管理者的新视角:管理状态而非时间

在快节奏的商业环境中&#xff0c;时间管理常被看作是提升效率和效果的关键因素。然而&#xff0c;对于顶级管理者来说&#xff0c;仅仅管理时间可能并不足够。一个更深层、更全面的管理方式——管理状态&#xff0c;正在成为新的趋势。在这篇文章中&#xff0c;我们将探讨为什…

Flutter 项目设置 Flutter 版本

即便使用了 fvm 设置了版本&#xff0c;AdroidStudio Setting 中如果不修改路径&#xff0c;Editor 依然会编译错误。目前还没看懂如何通过命令、文件来记录AdroidStudio Setting中的设置。 fvm list 来查看 flutter 路径&#xff1a;

【每天学会一个渗透测试工具】AppScan安装及使用指南

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 https://www.hcl-software.com/appscan AppScan是一种综合型漏洞扫描工具&#xff0c;采用SaaS解决方案&#xff0c;它将所以…

神经网络学习3-卷积层

膨胀卷积&#xff0c;也被称为空洞卷积或扩张卷积&#xff0c;是一种特殊的卷积运算&#xff0c;它在标准卷积的基础上引入了一个额外的超参数&#xff0c;即膨胀率&#xff08;dilation rate&#xff09;。这个超参数决定了在卷积核的元素之间插入多少额外的空间。通过这种方式…