吉安感知网项目-后端
xiebin
2026-01-06 d207a86cdf1ab52ef8cb7cd83bad8fceab8038cf
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package org.sxkj.common.geo.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;
    }
 
    // 计算两点之间的欧几里得距离
    public static double distance(Coordinate a1, Coordinate b2) {
        double lat1 = Math.toRadians(a1.y); // 将纬度从度转换为弧度
        double lat2 = Math.toRadians(b2.y); // 将纬度从度转换为弧度
        double lon1 = Math.toRadians(a1.x); // 将经度从度转换为弧度
        double lon2 = Math.toRadians(b2.x); // 将经度从度转换为弧度
 
        double dLat = lat2 - lat1; // 纬度差
        double dLon = lon2 - lon1; // 经度差
 
        // 使用 Haversine 公式
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.sin(dLon / 2) * Math.sin(dLon / 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 point1 第一个点
     * @param point2 第二个点
     * @return 两点之间的距离(米)
     */
    public static double calculateDistance(Coordinate point1, Coordinate point2) {
        final double EARTH_RADIUS = 6371000; // 地球半径(米)
 
        // 将经纬度转换为弧度
        double lat1 = Math.toRadians(point1.getY());
        double lng1 = Math.toRadians(point1.getX());
        double lat2 = Math.toRadians(point2.getY());
        double lng2 = Math.toRadians(point2.getX());
 
        // 使用Haversine公式计算距离
        double deltaLat = lat2 - lat1;
        double deltaLng = lng2 - lng1;
 
        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
            Math.cos(lat1) * Math.cos(lat2) *
                Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);
 
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 
        return EARTH_RADIUS * c;
    }
 
    /**
     *  中心点排序
     * @param coordinates 中心点数组
     * @param airportLat 纬度
     * @param airportLon 经度
     * @param index 索引
     * @param retCoordinate 返回结果
     * @return
     */
    public static Coordinate[] sortByDistance(List<Coordinate> coordinates, double airportLat, double airportLon,int index,Coordinate[] retCoordinate) {
        // 创建一个列表来保存坐标、对应的距离以及原始下标
        List<Map.Entry<Coordinate, Map.Entry<Double, Integer>>> 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<Coordinate> coordinatesCentro,Coordinate[] afterCoor,List<List<Coordinate>> coordinates) {
        // 创建一个列表来保存坐标、对应的距离以及原始下标
        List<Map.Entry<Coordinate, List<List<Coordinate>>>> distanceList = new ArrayList<>();
        for (int i = 0; i < coordinates.size(); i++) {
            Coordinate coord = coordinatesCentro.get(i);
            distanceList.add(new AbstractMap.SimpleEntry<>(coord, coordinates));
        }
 
        // 如果你需要排序前的下标,你可以通过以下方式获取它们:
        Map<Coordinate, List<List<Coordinate>>> 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<afterCoor.length;i++) {
            originalIndexMap.get(afterCoor[i]);
            System.out.println(originalIndexMap.get(afterCoor[i]));
        }
 
        return null;
 
    }
 
 
 
 
 
}