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

news2024/11/13 9:13:47

目录

1. 项目结构

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

3. 实现后端服务

 4. 配置文件 (application.properties) 

5. 启动项目

6. 访问页面


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

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

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. 实现后端服务

package com.example.beidou;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling  // 启用定时任务
public class BeidouApplication {
    public static void main(String[] args) {
        SpringApplication.run(BeidouApplication.class, args);
    }
}
效果图:
Controller:
package com.example.beidou.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;

@RestController
public class VehicleController {

    @Autowired
    private 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);
        }});

    }};

    // 服务器启动时自动启动模拟
    @PostConstruct
    public void startSimulation() {
        System.out.println("Starting vehicle simulation...");
    }


    // 模拟车辆移动轨迹
    @Scheduled(fixedRate = 1000)
    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/100
            double 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 {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");  // 使用 "/topic" 作为消息前缀
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/vehicle-location").setAllowedOriginPatterns("*").withSockJS();
    }
}

 4. 配置文件 (application.properties) 

server.port=8080

5. 启动项目

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

mvn spring-boot:run

6. 访问页面

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

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

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

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

相关文章

企业导师面对面,产教融合实训基地搭建人才成长快车道

产教融合实训基地是指以特定专业群为服务对象&#xff0c;由高职院校和企业双方共同投入、共同利用&#xff0c;并由若干实验实训室和模块产线组成的综合性实训基地。这一基地不仅具备工学结合的功能&#xff0c;还融合了教育、产业和科技创新的要素&#xff0c;形成了一种特殊…

食品检测与分类系统源码分享

食品检测与分类检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

Galileo与GLONASS信号类型

GLONASS的G1信号与G2信号是频分多址&#xff0c;用于标记卫星。

面向切面:单元测试、事务、资源操作

目录 一、单元测试二、事务2.1、概述2.1.1、编程式事务2.1.2、声明式事务 2.2、JdbcTemplate2.3、基于注解的声明式事务2.3.1、基本用例-实现注解式的声明事务2.3.2、事务属性&#xff1a;只读2.3.3、事务属性&#xff1a;超时2.3.4、事务属性&#xff1a;回滚策略2.3.5、事务属…

柯桥生活英语培训之“老顾客”在英语中通常有几种表达方式?

“老顾客”用英语怎么说&#xff1f;千万不要直接翻译成“old customer”&#xff0c;因为这会让人误以为是指年龄大的顾客。 “老顾客”在英语中通常有以下几种表达方式&#xff1a; regular customer 这是最常见的表达&#xff0c;强调顾客经常光顾。这里的“regular”强调的…

RTR——Chapter5 下

锯齿和抗锯齿 想象现在有一个巨大的黑色三角形&#xff0c;正在白色的背景上缓缓移动。由于屏幕上的网格单元被三角形所覆盖&#xff0c;因此其像素值的强度应该会平滑的下降。但是通常在各种基础渲染器中发生的情况是&#xff0c;一旦网格单元的中心被三角形所覆盖&#xff0c…

【JavaScript】算法之分治、动态规划

一个大问题分成多个小问题&#xff0c;递归解决小问题&#xff0c;将结果合并从而来解决原来的问题 分治 子问题都是独立的 动态规划 把分治优化了【重复的问题&#xff0c;单独保存起来】斐波那契数列 leetcode 习题 分治、动态规划习题

Varjo在芬兰开设新工厂,以满足国防部门在XR模拟训练中的需求

在军事国防领域&#xff0c;全新技术的投入使用最看重的就是保密与安全。作为全球领先的XR头戴式显示器提供商Varjo&#xff0c;近日正式宣布将在位于芬兰的赫尔辛基开设一家新的安全制造工厂。 此次工厂扩建将使Varjo能够满足国防训练和模拟领域对其高分辨率XR解决方案日益增…

Python if 语句优化技巧

大家好&#xff01;今天我们来聊聊Python中的if语句优化技巧。if语句是Python中最基本的控制结构之一&#xff0c;它用于根据条件执行不同的代码块。虽然if语句本身非常简单&#xff0c;但通过一些小技巧&#xff0c;可以让我们的代码更加高效、简洁。接下来&#xff0c;我们将…

怎么选择合适的员工电脑监控软件,优质的电脑屏幕监控软件

在当今信息化管理的时代&#xff0c;员工电脑监控软件已成为中小公司管理的重要工具之一。无论是提升工作效率、保障公司数据安全&#xff0c;还是确保员工在工作时间专注于任务&#xff0c;选择一款合适的监控软件都至关重要。今天&#xff0c;我们将重点介绍一款国内优秀的监…

Android TV RecyclerView列表获得焦点左右换行

在TV上&#xff0c;用RecyclerView显示一个列表&#xff0c;飞鼠遥控左右遥控获得Item焦点&#xff0c;到最后一个进行右键换行&#xff0c;是不能做到的&#xff0c;因此需要监听key事件处理换行。 效果图如下 代码实现 Item.xml布局 <?xml version"1.0" enc…

24最全网最全面的Comfyui工作流原理拆解分析教程!

前言 前言 前面几篇有讲到Comfyui的安装和入门基础的文生图&#xff0c;图生图加上CN和局部重绘的工作流教程&#xff0c;这工作流是基于sd webui的工作流原理跟大家简单讲了Comfyui工作流的基本原理。 今天我们通过拆解组合的方式再稍微深入拓展给大家讲一下Comfyui的工作流…

基于springboot+vue图书管理系统的设计与实现

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;图书信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

昂科烧录器支持Senasic琻捷电子的蓝牙低功耗芯片SNP746

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Senasic琻捷电子的蓝牙低功耗芯片SNP746已经被昂科的通用烧录平台AP8000所支持。 SNP746是一款蓝牙低功耗芯片&#xff0c;集成了压力传感器和加速度传感器的测量电路。它是为…

以电子书号出版的论著有哪些优缺点?

以电子书号出版的论著具有以下优点和缺点&#xff1a; 优点&#xff1a; 1. 费用较低&#xff1a; - 电子书号的管理费用相对较低&#xff0c;因为其不需要分配 CIP 数据&#xff08;图书在版编目数据&#xff09;&#xff0c;这一项就节省了不少成本。对于一些预算有限的作者…

不小心把U盘格式化了怎么恢复?教你轻松找回数据

U盘作为我们日常工作和生活中的重要数据存储工具&#xff0c;其便携性和大容量深受用户喜爱。然而&#xff0c;不小心将U盘格式化&#xff0c;导致重要数据丢失&#xff0c;是许多人都可能遇到的问题。 当这种突发情况发生时&#xff0c;我们应该如何迅速有效地恢复被格式化的…

最佳实践 · 如何高效索引MySQL JSON字段

概述 从MySQL 5.7.8版本开始&#xff0c;MySQL引入了对JSON字段的支持&#xff0c;这为处理半结构化数据提供了极大的灵活性。然而&#xff0c;MySQL原生并不支持直接对JSON对象中的字段进行索引。本文将介绍如何利用MySQL 5.7中的虚拟字段功能&#xff0c;对JSON字段中的数据…

数据结构-排序(冒泡,选择,插入,希尔,快排,归并,堆排)

文章目录 排序冒泡排序代码实现 选择排序动图演示代码实现 插入排序动图演示代码实现 希尔排序动图演示代码实现 快速排序动图演示代码实现(递归) 归并排序动图演示代码实现 堆排序动图演示代码实现 排序 概念&#xff1a;排序就是将一组杂乱无章的数据按照一定的规律&#xff…

web基础—dvwa靶场(九)Weak Session IDs

Weak Session IDs&#xff08;弱会话&#xff09; Weak Session IDs&#xff08;弱会话&#xff09;&#xff0c;用户访问服务器的时候&#xff0c;一般服务器都会分配一个身份证 session id 给用户&#xff0c;用于标识。用户拿到 session id 后就会保存到 cookies 上&#x…

数据可视化pyecharts——数据分析(柱状图、折线图、饼图)

安装 首先确保已经安装了pyecharts库&#xff0c;如果没有&#xff0c;可以通过pip install pyecharts进行安装。 柱状图 从pyecharts.charts导入Bar&#xff0c;从pyecharts导入options。准备数据&#xff08;如类别数据x_data和对应的数值数据y_data&#xff09;。创建Bar对…