public class MapsUtil {
private static double EARTH_RADIUS = 6378.137;//地球半径
/**
* 求两点之间的距离(km)
*
* @param lng1 A点经度
* @param lat1 A点纬度
* @param lng2 B点经度
* @param lat2 B点纬度
* @return 两点距离
*/
public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
double EARTH_RADIUS = 6371;
// A经弧度
double radiansAX = Math.toRadians(lng1);
// A纬弧度
double radiansAY = Math.toRadians(lat1);
// B经弧度
double radiansBX = Math.toRadians(lng2);
// B纬弧度
double radiansBY = Math.toRadians(lat2);
// 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
+ Math.sin(radiansAY) * Math.sin(radiansBY);
// 反余弦值
double acos = Math.acos(cos);
// 最终结果
return EARTH_RADIUS * acos;
}
private static double rad(double d) {
return d * Math.PI / 180.0;
}
public static double getDistanceNew(double lng1, double lat1, double lng2, double lat2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+ Math.cos(radLat1) * Math.cos(radLat2)
* Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.round(s * 10000d) / 10000d;
s = s * 1000;
return s;
}
@Data
public class Point {
double num1, num2;
}
/**
* 是否有 横断<br/> 参数为四个点的坐标
*
* @param px1
* @param py1
* @param px2
* @param py2
* @param px3
* @param py3
* @param px4
* @param py4
* @return
*/
public static boolean isIntersect(double px1, double py1, double px2, double py2,
double px3, double py3, double px4, double py4) {
boolean flag = false;
double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
if (d != 0) {
double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3))
/ d;
double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1))
/ d;
if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1)) {
flag = true;
}
}
return flag;
}
/**
* 判断是否在多边形区域内
*/
public static boolean isPointInPolygon(double px, double py, List<MapPoint> points) {
// 将要判断的横纵坐标组成一个点
Point2D.Double point = new Point2D.Double(px, py);
// 将区域各顶点的横纵坐标放到一个点集合里面
List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
double polygonPoint_x = 0.0, polygonPoint_y = 0.0;
for (int i = 0; i < points.size() - 1; i++) {
MapPoint mapPoint = points.get(i);
polygonPoint_x = mapPoint.getLng();
polygonPoint_y = mapPoint.getLat();
Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x, polygonPoint_y);
pointList.add(polygonPoint);
}
return check(point, pointList);
}
/**
* 目标点是否在目标边上边上<br/>
*
* @param px0 目标点的经度坐标
* @param py0 目标点的纬度坐标
* @param px1 目标线的起点(终点)经度坐标
* @param py1 目标线的起点(终点)纬度坐标
* @param px2 目标线的终点(起点)经度坐标
* @param py2 目标线的终点(起点)纬度坐标
* @return
*/
public static boolean isPointOnLine(double px0, double py0, double px1,
double py1, double px2, double py2) {
boolean flag = false;
// 无限小的正数
double ESP = 1e-9;
if ((Math.abs(Multiply(px0, py0, px1, py1, px2, py2)) < ESP)
&& ((px0 - px1) * (px0 - px2) <= 0)
&& ((py0 - py1) * (py0 - py2) <= 0)) {
flag = true;
}
return flag;
}
public static double Multiply(double px0, double py0, double px1, double py1,
double px2, double py2) {
return ((px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0));
}
/**
* 一个点是否在多边形内
*
* @param point 要判断的点的横纵坐标
* @param polygon 组成的顶点坐标集合
* @return
*/
private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();
Point2D.Double first = polygon.get(0);
// 通过移动到指定坐标(以双精度指定),将一个点添加到路径中
peneralPath.moveTo(first.x, first.y);
polygon.remove(0);
for (Point2D.Double d : polygon) {
// 通过绘制一条从当前坐标到新指定坐标(以双精度指定)的直线,将一个点添加到路径中。
peneralPath.lineTo(d.x, d.y);
}
// 将几何多边形封闭
peneralPath.lineTo(first.x, first.y);
peneralPath.closePath();
// 测试指定的 Point2D 是否在 Shape 的边界内。
return peneralPath.contains(point);
}
}