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 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 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 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 points = new ArrayList(); /** * 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); } }