From 362b8dd171ada6b7cf05ac4027df7f1abe9b16fd Mon Sep 17 00:00:00 2001
From: tangzy <tangzy123456>
Date: Thu, 12 May 2022 16:50:23 +0800
Subject: [PATCH] 面积计算

---
 src/main/java/org/springblade/common/utils/PolyginArea.java |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)

diff --git a/src/main/java/org/springblade/common/utils/PolyginArea.java b/src/main/java/org/springblade/common/utils/PolyginArea.java
new file mode 100644
index 0000000..774c661
--- /dev/null
+++ b/src/main/java/org/springblade/common/utils/PolyginArea.java
@@ -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);
+	}
+
+}

--
Gitblit v1.9.3