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;
|
}
|
}
|