看过的知识不等于学会。唯有用心总结、系统记录,并通过温故知新反复实践,才能真正掌握一二
作为一名摸爬滚打三年的前端开发,开源社区给了我饭碗,我也将所学的知识体系回馈给大家,助你少走弯路!
OpenLayers、Leaflet 快速入门 ,每周保持更新 2 个案例
Cesium 快速入门,每周保持更新 4 个案例

OpenLayers 综合案例-轨迹回放

Vue 3 + OpenLayers 实现的 WebGIS 应用提供了完整的轨迹回放功能

主要功能

  1. 地图上显示一条预设轨迹线。
  2. 小车🚗沿轨迹逐点移动,拐弯时方向自动调整。
  3. 支持“开始”“暂停”“继续”“重置”操作。
  4. 显示当前进度和状态。

在这里插入图片描述

MP4效果动画

<template><div class="car-track-container"><div ref="mapContainer" class="map"></div><div class="map-controls"><h3>小车轨迹回放 🚗</h3><div class="control-group"><button class="control-btn" @click="startTrack" :disabled="playing">开始</button><button class="control-btn" @click="pauseTrack" :disabled="!playing">暂停</button><buttonclass="control-btn"@click="resumeTrack":disabled="playing || finished">继续</button><button class="control-btn" @click="resetTrack">重置</button></div><div class="stats-section"><div>进度:<span class="progress">{{ progress + 1 }} / {{ trackPoints.length }}</span></div><div>状态: <span class="status">{{ statusText }}</span></div></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted, computed } from "vue";
import Map from "ol/Map";
import View from "ol/View";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { XYZ, Vector as VectorSource } from "ol/source";
import { LineString, Point } from "ol/geom";
import Feature from "ol/Feature";
import { Style, Stroke, Icon } from "ol/style";
import { defaults as defaultControls, FullScreen, ScaleLine } from "ol/control";
import { fromLonLat } from "ol/proj";
import "ol/ol.css";const map = ref(null);
const mapContainer = ref(null);
const vectorSource = ref(null);
const carFeature = ref(null);
const trackFeature = ref(null);
const playing = ref(false);
const finished = ref(false);
const progress = ref(0);
const timer = ref(null);// 预设轨迹点(经纬度)
const trackPoints = ref([[116.39, 39.9],[116.392, 39.901],[116.395, 39.902],[116.398, 39.903],[116.4, 39.905],[116.402, 39.908],[116.404, 39.91],[116.406, 39.912],[116.408, 39.914],[116.41, 39.916],
]);const statusText = computed(() => {if (finished.value) return "已完成";if (playing.value) return "播放中";if (progress.value > 0) return "已暂停";return "未开始";
});// 计算两点间的角度(弧度,正北为0,顺时针)
function getAngle(p1, p2) {const [x1, y1] = p1;const [x2, y2] = p2;const dx = x2 - x1;const dy = y2 - y1;return Math.atan2(dy, dx);
}function carStyle(angle = 0) {return new Style({image: new Icon({src: "/src/assets/car.png",anchor: [0.5, 0.5],rotateWithView: true,rotation: -angle, // 加上这一行实现方向旋转}),});
}function trackLineStyle() {return new Style({stroke: new Stroke({ color: "#1976d2", width: 4, lineDash: [8, 8] }),});
}// 绘制轨迹线
function drawTrack() {if (trackFeature.value) vectorSource.value.removeFeature(trackFeature.value);const coords = trackPoints.value.map((pt) => fromLonLat(pt));trackFeature.value = new Feature({ geometry: new LineString(coords) });trackFeature.value.setStyle(trackLineStyle());vectorSource.value.addFeature(trackFeature.value);
}// 绘制小车
function drawCar(idx = 0, angle = 0) {if (carFeature.value) vectorSource.value.removeFeature(carFeature.value);const coord = fromLonLat(trackPoints.value[idx]);carFeature.value = new Feature({ geometry: new Point(coord) });carFeature.value.setStyle(carStyle(angle));vectorSource.value.addFeature(carFeature.value);
}// 开始
function startTrack() {if (playing.value || finished.value) return;playing.value = true;finished.value = false;if (progress.value === 0) {drawCar(0, getAngle(trackPoints.value[0], trackPoints.value[1]));}runTrack();
}// 开始
function runTrack() {if (timer.value) clearInterval(timer.value);timer.value = setInterval(() => {if (!playing.value) return;if (progress.value >= trackPoints.value.length - 1) {playing.value = false;finished.value = true;clearInterval(timer.value);return;}const idx = progress.value;const nextIdx = idx + 1;const angle = getAngle(trackPoints.value[idx], trackPoints.value[nextIdx]);drawCar(nextIdx, angle);progress.value = nextIdx;}, 600);
}// 暂停
function pauseTrack() {playing.value = false;if (timer.value) clearInterval(timer.value);
}// 继续
function resumeTrack() {if (playing.value || finished.value) return;playing.value = true;runTrack();
}// 重置
function resetTrack() {playing.value = false;finished.value = false;progress.value = 0;if (timer.value) clearInterval(timer.value);drawCar(0, getAngle(trackPoints.value[0], trackPoints.value[1]));
}onMounted(() => {vectorSource.value = new VectorSource();const vectorLayer = new VectorLayer({source: vectorSource.value,zIndex: 10,});const baseLayer = new TileLayer({source: new XYZ({url: "https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",}),});map.value = new Map({target: mapContainer.value,layers: [baseLayer, vectorLayer],view: new View({center: fromLonLat(trackPoints.value[0]),zoom: 14,}),controls: defaultControls().extend([new FullScreen(), new ScaleLine()]),});drawTrack();drawCar(0, getAngle(trackPoints.value[0], trackPoints.value[1]));
});onUnmounted(() => {if (map.value) map.value.dispose();if (timer.value) clearInterval(timer.value);
});
</script><style scoped>
.car-track-container {position: relative;width: 100vw;height: 100vh;overflow: hidden;background: linear-gradient(135deg, #1a237e, #4a148c);font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.map {width: 100%;height: 100%;background: #0d47a1;
}
.map-controls {position: absolute;top: 20px;right: 20px;background: rgba(255, 255, 255, 0.95);border-radius: 12px;padding: 20px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);z-index: 2;width: 320px;backdrop-filter: blur(5px);border: 1px solid rgba(255, 255, 255, 0.3);
}
.map-controls h3 {margin-top: 0;margin-bottom: 15px;color: #1a237e;font-size: 1.4rem;
}
.control-group {display: flex;flex-wrap: wrap;gap: 10px;margin-bottom: 15px;
}
.control-btn {flex: 1 1 45%;padding: 12px 15px;border: none;border-radius: 8px;background: #3f51b5;color: white;font-weight: 600;cursor: pointer;transition: all 0.3s ease;display: flex;align-items: center;justify-content: center;gap: 8px;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.control-btn:disabled {background: #b0bec5;cursor: not-allowed;
}
.control-btn:hover:not(:disabled) {background: #303f9f;transform: translateY(-2px);box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
.stats-section {margin-top: 10px;font-size: 1.1rem;color: #1976d2;
}
.progress {font-weight: bold;color: #ffc107;
}
.status {font-weight: bold;color: #388e3c;
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语音自动生成PPT、思维导图、会议纪要、笔记、大纲、导读等

一、需要用到录音工具&#xff0c;手机端工具&#xff1a;讯飞听见二、需要用到的工具通义&#xff1a;https://www.tongyi.com/discover上传录音&#xff0c;描述一下&#xff0c;让直接给生成PPT就行&#xff0c;点生成就可以生成ppt&#xff0c;对PPT进行导出就行 三、除了生…

【MySQL】脚本化快速搭建跨平台、可定制的MySQL数据库

冗长的废话就省略了&#xff0c;大家看到这篇博客&#xff0c;效果如标题所示&#xff0c;我将提供完整的脚本&#xff0c;并用 「保姆级」的详细步骤&#xff0c;给你提供一个快速搭建跨平台、可定制的 MySQL环境的解决方案。保证无论你是 Linux 服务器管理员、macOS 开发者&a…

MAC包头、IP包头 、UDP包头中的长度含义是啥?三者之间有啥区别?

以太网帧、IP包及TCP与UDP的报文格式 下面用通俗技术的方式详细解释&#xff1a; 1. MAC包头&#xff08;以太网帧头&#xff09;中的长度 字段名称&#xff1a;EtherType/Length位置&#xff1a;以太网帧头的第13、14字节含义&#xff1a; 如果值小于等于1500&#xff08;0x0…

Multiscale Structure Guided Diffusion for Image Deblurring 论文阅读

基于多尺度结构引导扩散模型的图像去模糊 摘要 扩散概率模型&#xff08;Diffusion Probabilistic Models, DPMs&#xff09;最近被用于图像去模糊&#xff0c;其被表述为一个以模糊输入为条件的图像条件生成过程&#xff0c;将高斯噪声映射到高质量图像。当在成对的域内数据上…

git 提交时排除一个或多个文件

前言 在提交文件时&#xff0c;总是有一些文件是不需要提交的&#xff0c;比如机器上的配置文件&#xff0c;日志文件等等&#xff0c;所以在提交时就需要排除这些文件&#xff1b; 第一种方案 git add file1 file2 比如我新添加了3个文件&#xff1a; file1.txt file2.txt fil…

OpenCV 入门:基础图像操作

在计算机视觉领域&#xff0c;OpenCV 无疑是最受欢迎的开源库之一。它由 Intel 公司俄罗斯团队发起&#xff0c;如今已成为处理图像和视频的强大工具。本文我会介绍OpenCV 的基础知识&#xff0c;从图像的读写显示到实时视频流处理&#xff0c;迈出计算机视觉的第一步。 目录 …

大语言模型 LLM 通过 Excel 知识库 增强日志分析,根因分析能力的技术方案(3):使用云平台最小外部依赖方案

文章大纲 1 方案总览(与官方文档映射) 2 环境准备(一步完成) 3 数据层(零代码迁移 Excel → BigQuery 或 SQLite) 4 函数声明(JSON Schema 与官方示例一致) 5 Cloud Function(**最小外部依赖**) 6 客户端调用(对齐官方 Python 示例) 7 Token 与性能对比(官方计费口…

C++高效实现轨迹规划、自动泊车、RTS游戏、战术迂回包抄、空中轨迹、手术机器人、KD树

C++ 算法汇总 基于C++的城市道路场景 以下是基于C++的城市道路场景中车辆紧急变道轨迹生成的实现方法和示例代码。内容涵盖轨迹规划算法、数学建模及代码实现,适用于自动驾驶或驾驶辅助系统开发。 基于多项式曲线的轨迹生成 采用五次多项式(Quintic Polynomial)生成平滑…

电动汽车转向系统及其工作原理

电动汽车的转向系统作为电动汽车的一个关键系统&#xff0c;与燃油车的转向系统有着较大差异。电动汽车的转向系统主要分为 电动助力转向&#xff08;EPS, Electric Power Steering&#xff09; 、电动液压助力转向系统&#xff08;EHPS, Electro-Hydraulic Power Steering&…

TCP/IP 体系结构网络接口层的原理

TCP/IP 网络接口层详解 网络接口层&#xff08;Network Interface Layer&#xff09;是 TCP/IP 模型的最底层&#xff08;对应 OSI 模型的物理层 数据链路层&#xff09;&#xff0c;负责在物理网络中传输原始比特流&#xff0c;实现相邻设备之间的可靠数据传输。核心功能物理…

笔记本键盘的启用和禁用

管理员 打开 CMD&#xff1a;这一步要求以管理员权限打开命令提示符&#xff08;Command Prompt&#xff09;。在Windows系统中&#xff0c;可以通过搜索“cmd”&#xff0c;然后右键选择“以管理员身份运行”来实现。sc config i8042prt start disabled (关闭笔记本键盘)&…

vue3的一些浅显用法

1/ 父页面调用子页面相关需要在父页面引用 <FieldUserForm ref"userFormRef" success"handleUserFormSuccess" />其中 FieldUserForm 是子页面 success"handleUserFormSuccess" 是子页面成功后回调方法 父页面 实现 handleUserFormSucces…

C语言习题讲解-第五讲-循环编程练习等

C语言习题讲解-第五讲-循环编程练习等1. 关于一维数组描述不正确的是&#xff1a;( )2. 关于一维数组初始化&#xff0c;下面哪个定义是错误的&#xff1f;&#xff08; &#xff09;3. 定义了一维 int 型数组 a[10] 后&#xff0c;下面错误的引用是&#xff1a;&#xff08; &…

MongoDB索引及其原理

目录 索引原理 索引类型 单键索引 组合索引 特性索引 唯一索引 稀疏索引 部分索引 TTL索引 多键索引 文本索引 地理空间索引 哈希索引 总结 MongoDB 索引执行计划 索引原理 MongoDB索引的背后的原理和MySQL中的索引原理是差不多的,都是使用B数来对数据进行管理…

学习嵌入式的第三十三天-数据结构-(2025.7.25)服务器/多客户端模型

服务器/多客户端模型循环服务器 while(1){ accept(); recv(); } 适用于简单任务&#xff0c;如基础Web服务器&#xff0c;但无法处理并发请求。并发服务器 通过thread或fork实现多任务处理。需注意子进程/线程的资源回收&#xff0c;避免内存泄漏。多路IO模型服务器 使用select…

【Canvas与标牌】优质资产六角星标牌

【成图】【代码】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>优质资产六角星标记 Draft1</title><style type"text/cs…

扫雷游戏开发教程:从零打造精美像素扫雷

完整源码在本文结尾处一、游戏概述 扫雷是一款经典的益智游戏&#xff0c;玩家需要在不触发地雷的情况下揭开所有安全格子。本教程将带你从零开始开发一个具有精美界面和动画效果的扫雷游戏&#xff0c;包含难度选择、棋盘大小调整等高级功能。 二、游戏核心功能 三种难度级别&…

Linux驱动开发笔记(五)——设备树(上)

内容详见《【正点原子】I.MX6U嵌入式Linux驱动开发指南》四十三章 开发板&#xff1a;imx6ull mini 虚拟机&#xff1a;VMware17 ubuntu&#xff1a;ubuntu20.04 一、什么是设备树 视频&#xff1a;第6.1讲 Linux设备树详解-什么是设备树&#xff1f;_哔哩哔哩_bilibili 对…

【QT入门到晋级】window opencv安装及引入qtcreator(包含两种qt编译器:MSVC和MinGW)

前言 本文主要分享QT的两种编译器环境&#xff08;MSVC和MinGW&#xff09;下&#xff0c;安装及引入opencv的方法。 编译器区别 特性​​​​MSVC​​​​MinGW​​​​编译器类型​​微软专有编译器&#xff08;cl.exe&#xff09;基于GCC的开源工具链​​平台支持​​仅Wi…

字节跳动Coze Studio开源了!架构解析

Coze Studio 是字节跳动推出的一款 AI 应用开发平台&#xff0c;专注于帮助开发者快速构建、测试和部署基于大语言模型的智能应用。其整体架构围绕“低代码开发 AI 应用”的核心目标设计&#xff0c;融合了模型能力、工具集成、流程编排和多端部署等功能。以下是其整体架构的详…