关于多个点位匹配多个区域,返回最匹配多个点位的区域

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);
    }
}

 

posted @ 2023-06-19 19:26  不想被举的栗子  阅读(12)  评论(0编辑  收藏  举报