package com.persagy.dmp.rwd.basic.utils;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;


/**
 * @ClassName GeoToolsUtil
 * @Description: 点面包含关系分析
 * @Author linhuili
 * @Date 2021/9/3 20:31
 * @Version V1.0
 **/
public class GeoToolsUtil {
    /**
     * 创建点
     * @param pointLocal
     */
    private static Point createPoint(ObjectNode pointLocal){
        double x =0L;
        double y =0L;
        double z =0L;
        if(pointLocal.get("X") != null){
            x =pointLocal.get("X").doubleValue();
        }
        if(pointLocal.get("Y") != null){
            y = pointLocal.get("Y").doubleValue();
        }
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        Coordinate coord = new Coordinate(x, y,z);
        Point point = geometryFactory.createPoint(coord);
        return point;
    }

    /**
     * 创建面
     * @param outLines
     */
    private static Polygon createPolygon(List<LinkedHashMap<String,Object>> outLines){
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        List<Coordinate> objects = new ArrayList<>();
        for (LinkedHashMap<String,Object> outLine : outLines) {
            double x = Double.parseDouble(outLine.getOrDefault("X",0.0D).toString());
            double y = Double.parseDouble(outLine.getOrDefault("Y",0.0D).toString());
            double z = 0L;
            Coordinate coordinate = new Coordinate(x, y, z);
            objects.add(coordinate);
        }
        //注意数据的闭合
        Coordinate[] coordinates = objects.toArray(new Coordinate[0]);
        LinearRing ring = geometryFactory.createLinearRing(coordinates);
        Polygon polygon = geometryFactory.createPolygon(ring, null);

        return polygon;
   }

    /**
     * 点面包含关系判断
     * 用途：判断一个面是否包含一个点，即一个点是否在一个面内
     * @param pointLocal 坐标点
     * @param outLines 轮廓线
     * @return
     */
   public static Boolean isPointInPoly(ObjectNode pointLocal, List<LinkedHashMap<String,Object>> outLines) {
       if (null==pointLocal || CollUtil.isEmpty(outLines)){
           return false;
       }
       //创建点
       Point point = createPoint(pointLocal);
       //创建面
       Polygon polygon = createPolygon(outLines);
       //判断点面包含关系
       return polygon.contains(point);
   }
    /**
     * 点面包含关系判断
     * 用途：判断一个面是否包含一个点，即一个点是否在一个面内
     * @param fromOutLines: 轮廓坐标
     * @param toOutLines: 轮廓坐标
     * @return
     */
   public static Boolean isPolyInPoly(List<LinkedHashMap<String,Object>> fromOutLines,
                                       List<LinkedHashMap<String,Object>> toOutLines) {
       if (CollUtil.isEmpty(fromOutLines) || CollUtil.isEmpty(toOutLines)){
           return false;
       }
       //创建点
       Polygon fromPolygon = createPolygon(fromOutLines);
       //创建面
       Polygon toPolygon = createPolygon(toOutLines);
       //判断面-面包含关系
       return fromPolygon.contains(toPolygon)
               || fromPolygon.equalsTopo(toPolygon)
               || fromPolygon.overlaps(toPolygon)
               || toPolygon.contains(fromPolygon);
   }

}
