MapTools

MapTools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
* 地球半径,单位千米
*/
private static final double EARTH_RADIUS = 6378.137;

/** 180° **/
private static final DecimalFormat df = new DecimalFormat("0.000000");

public static boolean checkWithPath(Float myLong, Float myLati, Float[] areaLongitude, Float[] areaLatitude) {
Point2D.Double myPosition = new Point2D.Double(myLong, myLati);
List<Point2D.Double> areaBoundaryList = new ArrayList<>();
for (int i = 0; i < areaLatitude.length; i++) {
Point2D.Double areaBoundary = new Point2D.Double(areaLongitude[i], areaLatitude[i]);
areaBoundaryList.add(areaBoundary);
}
return checkWithPath(myPosition, areaBoundaryList);
}

private static boolean checkWithPath(Point2D.Double point, List<Point2D.Double> polygon) {
GeneralPath p = new GeneralPath();
Point2D.Double first = polygon.get(0);
p.moveTo(first.x, first.y);
for (Point2D.Double d : polygon) {
p.lineTo(d.x, d.y);
}
p.lineTo(first.x, first.y);
p.closePath();
return p.contains(point);
}

private static double rad(double d) {
return d * Math.PI / 180.0;
}

/**
* @param latitude1
* @param longitude1
* @param latitude2
* @param longitude2
* @return
*/
public static double getDistance(double latitude1, double longitude1, double latitude2, double longitude2) {
// 纬度
double Lat1 = rad(latitude1);
double Lat2 = rad(latitude2);
//两点纬度之差
double a = Lat1 - Lat2;
//经度之差
double b = rad(longitude1) - rad(longitude2);
//计算两点距离的公式
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(Lat1) * Math.cos(Lat2) * Math.pow(Math.sin(b / 2), 2)));
//弧长乘地球半径(半径为米)
s = s * 6378137.0;
//精确距离的数值
s = Math.round(s * 10000d) / 10000d;
return s;

}

/**
* 通过GPS的list算出距离
*
* @param
* @return
*/
public static Double getTotalDistance(List<DistanceBO> distanceBOS) {

//每两个点之间的set集合
Set<Double> distance = new HashSet<>();
for (int i = 0; i < distanceBOS.size()-1; i++) {
Double singleDistance=getDistance(distanceBOS.get(i).getLatitude(),
distanceBOS.get(i).getLongitude(),
distanceBOS.get(i+1).getLatitude(),
distanceBOS.get(i+1).getLongitude());
distance.add(singleDistance);
}
//算出距离
Double totalDistance = distance.stream().mapToDouble(Double::doubleValue).sum();
return totalDistance;
}


/**
* 判断一个点是否在圆形区域内
*/
public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, String radius) {
return getDistance(lat1, lng1, lat2, lng2) > Double.parseDouble(radius);
}
/**
* 判断当前位置是否在围栏内
* @param mobilelocationEntity -- 位置信息类 包含经度纬度
* @param enclosureList -- 围栏类 每一个对象是形成多边形围栏的一个点 包含经度纬度
* @return
*/
public static boolean isInPolygon(DistanceBO mobilelocationEntity,List<DistanceBO> enclosureList){
double p_x = mobilelocationEntity.getLongitude();
double p_y = mobilelocationEntity.getLatitude();
Point2D.Double point = new Point2D.Double(p_x, p_y);

List<Point2D.Double> pointList= new ArrayList<Point2D.Double>();

for (DistanceBO distanceBO : enclosureList){
double polygonPoint_x = distanceBO.getLongitude();
double polygonPoint_y = distanceBO.getLatitude();
Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y);
pointList.add(polygonPoint);
}
return checkWithJdkGeneralPath(point,pointList);
}

/**
* 返回一个点是否在一个多边形区域内
* @param point
* @param polygon
* @return
*/
private static boolean checkWithJdkGeneralPath(Point2D.Double point, List<Point2D.Double> polygon) {
java.awt.geom.GeneralPath p = new java.awt.geom.GeneralPath();

Point2D.Double first = polygon.get(0);
p.moveTo(first.x, first.y);
polygon.remove(0);
for (Point2D.Double d : polygon) {
p.lineTo(d.x, d.y);
}

p.lineTo(first.x, first.y);

p.closePath();

return p.contains(point);

}

/**
* 根据一点的坐标与距离,以及方向,计算另外一点的位置
* @param angle 角度,从正北顺时针方向开始计算
* @param startLong 起始点经度
* @param startLat 起始点纬度
* @param distance 距离,单位 km
* @return
*/
public static DistanceBO getOneSixthCircles(double angle, double startLong, double startLat, double distance){
DistanceBO bo = new DistanceBO();
//将距离转换成经度的计算公式
double δ = distance/EARTH_RADIUS;
// 转换为radian,否则结果会不正确
angle = Math.toRadians(angle);
startLong = Math.toRadians(startLong);
startLat = Math.toRadians(startLat);
double lat = Math.asin(Math.sin(startLat)*Math.cos(δ)+Math.cos(startLat)*Math.sin(δ)*Math.cos(angle));
double lon = startLong + Math.atan2(Math.sin(angle)*Math.sin(δ)*Math.cos(startLat),Math.cos(δ)-Math.sin(startLat)*Math.sin(lat));
// 转为正常的10进制经纬度
lon = Math.toDegrees(lon);
lat = Math.toDegrees(lat);
bo.setLongitude(lon);
bo.setLatitude(lat);
return bo;
}

public static void main(String[] args) {
double angle = 60;
double startLong = 116.442774;
double startLat = 39.977867;
double distance = 1.732;
getOneSixthCircles(angle, startLong, startLat, distance);
System.out.println(MapTool.getDistance(22.75424, 112.76535, 23.014171, 113.10111));
}