puzhibing
2026-04-11 b6f3de8451867d85242b2bd706fcfa4a65df4ff7
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
package com.xiaopeng.map.utils.map.map;
 
public class FastDistanceCalculator {
    private static final double R = 6371.0; // 地球半径(千米)
    private static final double DEG_TO_RAD = Math.PI / 180.0;
    
    /**
     * 快速近似算法 - 性能极高,误差<0.5%
     * 适合需要大量计算的场景(如KNN、聚类)
     * 米
     */
    public static double distanceFast(double lat1, double lon1, 
                                      double lat2, double lon2) {
        double x = (lon2 - lon1) * DEG_TO_RAD * Math.cos((lat1 + lat2) * 0.5 * DEG_TO_RAD);
        double y = (lat2 - lat1) * DEG_TO_RAD;
        return R * Math.sqrt(x * x + y * y)*1000;
    }
 
    /**
     * 快速近似算法 - 误差<0.5%
     * 适合需要大量计算的场景(如KNN、聚类)
     * 千米
     */
    public static double distanceFastKm(double lat1, double lon1,
                                      double lat2, double lon2) {
        double x = (lon2 - lon1) * DEG_TO_RAD * Math.cos((lat1 + lat2) * 0.5 * DEG_TO_RAD);
        double y = (lat2 - lat1) * DEG_TO_RAD;
        return R * Math.sqrt(x * x + y * y);
    }
 
    /**
     * 平面近似 - 极高性能,适用于小范围(城市内)
     */
    public static double distanceFlatApprox(double lat1, double lon1,
                                           double lat2, double lon2) {
        // 每度纬度约111km,每度经度随纬度变化
        double kmPerDegreeLat = 111.0;
        double kmPerDegreeLon = 111.0 * Math.cos((lat1 + lat2) * 0.5 * DEG_TO_RAD);
        
        double dLat = lat2 - lat1;
        double dLon = lon2 - lon1;
        
        return Math.sqrt(Math.pow(dLat * kmPerDegreeLat, 2) + 
                        Math.pow(dLon * kmPerDegreeLon, 2));
    }
}