张世豪
6 天以前 c498385fb7e372d13e2ee76d7b54ae2381728082
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
package bianjie;
 
import java.util.List;
 
import zhuye.Coordinate;
 
public class jisuanmianjie {
    /**
     * 计算coordinates集合中所有经纬度点围成的多边形面积
     * 使用球面多边形面积计算公式,适用于经纬度坐标
     * 
     * @return 多边形面积(平方米)
     */
    public static double calculatePolygonArea() {
        List<Coordinate> coordinates =Coordinate.coordinates;
        if (coordinates == null || coordinates.size() < 3) {
            System.err.println("坐标点数量不足,至少需要3个点才能构成多边形");
            return 0.0;
        }
        
        int pointCount = coordinates.size();
        double totalArea = 0.0;
        final double EARTH_RADIUS = 6371000.0; // 地球半径(米)
        
        try {
            // 将度分格式转换为十进制度
            double[] lats = new double[pointCount];
            double[] lons = new double[pointCount];
            
            for (int i = 0; i < pointCount; i++) {
                Coordinate coord = coordinates.get(i);
                lats[i] = parseDMMToDegree(coord.getLatitude(), coord.getLatDirection());
                lons[i] = parseDMMToDegree(coord.getLongitude(), coord.getLonDirection());
            }
            
            // 使用球面多边形面积公式
            for (int i = 0; i < pointCount; i++) {
                int j = (i + 1) % pointCount;
                
                double lat1 = Math.toRadians(lats[i]);
                double lon1 = Math.toRadians(lons[i]);
                double lat2 = Math.toRadians(lats[j]);
                double lon2 = Math.toRadians(lons[j]);
                
                totalArea += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2));
            }
            
            totalArea = totalArea * EARTH_RADIUS * EARTH_RADIUS / 2.0;
            
            // 取绝对值确保面积为正
            return Math.abs(totalArea);
            
        } catch (Exception e) {
            System.err.println("计算多边形面积时发生错误: " + e.getMessage());
            e.printStackTrace();
            return 0.0;
        }
    }
 
    /**
     * 将度分格式转换为十进制度
     * 格式示例:纬度"3956.1234" + 方向"N" -> 39.93539度
     * 
     * @param dmm 度分格式字符串
     * @param direction 方向(N/S/E/W)
     * @return 十进制度
     */
    private static double parseDMMToDegree(String dmm, String direction) {
        if (dmm == null || dmm.isEmpty()) {
            return 0.0;
        }
        
        try {
            // 找到小数点的位置
            int dotIndex = dmm.indexOf('.');
            if (dotIndex == -1) {
                dotIndex = dmm.length();
            }
            
            // 确保有足够的位数
            if (dotIndex < 2) {
                return 0.0;
            }
            
            // 提取度和分
            int degrees = Integer.parseInt(dmm.substring(0, dotIndex - 2));
            double minutes = Double.parseDouble(dmm.substring(dotIndex - 2));
            
            // 转换为十进制度
            double decimalDegrees = degrees + minutes / 60.0;
            
            // 根据方向调整符号
            if ("S".equalsIgnoreCase(direction) || "W".equalsIgnoreCase(direction)) {
                decimalDegrees = -decimalDegrees;
            }
            
            return decimalDegrees;
            
        } catch (NumberFormatException e) {
            System.err.println("坐标格式转换错误: " + dmm);
            return 0.0;
        }
    }
 
    /**
     * 计算面积并返回带单位的字符串
     * 
     * @return 面积字符串(平方米和亩)
     */
    public static String getAreaString() {
        double areaM2 = calculatePolygonArea();
        double areaMu = areaM2 / 666.67; // 转换为亩(1亩 ≈ 666.67平方米)
        
        return String.format("面积: %.2f 平方米 (约 %.2f 亩)", areaM2, areaMu);
    }
 
    /**
     * 计算面积并返回带单位的字符串(指定小数位数)
     * 
     * @param decimalPlaces 小数位数
     * @return 面积字符串(平方米和亩)
     */
    public static String getAreaString(int decimalPlaces) {
        double areaM2 = calculatePolygonArea();
        double areaMu = areaM2 / 666.67;
        
        String format = "面积: %." + decimalPlaces + "f 平方米 (约 %." + decimalPlaces + "f 亩)";
        return String.format(format, areaM2, areaMu);
    }
}