无关风月
2 天以前 d8ad5605a031477c252e029149a4735a1a20ffbd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.ruoyi.web.controller.tool;
 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
 
import java.util.ArrayList;
import java.util.List;
 
public class PathParser {
    public static List<double[]> parseAndInterpolate(String jsonResponse, int segments,double startLat, double startLon, double endLat, double endLon) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(jsonResponse);
        JsonNode steps = root.at("/route/paths/0/steps");
        List<double[]> allPoints = new ArrayList<>();
        allPoints.add(new double[]{startLat, startLon});
 
        if (startLat==endLat&&startLon==endLon){
            allPoints.add(new double[]{startLat, startLon});
        }else{
            for (JsonNode step : steps) {
                String polyline = step.get("polyline").asText();
                String[] points = polyline.split(";");
                for (String point : points) {
                    String[] lonlat = point.split(",");
                    double lon = Double.parseDouble(lonlat[0]);
                    double lat = Double.parseDouble(lonlat[1]);
                    allPoints.add(new double[]{lat, lon});
                }
            }
        }
 
        allPoints.add(new double[]{endLat, endLon});
 
        // 计算总距离
        double totalDistance = 0;
        for (int i = 1; i < allPoints.size(); i++) {
            totalDistance += calculateDistance(allPoints.get(i - 1)[0], allPoints.get(i - 1)[1],
                    allPoints.get(i)[0], allPoints.get(i)[1]);
        }
 
        // 均分距离
        double segmentLength = totalDistance / segments;
        List<double[]> resultPoints = new ArrayList<>();
        resultPoints.add(allPoints.get(0));
 
        double accumulatedDistance = 0;
        int currentPointIndex = 0;
        for (int i = 1; i < segments; i++) {
            double targetDistance = i * segmentLength;
            while (accumulatedDistance < targetDistance && currentPointIndex < allPoints.size() - 1) {
                double[] p1 = allPoints.get(currentPointIndex);
                double[] p2 = allPoints.get(currentPointIndex + 1);
                double d = calculateDistance(p1[0], p1[1], p2[0], p2[1]);
                if (accumulatedDistance + d >= targetDistance) {
                    double ratio = (targetDistance - accumulatedDistance) / d;
                    double lat = p1[0] + ratio * (p2[0] - p1[0]);
                    double lon = p1[1] + ratio * (p2[1] - p1[1]);
                    resultPoints.add(new double[]{lat, lon});
                    accumulatedDistance = targetDistance;
                } else {
                    accumulatedDistance += d;
                    currentPointIndex++;
                }
            }
        }
 
        resultPoints.add(allPoints.get(allPoints.size() - 1));
        return resultPoints;
    }
 
    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        double R = 6371000; // 地球半径单位米
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
 
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                        Math.sin(dLon / 2) * Math.sin(dLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c;
    }
}