基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图

实现基于北斗卫星的车辆定位和轨迹图的Maven工程(使用模拟数据),我们将使用以下技术:

  • Spring Boot:作为后端框架,用来提供数据接口。
  • Thymeleaf:作为前端模板引擎,呈现网页。
  • Leaflet.js:一个开源的JavaScript库,用于显示交互式地图。
  • Simulated Data:使用随机生成的模拟GPS数据来模拟北斗卫星车辆位置。
  • WebSocket:用于实现实时数据推送,确保地图位置每秒更新。

目录

1. 项目结构

2. Maven依赖配置 (pom.xml)

3. 实现后端服务

3.1 BeidouApplication.java

4. 配置文件 (application.properties)

5. 启动项目

6. 访问页面


1. 项目结构

创建一个Maven项目,基本结构如下:

项目结构图: 

2. Maven依赖配置 (pom.xml)

首先在pom.xml中添加必要的依赖,确保使用Spring Boot、WebSocket和Thymeleaf:

<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Thymeleaf for rendering HTML --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- WebSocket for real-time communication --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- Lombok (Optional, for cleaner code) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency>
</dependencies>

3. 实现后端服务

3.1 BeidouApplication.java

这是Spring Boot的启动类:

package com.example.beidou;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class BeidouApplication {public static void main(String[] args) {SpringApplication.run(BeidouApplication.class, args);}
}

4. 配置文件 (application.properties)

server.port=8080

5. 启动项目

确保你有Java和Maven环境,在项目根目录执行以下命令启动应用:

mvn spring-boot:run

6. 访问页面

在浏览器中访问 http://localhost:8080,你应该可以看到一个地图,显示车辆的实时位置和轨迹更新。

效果图:

 Controller:

package com.example.beidou.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;@RestController
public class VehicleController {private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);@Autowiredprivate SimpMessagingTemplate messagingTemplate;private Map<String, Map<String, Double>> vehiclePositions = new HashMap<String, Map<String, Double>>() {{put("Vehicle 1", new HashMap<String, Double>() {{put("latitude", 39.9042);//北京put("longitude", 116.4074);}});put("Vehicle 2", new HashMap<String, Double>() {{put("latitude", 31.2304);//上海put("longitude", 121.4737);}});put("Vehicle 3", new HashMap<String, Double>() {{put("latitude", 22.3964);// 香港put("longitude", 114.1095);}});put("Vehicle 4", new HashMap<String, Double>() {{put("latitude", 30.5728);//成都put("longitude", 104.0668);}});put("Vehicle 5", new HashMap<String, Double>() {{put("latitude", 34.3416);// 西安put("longitude", 108.9398);}});}};private Map<String, Map<String, Double>> vehicleTargets = new HashMap<String, Map<String, Double>>() {{put("Vehicle 1", new HashMap<String, Double>() {{put("latitude", 31.2304);//上海put("longitude", 121.4737);}});put("Vehicle 2", new HashMap<String, Double>() {{put("latitude", 39.9042);//北京put("longitude", 116.4074);}});put("Vehicle 3", new HashMap<String, Double>() {{put("latitude", 34.3416);// 西安put("longitude", 108.9398);}});put("Vehicle 4", new HashMap<String, Double>() {{put("latitude", 22.3964);// 香港put("longitude", 114.1095);}});put("Vehicle 5", new HashMap<String, Double>() {{put("latitude", 30.5728);//成都put("longitude", 104.0668);}});}};@GetMapping("/startSimulation")public String startSimulation() {executorService.scheduleAtFixedRate(this::sendVehicleUpdates, 0, 500, TimeUnit.MILLISECONDS);return "Simulation started!";}@GetMapping("/stopSimulation")public String stopSimulation() {executorService.shutdownNow();return "Simulation stopped!";}private void sendVehicleUpdates() {Map<String, Map<String, Double>> updatedPositions = new HashMap<>();for (Map.Entry<String, Map<String, Double>> entry : vehiclePositions.entrySet()) {String vehicleId = entry.getKey();Map<String, Double> position = entry.getValue();Map<String, Double> target = vehicleTargets.get(vehicleId);// 按一定速度向目标移动double latDiff = target.get("latitude") - position.get("latitude");double lonDiff = target.get("longitude") - position.get("longitude");// 每次移动经纬度的 1/100double newLatitude = position.get("latitude") + latDiff * 0.02;double newLongitude = position.get("longitude") + lonDiff * 0.02;position.put("latitude", newLatitude);position.put("longitude", newLongitude);updatedPositions.put(vehicleId, new HashMap<>(position));}messagingTemplate.convertAndSend("/topic/vehicleLocation", updatedPositions);}
}

WebSocketConfig:
package com.example.beidou.config;import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic");config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/vehicle-location").setAllowedOriginPatterns("*").withSockJS();}
}

前端页面代码有需要的,请私信我,有偿提供代码,白嫖党勿扰! 

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

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

相关文章

图书馆座位预约系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;图书馆管理&#xff0c;座位信息管理&#xff0c;预约选座管理&#xff0c;签到信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;论坛&#xf…

力扣最热一百题——缺失的第一个正数

目录 题目链接&#xff1a;41. 缺失的第一个正数 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 解法一&#xff1a;标记数组法 1. 将非正数和超出范围的数替换 2. 使用数组下标标记存在的数字 3. 找到第一个未标记的位置 4. 为什么时间复杂…

【Vue】- 路由及传参

文章目录 知识回顾前言源码分析1. 声明式导航2. 路由传参3. 可选符4. 重定向5. 4046. 跳转及传参7. 路由懒加载拓展知识总结router-link静态传参和动态路由的对比知识回顾 前言 什么是单页面应用程序? ● 所有功能在一个html页面上实现 单页面应用优缺点? ● 优点:按需更新…

Python | Leetcode Python题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; class Solution:def addStrings(self, num1: str, num2: str) -> str:res ""i, j, carry len(num1) - 1, len(num2) - 1, 0while i > 0 or j > 0:n1 int(num1[i]) if i > 0 else 0n2 int(num2[j]) if j > 0 e…

openssl 生成多域名 多IP 的数字证书

openssl.cnf 文件内容&#xff1a; [req] default_bits 2048 distinguished_name req_distinguished_name copy_extensions copy req_extensions req_ext x509_extensions v3_req prompt no [req_distinguished_name] countryName CN stateOrProvinceName GuangDong l…

[Linux]从零开始的泰山派系统安装与远程教程

一、前言 泰山派买回来也有一阵子了&#xff0c;最近慢慢开始研究。当然&#xff0c;学习这种Linux的开发板的第一步就是安装系统&#xff0c;对于RK系列的芯片系统安装有专门的软件&#xff0c;所有在系统安装方面比较简单。更多的还是我们应该怎么去编译系统&#xff0c;这一…

电脑端视频剪辑软件哪个好用,十多款剪辑软件分享

随着自媒体时代的蓬勃发展&#xff0c;视频创作已成为营销战略与社交媒体互动中不可或缺的一环&#xff0c;这极大地推动了视频编辑技术的普及与兴盛。今天&#xff0c;我将为大家精选并介绍15款当前市场上广受欢迎的视频剪辑工具及配套软件&#xff0c;旨在帮助大家更高效地进…

YOLO混凝土缺陷检测数据集

YOLO混凝土缺陷检测 数据集 模型 ui界面 ✓图片数量7353&#xff0c;模型已训练200轮&#xff1b; ✓类别&#xff1a;exposed reinforcement&#xff0c;rust stain&#xff0c;Crack&#xff0c;Spalling&#xff0c;Efflorescence&#xff0c;delamination&#xff08;外露…

基于单片机的楼宇门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计程序具体实现截图参考文献设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设…

华为OD机试 - 报数问题 - 约瑟夫环(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

Apache ZooKeeper 及 Curator 使用总结

1. 下载 官网地址&#xff1a;Apache ZooKeeper 点击下载按钮 选择对应的版本进行下载 2. 使用 1、解压 tar -zxf apache-zookeeper-3.9.2-bin.tar.gz2、复制配置文件&#xff0c;有一个示例配置文件 conf/zoo_sample.cfg&#xff0c;此文件不能生效&#xff0c;需要名称为…

【非常实用—Navicat重置 MySQL 的密码】

Navicat重置 MySQL 的密码 连接本地数据库&#xff0c;忘记原始密码停止 MySQL 服务以安全模式启动 MySQL打开新的命令行窗口重置密码停止 MySQL 并重启 连接本地数据库&#xff0c;忘记原始密码 停止 MySQL 服务 在命令行中使用以下命令停止服务&#xff08;Windows 下&#…

C语言6大常用标准库 -- 4.<math.h>

目录 引言 4. C标准库--math.h 4.1 简介 4.2 库变量 4.3 库宏 4.4 库函数 4.5 常用的数学常量 &#x1f308;你好呀&#xff01;我是 程序猿 &#x1f30c; 2024感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&#xff0c;共同成长&…

医学数据分析实训 项目五 分类分析--乳腺癌数据分析与诊断

文章目录 项目六&#xff1a;分类分析实践目的实践平台实践内容&#xff08;一&#xff09;数据理解及准备&#xff08;二&#xff09;模型建立、预测及优化任务一&#xff1a;使用 KNN算法进行分类预测任务二&#xff1a;使用贝叶斯分类算法进行分类预测任务三&#xff1a;使用…

星云股份战略运营副总裁袁智勇︱如何培养“能打胜仗”的项目经理

全国项目经理专业人士年度盛会 福建星云电子股份有限公司总裁办战略运营副总裁袁智勇先生受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾&#xff0c;演讲议题为“如何培养“能打胜仗”的项目经理”。大会将于10月26-27日在北京举办&…

56.【C语言】字符函数和字符串函数(strtok函数)(未完)

目录 12.strtok函数(较复杂) *简单使用 总结: *优化 12.strtok函数(较复杂) *简单使用 strtok:string into tokens cplusplus的介绍 点我跳转 翻译: 函数 strtok char * strtok ( char * str, const char * delimiters ); 总结: delimiters参数指向一个字符串&#xff0…

波士顿机器人滑环的技术特点与应用前景

机器人滑环在现代自动化和机器人技术中扮演着至关重要的角色。作为一种关键的机械组件&#xff0c;滑环允许机器人在旋转和移动的过程中保持稳定的电信号和数据传输。波士顿机器人滑环作为行业中的领先产品&#xff0c;具有多项独特的技术特点和优势&#xff0c;为各种机器人系…

Packet Tracer - 配置编号的标准 IPv4 ACL(两篇)

Packet Tracer - 配置编号的标准 IPv4 ACL(第一篇) 目标 第 1 部分&#xff1a;计划 ACL 实施 第 2 部分&#xff1a;配置、应用和验证标准 ACL 背景/场景 标准访问控制列表 (ACL) 为路由器 配置脚本&#xff0c;基于源地址控制路由器 是允许还是拒绝数据包。本练习的主要内…

如何学习React?一些学习React的网站

React相关网站集锦 React入门 React 官网&#xff1a;https://react.zcopy.site/docs/getting-started.html 深入React原理 1. 图解React&#xff1a;https://7kms.github.io/react-illustration-series/main/bootstrap 帮助我们快速学习React Fiber架构相关知识&#xff0c;主…

STM32—MPU6050

1.MPU6050简介 MPU6050是一个6轴姿态传感器可以测量芯片自身X、Y、Z轴的加速度、角速度参数&#xff0c;通过数据融合&#xff0c;可进一步得到姿态角&#xff0c;常应用于平衡车、飞行器等需要检测自身姿态的场景3轴加速度计(Accelerometer&#xff1a;测量X、Y、Z轴的加速度3…