From e61944b5ec589380ad36bfe113e410eb0aef0d1d Mon Sep 17 00:00:00 2001
From: sparkcyf <sparktour@outlook.com>
Date: Mon, 27 Nov 2023 08:37:59 +0800
Subject: [PATCH] RealtimeMap.vue: update heading calculation logic, use the
 heading to two nearest points to calculate the heading of the bus 
 modified:   docs/.vuepress/components/RealtimeMap.vue

---
 docs/.vuepress/components/RealtimeMap.vue | 58 +++++++++++++++--------
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/docs/.vuepress/components/RealtimeMap.vue b/docs/.vuepress/components/RealtimeMap.vue
index 1a2bb1a6e..4f2b85e90 100644
--- a/docs/.vuepress/components/RealtimeMap.vue
+++ b/docs/.vuepress/components/RealtimeMap.vue
@@ -169,20 +169,29 @@ export default {
       }
       this.update_location()
     },
-    calculateBusAngle(lat1, lon1, lat2, lon2) {
-      const dLon = (lon2 - lon1);
+    calculateBusAngle(startLat, startLng, destLat, destLng) {
+      // 将度数转换为弧度
+      function toRadians(degrees) {
+        return degrees * Math.PI / 180;
+      };
+
+      // 将弧度转换为度数
+      function toDegrees(radians) {
+        return radians * 180 / Math.PI;
+      }
 
-      const y = Math.sin(dLon) * Math.cos(lat2);
-      const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
-          * Math.cos(lat2) * Math.cos(dLon);
+      // 转换起始点和目标点的经纬度为弧度
+      startLat = toRadians(startLat);
+      startLng = toRadians(startLng);
+      destLat = toRadians(destLat);
+      destLng = toRadians(destLng);
 
+      // 计算方位角
+      const y = Math.sin(destLng - startLng) * Math.cos(destLat);
+      const x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
       let brng = Math.atan2(y, x);
-
-      brng = brng * (180 / Math.PI);
-      brng = (brng + 360) % 360;
-      brng = 360 - brng; // 如果需要顺时针度数,请移除此行
-
-      return brng;
+      brng = toDegrees(brng);
+      return (brng + 360) % 360;
     },
     findNearestPointOnSegment(point, segmentStart, segmentEnd) {
       const A = point[0] - segmentStart[0];
@@ -210,21 +219,27 @@ export default {
       return [xx, yy];
     },
     findNearestSegment(busLocation, geojsonLine) {
-      let closestSegment = [geojsonLine[0], geojsonLine[1]];
+      let closestSegmentStart = geojsonLine[0];
+      let closestSegmentEnd = geojsonLine[1];
       let minDistance = Number.MAX_VALUE;
 
+      // 遍历 GeoJSON 线路的每个线段
       for (let i = 0; i < geojsonLine.length - 1; i++) {
-        const point1 = geojsonLine[i];
-        const point2 = geojsonLine[i + 1];
-        const distance = this.calculateDistance(busLocation, this.findNearestPointOnSegment(busLocation, point1, point2));
+        const segmentStart = geojsonLine[i];
+        const segmentEnd = geojsonLine[i + 1];
+        const nearestPoint = this.findNearestPointOnSegment(busLocation, segmentStart, segmentEnd);
+        const distance = this.calculateDistance(busLocation, nearestPoint);
 
+        // 更新最近线段
         if (distance < minDistance) {
           minDistance = distance;
-          closestSegment = [point1, point2];
+          closestSegmentStart = segmentStart;
+          closestSegmentEnd = segmentEnd;
         }
       }
 
-      return closestSegment;
+      // 确保线段的顺序与 GeoJSON 中的一致
+      return [closestSegmentStart, closestSegmentEnd];
     },
     calculateDistance(point1, point2) {
       return Math.sqrt(Math.pow(point2[0] - point1[0], 2) + Math.pow(point2[1] - point1[1], 2));
@@ -237,13 +252,18 @@ export default {
         // if current time - report time < 300s, then display
         if (parseInt(new Date().getTime() / 1000) - this.bus_location_data_api[i].time_mt < 300) {
           const busLocation = [this.bus_location_data_api[i].lng, this.bus_location_data_api[i].lat];
+          var busHeadingAngle = 0
           if (this.bus_location_data_api[i].route_code.slice(-1) === '1') { //XYBS1
             this.bus_location_data_api[i].route_geojson = this.geojson_line_1
+            const closestSegment = this.findNearestSegment(busLocation, this.bus_location_data_api[i].route_geojson);
+            console.log(closestSegment)
+            busHeadingAngle = this.calculateBusAngle(closestSegment[0][1], closestSegment[0][0], closestSegment[1][1], closestSegment[1][0]);
           } else { //XYBS2
             this.bus_location_data_api[i].route_geojson = this.geojson_line_2
+            const closestSegment = this.findNearestSegment(busLocation, this.bus_location_data_api[i].route_geojson);
+            busHeadingAngle = this.calculateBusAngle(closestSegment[0][1], closestSegment[0][0], closestSegment[1][1], closestSegment[1][0]) - 180;
           }
-          const closestSegment = this.findNearestSegment(busLocation, this.bus_location_data_api[i].route_geojson);
-          const busHeadingAngle = this.calculateBusAngle(busLocation[1], busLocation[0], closestSegment[1][1], closestSegment[1][0]);
+
 
 
           // create a DOM element for the marker