基于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.rhkb.cn/news/429664.html

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

相关文章

算法之逻辑斯蒂回归(Logistic regression)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 逻辑斯蒂回归&#xff08;Logistic Regression&#xff09;是统计学中一种广泛应用于二分类问题的算法。它的主要目标是预测二分类问题中的事件发生的概率。尽管名字里有“回归”&#xff0c;但逻…

高级I/O知识分享【epoll || Reactor ET,LT模式】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;接口 epo…

【kaggle竞赛】毒蘑菇的二元预测题目相关信息和思路求解代码

毒蘑菇的二元预测 您提供了很多关于不同二元分类任务的资源和链接&#xff0c;看起来这些都是Kaggle竞赛中的参考资料和高分解决方案。为了帮助您更好地利用这些资源&#xff0c;这里是一些关键点的总结&#xff1a; Playground Season 4 Episode 8 主要关注的竞赛: 使用银行…

如何将很多个pdf拼接在一起?很多种PDF拼接的方法

如何将很多个pdf拼接在一起&#xff1f;将多个PDF文件合并不仅能够提升信息的整合性&#xff0c;还能使文件管理更加高效。想象一下&#xff0c;你需要向同事或老师提交一份综合报告&#xff0c;其中包含了多份相关资料。如果每个文件单独存在&#xff0c;查找和传输都会变得繁…

Java 入门指南:JVM(Java虚拟机)—— Java 类加载器详解

类加载器 类加载器&#xff08;Class Loader&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#xff0c;它的作用是将类的字节码文件&#xff08;.class 文件&#xff09;从磁盘或其他来源加载到 JVM 中。类加载器负责查找和加载类的字节码文件&#xff0c;并…

Python|OpenCV-实现识别目标图像中的圆圈(20)

前言 本文是该专栏的第22篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在处理图像检测项目的时候,可能会遇到需要检测目标图像中的“圆圈”需求。笔者在这里举个例子,如下图所示: 在图中有一个篮球,但是我们要找的目标对象并不是篮球,而是篮球它本身的这个…

MySQL安装教程

MySQL安装教程 如果需要删除原有mysql&#xff0c;然后安装过新的&#xff0c;可以参照如何彻底卸载旧mysql重装测试 1. 准备资源 mysql官网直达&#xff1a;https://dev.mysql.com/downloads/mysql/ CADN&#xff1a;https://download.csdn.net/download/luocong321/89592962 …

《深度学习》PyTorch框架 优化器、激活函数讲解

目录 一、深度学习核心框架的选择 1、TensorFlow 1&#xff09;概念 2&#xff09;优缺点 2、PyTorch 1&#xff09;概念 2&#xff09;优缺点 3、Keras 1&#xff09;概念 2&#xff09;优缺点 4、Caffe 1&#xff09;概念 2&#xff09;优缺点 二、pytorch安装 1、安装 2、…

【人工智能】在大型活动中的应用案例

人工智能在娱乐大型活动中的应用 ## 作者主页: 知孤云出岫 目录 **人工智能在娱乐大型活动中的应用****1. 引言****2. 智能票务与入场管理****2.1 动态定价与票务预测****2.2 生物识别技术快速入场****2.3 区块链技术防伪票务管理** **3. 智能观众互动与个性化体验****3.1 个性…

CCF csp认证 小白必看

c支持到C17(还是更高?)&#xff1b;所以学一些封装好的函数功能是必要的---比如STL里的函数&#xff1b; 因为可携带纸质资料&#xff0c;建议打印带入&#xff0c;需要时可翻阅。 【题目概述:】 0-devc环境配置 配置好你常用的编译版本&#xff1a; 想要调试记得开启下选…

Python练习宝典:Day 1 - 选择题 - 基础知识

目录 一、踏上Python之旅二、Python语言基础三、流程控制语句四、序列的应用 一、踏上Python之旅 1.想要输出 I Love Python,应该使用()函数。 A.printf() B.print() C.println() D.Print()2.Python安装成功的标志是在控制台(终端)输入python/python3后,命令提示符变为: A.&…

Linux自主学习篇

用户及权限管理 sudo 是 "superuser do" 的缩写&#xff0c;是一个在类 Unix 操作系统&#xff08;如 Linux 和 macOS&#xff09;中使用的命令。它允许普通用户以超级用户&#xff08;root 用户&#xff09;的身份执行命令&#xff0c;从而获得更高的权限。 useradd…

数据飞轮:打造业务增长的持续循环

在当今数据驱动的世界中&#xff0c;企业必须利用数据的力量才能保持竞争力。然而&#xff0c;仅仅收集和分析数据是不够的&#xff1b;企业必须能够从他们的数据中创造一个持续增长的循环&#xff0c;才能保持成功。其中一种方法就是创建数据飞轮。接下来让我们来探讨一下什么…

网络高级day03(Http)

目录 【1】HTTP简介 【2】 HTTP特点 【3】 HTTP协议格式 1》客户端请求消息格式 1> 请求行 2> 请求头 3> 空行 4> 请求数据 2》服务器响应消息格式 【1】HTTP简介 HTTP协议是Hyper Text Transfer Protocol &#xff08;超文本传输协议&#xff09;的缩写&a…

Python_控制循环语句

if语句单分支结构的语法形式如下&#xff1a; 【操作】输入一个数字&#xff0c;小于10&#xff0c;则打印这个数字(if_test01.py)&#xff1a; num input("输入一个数字&#xff1a;") if int(num)<10: print("小于10的数&#xff1a;"num)条件表达式…

Shader 中的光源

1、Shader 开发中常用的光源属性 Unity当中一共支持四种光源类型&#xff1a; 平行光&#xff08;Directional&#xff09;点光源&#xff08;Point&#xff09;聚光灯&#xff08;Spot&#xff09;面光源&#xff08;Area&#xff09;— 面光源仅在烘焙时有用 不管光源类型到…

[网络层]-IP协议相关特性

IP协议 基本概念 主机 : 配有IP地址,但是不进行路由控制的设备路由器 : 既配有IP地址,又能进行路由控制节点: 主机和路由器的统称 协议头格式 4位版本(version):占四位,用于指定IP协议的版本,例如,使用IPv4,该字段就为44位首部长度: 表示IP协议首部的长度,以32位bit (4字节)…

Linux:终端(terminal)与终端管理器(agetty)

终端的设备文件 打开/dev目录可以发现其中有许多字符设备文件&#xff0c;例如对于我的RedHat操作系统&#xff0c;拥有tty0到tty59&#xff0c;它们是操作系统提供的终端设备。对于tty1-tty12使用ctrlaltF*可以进行快捷切换&#xff0c;下面的命令可以进行通用切换。 sudo ch…

【小bug】使用 RestTemplate 工具从 JSON 数据反序列化为 Java 对象时报类型转换异常

起因&#xff1a;今天编写一个请求时需要通过RestTemplate调用外部接口&#xff0c;获取一些信息&#xff0c;但是在获取了外部接口响应内容后&#xff0c;使用强制转换发现报了类型转换异常。之前也遇到过&#xff0c;但是没记录下来&#xff0c;今天又查了一遍……干脆记录一…

Springboot使用ThreadPoolTaskScheduler轻量级多线程定时任务框架

简介&#xff1a; Spring注解定时任务使用不是很灵活&#xff0c;如果想要灵活的配置定时任务&#xff0c;可以使用xxl-job 或者 quartz等定时任务框架&#xff0c;但是过于繁琐&#xff0c;可能成本较大。所以可以使用ThreadPoolTaskScheduler来灵活处理定时任务 ThreadPoolT…