智慧农业后台管理
tangzy
2022-07-16 b3e4a07414be178705937f78e3deafd3536012bf
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
152
153
154
155
156
157
158
159
160
161
162
163
package org.springblade.common.utils;
 
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 根据经纬度计算面积工具类
 *
 * @author hwl
 * @version 1.0.0 2018-01-17
 */
public class PolyginArea {
 
    // 地球半径 - 米
    // 源码中使用半径为 6367460.0;
    private static double earthRadiusMeters = 6371000.0;
    private static double metersPerDegree = 2.0 * Math.PI * earthRadiusMeters / 360.0;
    private static double radiansPerDegree = Math.PI / 180.0;
    private static double degreesPerRadian = 180.0 / Math.PI;
 
//    /**
//     * 传入经纬度集合计算面积
//     * @param points
//     */
//    private void calculateArea(List<double[]> points) {
//        if (points.size() > 2) {
//            double areaMeters2 = PlanarPolygonAreaMeters2(points);
//            // if (areaMeters2 > 1000000.0) {
//            areaMeters2 = SphericalPolygonAreaMeters2(points);
//            System.out.println("面积为:" + areaMeters2 + "(平方米)");
//            // }
//
//        }
//    }
 
    /**
     * 球面多边形面积计算
     *
     * @param points
     * @return
     */
    private double SphericalPolygonAreaMeters2(List<double[]> points) {
        double totalAngle = 0.0;
        for (int i = 0; i < points.size(); i++) {
            int j = (i + 1) % points.size();
            int k = (i + 2) % points.size();
            totalAngle += Angle(points.get(i), points.get(j), points.get(k));
        }
 
        double planarTotalAngle = (points.size() - 2) * 180.0;
        double sphericalExcess = totalAngle - planarTotalAngle;
 
        if (sphericalExcess > 420.0) {
            totalAngle = points.size() * 360.0 - totalAngle;
            sphericalExcess = totalAngle - planarTotalAngle;
        } else if (sphericalExcess > 300.0 && sphericalExcess < 420.0) {
            sphericalExcess = Math.abs(360.0 - sphericalExcess);
        }
 
        return sphericalExcess * radiansPerDegree * earthRadiusMeters
                * earthRadiusMeters;
    }
 
    /**
     * 角度
     *
     * @param p1
     * @param p2
     * @param p3
     * @return
     */
    private double Angle(double[] p1, double[] p2, double[] p3) {
        double bearing21 = Bearing(p2, p1);
        double bearing23 = Bearing(p2, p3);
        double angle = bearing21 - bearing23;
        if (angle < 0.0) {
            angle += 360.0;
        }
        return angle;
    }
 
    /**
     * 方向
     *
     * @param from
     * @param to
     * @return
     */
    private double Bearing(double[] from, double[] to) {
        double lat1 = from[1] * radiansPerDegree;
        double lon1 = from[0] * radiansPerDegree;
        double lat2 = to[1] * radiansPerDegree;
        double lon2 = to[0] * radiansPerDegree;
        double angle = -Math.atan2(
                Math.sin(lon1 - lon2) * Math.cos(lat2),
                Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
                        * Math.cos(lat2) * Math.cos(lon1 - lon2));
        if (angle < 0.0) {
            angle += Math.PI * 2.0;
        }
        angle = angle * degreesPerRadian;
        return angle;
    }
 
    /***
     * 平面多边形面积
     *
     * @param points
     *            Point2D.Double
     * @return
     * */
    public static double getAreaByxy(List<Point2D.Double> points) {
        double a = 0.0;
        if(points.size() > 2){
            for (int i = 0; i < points.size(); ++i) {
                int j = (i + 1) % points.size();
                double xi = points.get(i).x * metersPerDegree
                        * Math.cos(points.get(i).y * radiansPerDegree);
                double yi = points.get(i).y * metersPerDegree;
                double xj = points.get(j).x * metersPerDegree
                        * Math.cos(points.get(j).y * radiansPerDegree);
                double yj = points.get(j).y * metersPerDegree;
                a += xi * yj - xj * yi;
            }
        }
        a = BigDecimal.valueOf(Math.abs(a / 2.0)).setScale(1,BigDecimal.ROUND_DOWN).doubleValue();
        return a;
    }
 
    public static void main(String[] args) {
        List<Point2D.Double> points = new ArrayList<Point2D.Double>();
 
        /**
         * x1 = 84.86258; y1 = 44.46333;
         *
         * x2 = 84.86075; y2 = 44.45999;
         *
         * x3 = 84.86229; y3 = 44.45971;
         *
         * x4 = 84.86414; y4 = 44.46309;
         */
        // String s = "112.5293197631836,37.868892669677734;" +
        // "112.5170669555664,37.8605842590332;" +
        // "112.52099609375,37.849857330322266;" +
        // "112.54137420654297,37.85125732421875;" +
        // "112.53511810302734,37.858699798583984";
        String s = "114.917883,25.816108;114.917207,25.815577;114.918162,25.815519;114.917883,25.816108";
        String[] s1 = s.split(";");
        for (String ss : s1) {
            String[] temp = ss.split(",");
            Point2D.Double point = new Point2D.Double(Double.parseDouble(temp[0]),
                    Double.parseDouble(temp[1]));
            points.add(point);
            System.out.println(temp[1] + "," + temp[0]);
        }
        PolyginArea tp = new PolyginArea();
        double area = tp.getAreaByxy(points);
        System.out.println("面积是: " + area);
    }
 
}