OpenLayers 綜合案例-軌跡回放

看過的知識不等于學會。唯有用心總結、系統記錄,并通過溫故知新反復實踐,才能真正掌握一二
作為一名摸爬滾打三年的前端開發,開源社區給了我飯碗,我也將所學的知識體系回饋給大家,助你少走彎路!
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;融合了模型能力、工具集成、流程編排和多端部署等功能。以下是其整體架構的詳…