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