根据经纬度判断是否处在电子围栏内,电子围栏可分为 矩形围栏,圆形围栏、多边形围栏
/** * 地球半径 */ private static double EARTH_RADIUS = 6378138.0; private static double rad(double d) { return d * Math.PI / 180.0; } /** * 计算是否在圆上(单位/千米) * * @param radius 半径 * @param lat1 纬度 * @param lng1 经度 * @return double * @throws * @Title: GetDistance * @Description: TODO() */ public static boolean isInCircle(double radius, double lat1, double lng1, double lat2, double lng2) { 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 * 10000) / 10000; if (s > radius) {//不在圆上 return false; } else { return true; } } /** * 是否在矩形区域内 * * @param lat 测试点经度 * @param lng 测试点纬度 * @param minLat 纬度范围限制1 * @param maxLat 纬度范围限制2 * @param minLng 经度限制范围1 * @param maxLng 经度范围限制2 * @return boolean * @throws * @Title: isInArea * @Description: TODO() */ public static boolean isInRectangleArea(double lat, double lng, double minLat, double maxLat, double minLng, double maxLng) { if (isInRange(lat, minLat, maxLat)) {//如果在纬度的范围内 if (minLng * maxLng > 0) { if (isInRange(lng, minLng, maxLng)) { return true; } else { return false; } } else { if (Math.abs(minLng) + Math.abs(maxLng) < 180) { if (isInRange(lng, minLng, maxLng)) { return true; } else { return false; } } else { double left = Math.max(minLng, maxLng); double right = Math.min(minLng, maxLng); if (isInRange(lng, left, 180) || isInRange(lng, right, -180)) { return true; } else { return false; } } } } else { return false; } } /** * 判断是否在经纬度范围内 * * @param point * @param left * @param right * @return boolean * @throws * @Title: isInRange * @Description: TODO() */ public static boolean isInRange(double point, double left, double right) { if (point >= Math.min(left, right) && point <= Math.max(left, right)) { return true; } else { return false; } } /** * 判断点是否在多边形内 * * @param point 测试点 * @param pts 多边形的点 * @return boolean * @throws * @Title: IsPointInPoly * @Description: TODO() */ public static boolean isInPolygon(Point2D.Double point, List pts) { int N = pts.size(); boolean boundOrVertex = true; int intersectCount = 0;//交叉点数量 double precision = 2e-10; //浮点类型计算时候与0比较时候的容差 Point2D.Double p1, p2;//临近顶点 Point2D.Double p = point; //当前点 p1 = pts.get(0); for (int i = 1; i <= N; ++i) { if (p.equals(p1)) { return boundOrVertex; } p2 = pts.get(i % N); if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) { p1 = p2; continue; } //射线穿过算法 if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) { if (p.y = Math.min(p1.y, p2.y)) { return boundOrVertex; } if (p1.y == p2.y) { if (p1.y == p.y) { return boundOrVertex; } else { ++intersectCount; } } else { double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; if (Math.abs(p.y - xinters) < precision) { return boundOrVertex; } if (p.y < xinters) { ++intersectCount; } } } } else { if (p.x == p2.x && p.y = Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) { ++intersectCount; } else { intersectCount += 2; } } } p1 = p2; } if (intersectCount % 2 == 0) {//偶数在多边形外 return false; } else { //奇数在多边形内 return true; } }
转载自:https://www.cnblogs.com/songxiaotong/p/10852615.html