From 59782d1d8abc7a98111459349b4fddf45d286866 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E7=8E=89=E4=B8=9C?=
<129883742+liyudong2018@users.noreply.github.com>
Date: Thu, 18 Sep 2025 23:33:24 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9B=B8=E5=85=B3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/main/demo.html | 131 +++++++--------
src/main/java/com/hivekion/Test.java | 18 +-
.../common/MultiPointGeoPosition.java | 18 ++
.../com/hivekion/enums/WsCmdTypeEnum.java | 24 +++
.../com/hivekion/room/bean/MoveRootTask.java | 158 +++++++++++++++---
.../java/com/hivekion/room/bean/Room.java | 2 +-
.../service/impl/ScenarioTaskServiceImpl.java | 2 +-
.../service/impl/StatisticServiceImpl.java | 17 +-
src/main/java/com/hivekion/ws/WsServer.java | 4 +-
.../resources/application-rule.properties | 0
10 files changed, 268 insertions(+), 106 deletions(-)
create mode 100644 src/main/java/com/hivekion/enums/WsCmdTypeEnum.java
create mode 100644 src/main/resources/application-rule.properties
diff --git a/src/main/demo.html b/src/main/demo.html
index 4552271..d4dcd15 100644
--- a/src/main/demo.html
+++ b/src/main/demo.html
@@ -1,89 +1,86 @@
-
+
-
- Google Map 绘制路线
-
+
+ WS实时推送轨迹 - Google Map
+
-
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hivekion/Test.java b/src/main/java/com/hivekion/Test.java
index e990746..3dfaf84 100644
--- a/src/main/java/com/hivekion/Test.java
+++ b/src/main/java/com/hivekion/Test.java
@@ -1,5 +1,8 @@
package com.hivekion;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
/**
* [类的简要说明]
*
@@ -12,13 +15,12 @@ package com.hivekion;
public class Test {
public static void main(String[] args) {
- String test = "id\n"
- + "general_time\n"
- + "from_resource_id\n"
- + "supplier_type\n"
- + "supplier_num\n"
- + "lat\n"
- + "lng";
- System.out.println(test.toUpperCase());
+ TreeMap treeMap = new TreeMap();
+ treeMap.put(new Double("1"), "1");
+ treeMap.put(new Double("5"), "1");
+ treeMap.put(new Double("9"), "1");
+ treeMap.put(new Double("20"), "1");
+ treeMap.put(new Double("21"), "1");
+ System.out.println(treeMap.ceilingKey(new Double("22"))); ;
}
}
diff --git a/src/main/java/com/hivekion/common/MultiPointGeoPosition.java b/src/main/java/com/hivekion/common/MultiPointGeoPosition.java
index de99522..3ab572d 100644
--- a/src/main/java/com/hivekion/common/MultiPointGeoPosition.java
+++ b/src/main/java/com/hivekion/common/MultiPointGeoPosition.java
@@ -40,6 +40,7 @@ public class MultiPointGeoPosition {
}
public static double[] interpolate(double lat1, double lon1, double lat2, double lon2, double f) {
+
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
lat2 = toRadians(lat2);
@@ -118,4 +119,21 @@ public class MultiPointGeoPosition {
PositionResult pos = getPosition(points, speed, time);
System.out.printf("当前位置:纬度 %.6f, 经度 %.6f, 是否到达:%s\n", pos.latitude, pos.longitude, pos.reached ? "是" : "否");
}
+ /**
+ * 沿球面大圆,从起点(lat1, lon1)出发,沿着到终点(lat2, lon2)方向,距离为d(米)的位置点
+ * 若d >= 起点到终点距离,则返回终点
+ * @param lat1 起点纬度
+ * @param lon1 起点经度
+ * @param lat2 终点纬度
+ * @param lon2 终点经度
+ * @param d 距起点的距离(米)
+ * @return double[]{纬度, 经度}
+ */
+ public static double[] pointAlong(double lat1, double lon1, double lat2, double lon2, double d) {
+ double L = haversine(lat1, lon1, lat2, lon2);
+ if (d <= 0) return new double[] {lat1, lon1};
+ if (d >= L) return new double[] {lat2, lon2};
+ double f = d / L;
+ return interpolate(lat1, lon1, lat2, lon2, f);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/hivekion/enums/WsCmdTypeEnum.java b/src/main/java/com/hivekion/enums/WsCmdTypeEnum.java
new file mode 100644
index 0000000..1b00d81
--- /dev/null
+++ b/src/main/java/com/hivekion/enums/WsCmdTypeEnum.java
@@ -0,0 +1,24 @@
+package com.hivekion.enums;
+
+import lombok.Getter;
+
+/**
+ * [类的简要说明]
+ *
+ * [详细描述,可选]
+ *
+ *
+ * @author LiDongYU
+ * @since 2025/7/22
+ */
+public enum WsCmdTypeEnum {
+ PATH_UPDATE("path_update"),
+ PATH_FINISHED("path_finished"),
+ PATH_INIT("path_init");
+ @Getter
+ private final String code;
+
+ WsCmdTypeEnum(String code) {
+ this.code = code;
+ }
+}
diff --git a/src/main/java/com/hivekion/room/bean/MoveRootTask.java b/src/main/java/com/hivekion/room/bean/MoveRootTask.java
index 3a1ebce..052bf82 100644
--- a/src/main/java/com/hivekion/room/bean/MoveRootTask.java
+++ b/src/main/java/com/hivekion/room/bean/MoveRootTask.java
@@ -7,13 +7,21 @@ import com.alibaba.fastjson2.JSONObject;
import com.hivekion.Global;
import com.hivekion.common.MultiPointGeoPosition;
import com.hivekion.common.entity.ResponseCmdInfo;
+import com.hivekion.enums.WsCmdTypeEnum;
import com.hivekion.room.func.TaskAction;
import com.hivekion.scenario.entity.ScenarioTask;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
@@ -29,12 +37,19 @@ import org.springframework.core.env.Environment;
@Slf4j
public class MoveRootTask extends AbtParentTask implements TaskAction {
+ /**
+ * 速度 换算为100Km/小时
+ */
+ private final double SPEED = 27;
+ /**
+ * 距离和坐标的对应关系
+ */
+ private final TreeMap distanceInfoMap = new TreeMap<>();
+ /**
+ * 开始点坐标
+ */
+ private final AtomicReference startPoint = new AtomicReference<>();
- private final double SPEED = 170;//速度
- private double accumulatedDistance = 0;//累计距离
- private final Map distanceInfoMap = new TreeMap();//距离和坐标点对应关系
- private Double beforeLng = null;//上一次经度
- private Double beforeLat = null; //上一次纬度
public MoveRootTask(ScenarioTask scenarioTask, String roomId) {
super(scenarioTask, roomId);
@@ -53,9 +68,7 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
*/
private void initPath() {
try {
- beforeLng = Double.parseDouble(scenarioTask.getFromLng());
- beforeLat = Double.parseDouble(scenarioTask.getFromLat());
- //累计距离
+
String url = SpringUtil.getBean(Environment.class).getProperty("path.planning.url");
String params = url + "?"
+ "profile=car"
@@ -65,35 +78,56 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
+ scenarioTask.getToLng()
+ "&points_encoded=false"
+ "&algorithm=alternative_route&alternative_route.max_paths=3";
- log.info("params::{}", params);
+ //获取路线信息
String result = webClient.get().uri(params)
.retrieve()
.bodyToMono(String.class)
.block();
- log.info("result:{}", result);
+
JSONObject pointJson = JSON.parseObject(result);
//获取路径点
if (pointJson != null) {
JSONObject pointsObj = pointJson.getJSONArray("paths").getJSONObject(0)
.getJSONObject("points");
-
+ JSONArray coordinates = pointsObj.getJSONArray("coordinates");
+ //组装信息
+ Map dataMap = new HashMap<>();
+ dataMap.put("resourceId", scenarioTask.getResourceId());
+ dataMap.put("points", coordinates);
//推送路径任务
Global.sendCmdInfoQueue.add(
- ResponseCmdInfo.create("path_init", roomId, scenarioTask.getScenarioId(), pointsObj));
-
- JSONArray coordinates = pointsObj.getJSONArray("coordinates");
-
+ ResponseCmdInfo.create(WsCmdTypeEnum.PATH_INIT.getCode(), roomId,
+ scenarioTask.getScenarioId(), dataMap));
+ log.info("init::{}", JSON.toJSONString(coordinates));
+ //计算各个点的累计距离和坐标的对应关系
+ double beforeLng = Double.parseDouble(scenarioTask.getFromLng());
+ double beforeLat = Double.parseDouble(scenarioTask.getFromLat());
+ double total = 0;
for (int i = 0; i < coordinates.size(); i++) {
JSONArray coordinate = coordinates.getJSONArray(i);
Double lng = coordinate.getDouble(0);
+
Double lat = coordinate.getDouble(1);
- double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lng, lat);
- distanceInfoMap.put(distance, lng + "," + lat);
+
+ double distance = MultiPointGeoPosition.haversine(beforeLat, beforeLng, lat, lng);
+ //当前总距离
+ total = total + distance;
+ //定义坐标对象
+ Coordinate coordinateInfo = new Coordinate();
+ coordinateInfo.setLat(lat);
+ coordinateInfo.setLng(lng);
+
+ //记录距离和数组列表直接的索引关系
+ distanceInfoMap.put(total, coordinateInfo);
+
beforeLng = lng;
beforeLat = lat;
}
+ //设置第一个开始位置
+ startPoint.set(distanceInfoMap.firstKey());
}
+
} catch (Exception e) {
log.error("error::", e);
}
@@ -104,14 +138,96 @@ public class MoveRootTask extends AbtParentTask implements TaskAction {
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(
1);
schedule.scheduleWithFixedDelay(() -> {
- long duringTime = getDuringTime();
- //
- double distance = duringTime * SPEED;
-
+
+ try {
+ if (this.getRoomStatus()) {
+
+ long duringTime = getDuringTime();
+ log.info("duringTime::{}", duringTime);
+ //跑动距离
+ double distance = duringTime * SPEED;
+ //获取大与此距离的第一个路线点key
+ Entry endPoint = distanceInfoMap.ceilingEntry(distance);
+ //ws数据
+ List dataList = new ArrayList<>();
+ HashMap