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