package org.springblade.modules.attendance.util; import org.springblade.modules.attendance.entity.Attendance; import org.springblade.modules.enclosure.entity.Enclosure; import org.springblade.modules.enclosure.service.IEnclosureService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; /** * 判断当前坐标点是否在多边形区域内 * @author zhongrj * @time 2021--5-14 */ @Component public class PointMapUtil { public static PointMapUtil pointMapUtil; @Autowired private IEnclosureService iEnclosureService; @PostConstruct public void init(){ pointMapUtil=this; } public static void main(String[] args) { Attendance attendance = new Attendance(); attendance.setNumber("32165165"); attendance.setJd("114.9161"); attendance.setWd("25.85101"); Enclosure enclosure = new Enclosure(); enclosure.setAnumber(attendance.getNumber()); //查询当前处警人员的电子围栏信息 Enclosure enclosureDetail = pointMapUtil.iEnclosureService.selectEnclosureDetail(enclosure); //取出经纬度 Boolean onArea = PointMapUtil.isOnArea(Double.parseDouble(attendance.getJd()), Double.parseDouble(attendance.getWd()), enclosureDetail.getCoordinate()); System.out.println("onArea = " + onArea); } /** * 判断坐标点是否在多边形区域内 * @return */ public static Boolean isOnArea(Double x,Double y,String partitionLocation){ /** * 定义一个点 */ Point2D.Double point = new Point2D.Double(x, y); List pointList= new ArrayList(); //坐标数据处理 int i = partitionLocation.indexOf("("); int j = partitionLocation.indexOf(")"); String split = partitionLocation.substring(i+1, j); System.out.println("split = " + split); //读取多边形区域中的顶点 String[] strList = split.split(","); //遍历形成多边形区域的顶点 for (String str : strList){ String[] points = str.split(" "); System.out.println("points[0] = " + points[0]); System.out.println("points[1] = " + points[1]); double polygonPoint_x=Double.parseDouble(points[1]); double polygonPoint_y=Double.parseDouble(points[0]); Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y); pointList.add(polygonPoint); } return IsPtInPoly(point,pointList); } /** * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true * @param point 检测点 * @param pts 多边形的顶点 * @return 点在多边形内返回true,否则返回false */ public static boolean IsPtInPoly(Point2D.Double point, List pts){ int N = pts.size(); boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true int intersectCount = 0;//cross points count of x double precision = 2e-10; //浮点类型计算时候与0比较时候的容差 Point2D.Double p1, p2;//neighbour bound vertices Point2D.Double p = point; //当前点 p1 = pts.get(0);//left vertex for(int i = 1; i <= N; ++i){//check all rays if(p.equals(p1)){ return boundOrVertex;//p is an vertex } p2 = pts.get(i % N);//right vertex if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests p1 = p2; continue;//next ray left point } if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of) if(p.y <= Math.max(p1.y, p2.y)){//x is before of ray if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal ray return boundOrVertex; } if(p1.y == p2.y){//ray is vertical if(p1.y == p.y){//overlies on a vertical ray return boundOrVertex; }else{//before ray ++intersectCount; } }else{//cross point on the left side double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y if(Math.abs(p.y - xinters) < precision){//overlies on a ray return boundOrVertex; } if(p.y < xinters){//before ray ++intersectCount; } } } }else{//special case when ray is crossing through the vertex if(p.x == p2.x && p.y <= p2.y){//p crossing over p2 Point2D.Double p3 = pts.get((i+1) % N); //next vertex if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x ++intersectCount; }else{ intersectCount += 2; } } } p1 = p2;//next ray left point } if(intersectCount % 2 == 0){//偶数在多边形外 return false; } else { //奇数在多边形内 return true; } } /** * 返回一个点是否在一个多边形区域内, 如果点位于多边形的顶点或边上,不算做点在多边形内,返回false * @param point * @param polygon * @return */ public static boolean checkWithJdkGeneralPath(Point2D.Double point, List 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); } // public static boolean isPtInPoly (double ALon , double ALat , Point[] ps) { // int iSum, iCount, iIndex; // double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon; // if (ps.length < 3) { // return false; // } // iSum = 0; // iCount = ps.length; // for (iIndex = 0; iIndex= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) { // if (Math.abs(dLat1 - dLat2) > 0) { // //得到 A点向左射线与边的交点的x坐标: // dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat) ) / (dLat1 - dLat2); // // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一: // if (dLon < ALon) { // iSum++; // } // } // } // } // if ((iSum % 2) != 0) { // return true; // } // return false; // } }