新增经纬度点计算工具
This commit is contained in:
parent
f94288675d
commit
e2dcc3e270
33
basic-util/src/main/java/ink/wgink/util/point/Circle.java
Normal file
33
basic-util/src/main/java/ink/wgink/util/point/Circle.java
Normal file
@ -0,0 +1,33 @@
|
||||
package ink.wgink.util.point;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: Circle
|
||||
* @Description: 圆
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019-08-09 22:54
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class Circle {
|
||||
private double r;
|
||||
private Point point;
|
||||
|
||||
public double getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public void setR(double r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
public Point getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public void setPoint(Point point) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
}
|
41
basic-util/src/main/java/ink/wgink/util/point/Point.java
Normal file
41
basic-util/src/main/java/ink/wgink/util/point/Point.java
Normal file
@ -0,0 +1,41 @@
|
||||
package ink.wgink.util.point;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: Point
|
||||
* @Description: 点
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019-08-09 22:44
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class Point {
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
|
||||
public Point() {
|
||||
}
|
||||
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
}
|
304
basic-util/src/main/java/ink/wgink/util/point/PointUtil.java
Normal file
304
basic-util/src/main/java/ink/wgink/util/point/PointUtil.java
Normal file
@ -0,0 +1,304 @@
|
||||
package ink.wgink.util.point;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: PointUtil
|
||||
* @Description: 点工具类
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019-08-09 22:43
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class PointUtil {
|
||||
|
||||
private static final double EARTH_RADIUS = 637_1393.00D;
|
||||
private static final double RADIAN = Math.PI / 180.00D;
|
||||
private static final double HALF = 0.5D;
|
||||
|
||||
/**
|
||||
* 点在多边形内
|
||||
*
|
||||
* @param point
|
||||
* @param points
|
||||
* @return
|
||||
*/
|
||||
public static boolean isPointInPoly(Point point, List<Point> points) {
|
||||
int N = points.size();
|
||||
//如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
|
||||
boolean boundOrVertex = true;
|
||||
//cross points count of x
|
||||
int intersectCount = 0;
|
||||
//浮点类型计算时候与0比较时候的容差
|
||||
double precision = 2e-10;
|
||||
//neighbour bound vertices
|
||||
Point p1, p2;
|
||||
//当前点
|
||||
Point p = point;
|
||||
//left vertex
|
||||
p1 = points.get(0);
|
||||
//check all rays
|
||||
for (int i = 1; i <= N; ++i) {
|
||||
if (p.equals(p1)) {
|
||||
//p is an vertex
|
||||
return boundOrVertex;
|
||||
}
|
||||
//right vertex
|
||||
p2 = points.get(i % N);
|
||||
//ray is outside of our interests
|
||||
if (p.getX() < Math.min(p1.getX(), p2.getX()) || p.getX() > Math.max(p1.getX(), p2.getX())) {
|
||||
p1 = p2;
|
||||
continue;//next ray left point
|
||||
}
|
||||
//ray is crossing over by the algorithm (common part of)
|
||||
if (p.getX() > Math.min(p1.getX(), p2.getX()) && p.getX() < Math.max(p1.getX(), p2.getX())) {
|
||||
//x is before of ray
|
||||
if (p.getY() <= Math.max(p1.getY(), p2.getY())) {
|
||||
//overlies on a horizontal ray
|
||||
if (p1.getX() == p2.getX() && p.getY() >= Math.min(p1.getY(), p2.getY())) {
|
||||
return boundOrVertex;
|
||||
}
|
||||
//ray is vertical
|
||||
if (p1.getY() == p2.getY()) {
|
||||
//overlies on a vertical ray
|
||||
if (p1.getY() == p.getY()) {
|
||||
return boundOrVertex;
|
||||
} else {
|
||||
//before ray
|
||||
++intersectCount;
|
||||
}
|
||||
} else {
|
||||
//cross point on the left side
|
||||
//cross point of y
|
||||
double xinters = (p.getX() - p1.getX()) * (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()) + p1.getY();
|
||||
//overlies on a ray
|
||||
if (Math.abs(p.getY() - xinters) < precision) {
|
||||
return boundOrVertex;
|
||||
}
|
||||
//before ray
|
||||
if (p.getY() < xinters) {
|
||||
++intersectCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//special case when ray is crossing through the vertex
|
||||
//p crossing over p2
|
||||
if (p.getX() == p2.getX() && p.getY() <= p2.getY()) {
|
||||
//next vertex
|
||||
Point p3 = points.get((i + 1) % N);
|
||||
//p.x lies between p1.x & p3.x
|
||||
if (p.getX() >= Math.min(p1.getX(), p3.getX()) && p.getX() <= Math.max(p1.getX(), p3.getX())) {
|
||||
++intersectCount;
|
||||
} else {
|
||||
intersectCount += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//next ray left point
|
||||
p1 = p2;
|
||||
}
|
||||
if (intersectCount % 2 == 0) {
|
||||
//偶数在多边形外
|
||||
return false;
|
||||
} else {
|
||||
//奇数在多边形内
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否在圆形内
|
||||
* <p>
|
||||
* 判断点与圆心之间的距离和圆半径的关系
|
||||
*
|
||||
* @param p
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
public static int distencePC(Point p, Circle c) {
|
||||
int s;
|
||||
double d2 = Math.hypot((p.getX() - c.getPoint().getX()), (p.getY() - c.getPoint().getY()));
|
||||
double r = c.getR();
|
||||
if (d2 > r) {
|
||||
// 圆外
|
||||
s = -1;
|
||||
} else if (d2 < r) {
|
||||
// 圆内
|
||||
s = 1;
|
||||
} else {
|
||||
// 圆上
|
||||
s = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离,Point的x为纬度,y为经度
|
||||
*
|
||||
* @param point1
|
||||
* @param point2
|
||||
* @return
|
||||
*/
|
||||
public static double getDistance(Point point1, Point point2) {
|
||||
double lat1 = point1.getX();
|
||||
double lon1 = point1.getY();
|
||||
double lat2 = point2.getX();
|
||||
double lon2 = point2.getY();
|
||||
double x, y, a, b, distance;
|
||||
|
||||
lat1 *= RADIAN;
|
||||
lat2 *= RADIAN;
|
||||
x = lat1 - lat2;
|
||||
y = lon1 - lon2;
|
||||
y *= RADIAN;
|
||||
a = Math.sin(x * HALF);
|
||||
b = Math.sin(y * HALF);
|
||||
distance = EARTH_RADIUS * Math.asin(Math.sqrt(a * a + Math.cos(lat1) * Math.cos(lat2) * b * b)) / HALF;
|
||||
return new BigDecimal(distance).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算面积
|
||||
*
|
||||
* @param points
|
||||
* @return
|
||||
*/
|
||||
public static double getSqua(List<Point> points) {
|
||||
double area = 0;
|
||||
int size = points.size();
|
||||
if (size > 2) {
|
||||
double LowX = 0.0;
|
||||
double LowY = 0.0;
|
||||
double MiddleX = 0.0;
|
||||
double MiddleY = 0.0;
|
||||
double HighX = 0.0;
|
||||
double HighY = 0.0;
|
||||
|
||||
double AM = 0.0;
|
||||
double BM = 0.0;
|
||||
double CM = 0.0;
|
||||
|
||||
double AL = 0.0;
|
||||
double BL = 0.0;
|
||||
double CL = 0.0;
|
||||
|
||||
double AH = 0.0;
|
||||
double BH = 0.0;
|
||||
double CH = 0.0;
|
||||
|
||||
double CoefficientL = 0.0;
|
||||
double CoefficientH = 0.0;
|
||||
|
||||
double ALtangent = 0.0;
|
||||
double BLtangent = 0.0;
|
||||
double CLtangent = 0.0;
|
||||
|
||||
double AHtangent = 0.0;
|
||||
double BHtangent = 0.0;
|
||||
double CHtangent = 0.0;
|
||||
|
||||
double ANormalLine = 0.0;
|
||||
double BNormalLine = 0.0;
|
||||
double CNormalLine = 0.0;
|
||||
|
||||
double OrientationValue = 0.0;
|
||||
|
||||
double AngleCos = 0.0;
|
||||
|
||||
double Sum1 = 0.0;
|
||||
double Sum2 = 0.0;
|
||||
double Count2 = 0;
|
||||
double Count1 = 0;
|
||||
|
||||
double Sum = 0.0;
|
||||
double Radius = 6378000;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i == 0) {
|
||||
LowX = points.get(size - 1).getX() * Math.PI / 180;
|
||||
LowY = points.get(size - 1).getY() * Math.PI / 180;
|
||||
MiddleX = points.get(0).getX() * Math.PI / 180;
|
||||
MiddleY = points.get(0).getY() * Math.PI / 180;
|
||||
HighX = points.get(1).getX() * Math.PI / 180;
|
||||
HighY = points.get(1).getY() * Math.PI / 180;
|
||||
} else if (i == size - 1) {
|
||||
LowX = points.get(size - 2).getX() * Math.PI / 180;
|
||||
LowY = points.get(size - 2).getY() * Math.PI / 180;
|
||||
MiddleX = points.get(size - 1).getX() * Math.PI / 180;
|
||||
MiddleY = points.get(size - 1).getY() * Math.PI / 180;
|
||||
HighX = points.get(0).getX() * Math.PI / 180;
|
||||
HighY = points.get(0).getY() * Math.PI / 180;
|
||||
} else {
|
||||
LowX = points.get(i - 1).getX() * Math.PI / 180;
|
||||
LowY = points.get(i - 1).getY() * Math.PI / 180;
|
||||
MiddleX = points.get(i).getX() * Math.PI / 180;
|
||||
MiddleY = points.get(i).getY() * Math.PI / 180;
|
||||
HighX = points.get(i + 1).getX() * Math.PI / 180;
|
||||
HighY = points.get(i + 1).getY() * Math.PI / 180;
|
||||
}
|
||||
|
||||
AM = Math.cos(MiddleY) * Math.cos(MiddleX);
|
||||
BM = Math.cos(MiddleY) * Math.sin(MiddleX);
|
||||
CM = Math.sin(MiddleY);
|
||||
AL = Math.cos(LowY) * Math.cos(LowX);
|
||||
BL = Math.cos(LowY) * Math.sin(LowX);
|
||||
CL = Math.sin(LowY);
|
||||
AH = Math.cos(HighY) * Math.cos(HighX);
|
||||
BH = Math.cos(HighY) * Math.sin(HighX);
|
||||
CH = Math.sin(HighY);
|
||||
|
||||
CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
|
||||
CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);
|
||||
|
||||
ALtangent = CoefficientL * AL - AM;
|
||||
BLtangent = CoefficientL * BL - BM;
|
||||
CLtangent = CoefficientL * CL - CM;
|
||||
AHtangent = CoefficientH * AH - AM;
|
||||
BHtangent = CoefficientH * BH - BM;
|
||||
CHtangent = CoefficientH * CH - CM;
|
||||
|
||||
AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (
|
||||
Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent)
|
||||
* Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent
|
||||
+ CLtangent * CLtangent));
|
||||
|
||||
AngleCos = Math.acos(AngleCos);
|
||||
|
||||
ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
|
||||
BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
|
||||
CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;
|
||||
|
||||
if (AM != 0) {
|
||||
OrientationValue = ANormalLine / AM;
|
||||
} else if (BM != 0) {
|
||||
OrientationValue = BNormalLine / BM;
|
||||
} else {
|
||||
OrientationValue = CNormalLine / CM;
|
||||
}
|
||||
|
||||
if (OrientationValue > 0) {
|
||||
Sum1 += AngleCos;
|
||||
Count1++;
|
||||
|
||||
} else {
|
||||
Sum2 += AngleCos;
|
||||
Count2++;
|
||||
//Sum +=2*Math.PI-AngleCos;
|
||||
}
|
||||
}
|
||||
if (Sum1 > Sum2) {
|
||||
Sum = Sum1 + (2 * Math.PI * Count2 - Sum2);
|
||||
} else {
|
||||
Sum = (2 * Math.PI * Count1 - Sum1) + Sum2;
|
||||
}
|
||||
//平方米
|
||||
area = (Sum - (size - 2) * Math.PI) * Radius * Radius;
|
||||
}
|
||||
return Math.abs(area);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user