package com.xiaopeng.map.utils; import java.util.ArrayList; import java.util.List; /** * 电子围栏工具类 */ public class ElectricFenceUtil { /** * * @param coordinate 电子围栏 20,20:30,20 * @param locations 当前点位 * @return */ public static boolean monitorElectricFenc(String coordinate, String locations){ return areaMonitoring(coordinate, locations); } public static boolean areaMonitoring(String coordinate, String lonLat){ boolean flag = false; String[] split = coordinate.split(";"); List pointsX = new ArrayList<>(); List pointsY = new ArrayList<>(); for (String s : split) { pointsX.add(Double.valueOf(s.split(",")[0])); pointsY.add(Double.valueOf(s.split(",")[1])); } String lon1 = lonLat.split(",")[0]; String lat1 = lonLat.split(",")[1]; boolean inPolygon = isInPolygon(Double.valueOf(lon1), Double.valueOf(lat1), pointsX, pointsY); if (inPolygon){ flag = true; } return flag; } public static void main(String[] args) { boolean b = areaMonitoring("30.58735942193454,104.05487026416449;30.585448836687142,104.05417932370085;30.584709825825247,104.05798996498686;30.589414160478096,104.0595184091195;30.58735942193454,104.05487026416449", "30.586574495742138,104.0564187068153"); System.out.println(b); } /** // * 判断点是否在多边形内 // * @param px 测试点 // * @param polygonXA 多边形的点 // * @return boolean true:在多边形内, false:在多边形外 // * @throws // * @Title: IsPointInPoly // */ public static boolean isInPolygon(double px, double py,List polygonXA, List polygonYA) { boolean isInside = false; double ESP = 1e-9; int count = 0; double linePoint1x; double linePoint1y; double linePoint2x = 180; double linePoint2y; linePoint1x = px; linePoint1y = py; linePoint2y = py; for (int i = 0; i < polygonXA.size() - 1; i++) { double cx1 = polygonXA.get(i); double cy1 = polygonYA.get(i); double cx2 = polygonXA.get(i + 1); double cy2 = polygonYA.get(i + 1); if (isPointOnLine(px, py, cx1, cy1, cx2, cy2)) { return true; } if (Math.abs(cy2 - cy1) < ESP) { continue; } if (isPointOnLine(cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) { if (cy1 > cy2) count++; } else if (isPointOnLine(cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) { if (cy2 > cy1) count++; } else if (isIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) { count++; } } if (count % 2 == 1) { isInside = true; } return isInside; } 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)); } 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 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; } }