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);
|
}
|
|
}
|