package com.dji.sample.patches.utils; import org.locationtech.jts.geom.Coordinate; import java.util.*; import java.util.stream.Collectors; /** * @PROJECT_NAME: drone * @DESCRIPTION: 计算两个经纬度点之间的距离(以公里为单位) * @USER: aix * @DATE: 2024/3/25 14:25 */ public class DistanceCalculator { private static final int EARTH_RADIUS_KM = 6371; // 地球半径,单位:公里 /** * 使用Haversine公式计算两个经纬度点之间的距离(单位:公里) * * @param lat1 第一个点的纬度 * @param lon1 第一个点的经度 * @param lat2 第二个点的纬度 * @param lon2 第二个点的经度 * @return 两点之间的距离(单位:公里) */ public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { double dLat = Math.toRadians(lat2 - lat1); double dLon = Math.toRadians(lon2 - lon1); lat1 = Math.toRadians(lat1); lat2 = Math.toRadians(lat2); double a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double distance = EARTH_RADIUS_KM * c; return distance; } /** * 中心点排序 * @param coordinates 中心点数组 * @param airportLat 纬度 * @param airportLon 经度 * @param index 索引 * @param retCoordinate 返回结果 * @return */ public static Coordinate[] sortByDistance(List coordinates, double airportLat, double airportLon,int index,Coordinate[] retCoordinate) { // 创建一个列表来保存坐标、对应的距离以及原始下标 List>> distanceList = new ArrayList<>(); for (int i = 0; i < coordinates.size(); i++) { Coordinate coord = coordinates.get(i); double distance = calculateDistance(airportLat, airportLon, coord.y, coord.x); // 注意:y是纬度,x是经度 distanceList.add(new AbstractMap.SimpleEntry<>(coord, new AbstractMap.SimpleEntry<>(distance, i))); } // 根据距离进行排序 distanceList.sort(Comparator.comparingDouble(entry -> entry.getValue().getKey())); //中心点排序结果 retCoordinate[index] = distanceList.get(0).getKey(); coordinates.remove(distanceList.get(0).getKey()); if (coordinates.size() > 0) { index = index+1; sortByDistance(coordinates,distanceList.get(0).getKey().y,distanceList.get(0).getKey().x,index,retCoordinate); } return retCoordinate; } public static Coordinate[] getFirstPolygon(List coordinatesCentro,Coordinate[] afterCoor,List> coordinates) { // 创建一个列表来保存坐标、对应的距离以及原始下标 List>>> distanceList = new ArrayList<>(); for (int i = 0; i < coordinates.size(); i++) { Coordinate coord = coordinatesCentro.get(i); distanceList.add(new AbstractMap.SimpleEntry<>(coord, coordinates)); } // 如果你需要排序前的下标,你可以通过以下方式获取它们: Map>> originalIndexMap = distanceList.stream() .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())); // 现在你可以通过坐标查找原始的下标 // 例如:int originalIndex = originalIndexMap.get(someCoordinate); Coordinate[] retcoor = new Coordinate[afterCoor.length * 4 - 3]; for (int i = 0; i