关于多个点位匹配多个区域,返回最匹配多个点位的区域
package com.dji.sample.common.util; import com.dji.sample.hzsk.model.entity.Area; import com.dji.sample.hzsk.model.entity.WaylinePoint; import org.springframework.util.CollectionUtils; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.*; import java.util.stream.Collectors;
/**
* 格式:points:119.962359_30.271619,119.962638_30.271179,119.963002_30.271721,119.963228_30.271271
*/
@Data @Builder @AllArgsConstructor @NoArgsConstructor public class Area { String id; String name; String points; } @Data @Builder @AllArgsConstructor @NoArgsConstructor public class WaylinePoint { String longitude; String latitude; }
/** * @author xiong * @date 2023/6/12 14:57 */ public class GetAreaUtil { /** * 获取匹配航线中飞行器坐标最多的area对象 */ public static Area getMostFrequentArea(List<WaylinePoint> waylinePoints, List<Area> areas) { Map<Area, Integer> areaCountMap = new HashMap<>(); // 未进行飞行 直接 返回未分配标识的area对象 if(CollectionUtils.isEmpty(waylinePoints)){ return new Area("0","未分配",""); } for (Area area : areas) { int count = (int) waylinePoints.stream() .filter(waylinePoint -> isInPolygon(waylinePoint.getLongitude(), waylinePoint.getLatitude(), area.getPoints())) .count(); areaCountMap.put(area, count); } Map.Entry<Area, Integer> max = Collections.max(areaCountMap.entrySet(), Map.Entry.comparingByValue()); if(max.getValue() == 0){ return new Area("0","未分配",""); } return max.getKey(); } /** * @param waylinePoints * @param areas * @return */ public static Area getResult(List<WaylinePoint> waylinePoints, List<Area> areas){ List<Area> collect = areas.stream().filter(area -> { return waylinePoints.stream().anyMatch(waylinePoint -> isInPolygon(waylinePoint.getLongitude(), waylinePoint.getLatitude(), area.getPoints())); }).collect(Collectors.toList()); return collect.get(0); } public static boolean isInPolygon(String x,String y,String partitionLocation){ double pX =Double.parseDouble(x); double pY =Double.parseDouble(y); Point2D.Double point = new Point2D.Double(pX, pY); List<Point2D.Double> pointList= new ArrayList<Point2D.Double>(); String[] strList = partitionLocation.split(","); for (String str : strList){ String[] points = str.split("_"); double polygonPointX =Double.parseDouble(points[0]); double polygonPointY =Double.parseDouble(points[1]); Point2D.Double polygonPoint = new Point2D.Double(polygonPointX,polygonPointY); pointList.add(polygonPoint); } return isPtInPoly(point,pointList); } /** * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true * @param point 检测点 * @param pts 多边形的顶点 * @return 点在多边形内返回true,否则返回false */ public static boolean isPtInPoly(Point2D.Double point, List<Point2D.Double> pts) { // 创建多边形路径 Path2D.Double path = new Path2D.Double(); Point2D.Double firstPoint = pts.get(0); path.moveTo(firstPoint.getX(), firstPoint.getY()); for (int i = 1; i < pts.size(); i++) { Point2D.Double currentPoint = pts.get(i); path.lineTo(currentPoint.getX(), currentPoint.getY()); } path.closePath(); // 创建区域对象 java.awt.geom.Area area = new java.awt.geom.Area(path); // 判断点是否在区域内部 return area.contains(point); } }