智慧农业后台管理
tangzy
2022-05-12 362b8dd171ada6b7cf05ac4027df7f1abe9b16fd
面积计算
1 files added
163 ■■■■■ changed files
src/main/java/org/springblade/common/utils/PolyginArea.java 163 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/PolyginArea.java
New file
@@ -0,0 +1,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);
    }
}