package com.base.plan.utils;

import com.base.api.model.PointRpcDTO;
import com.base.plan.model.enums.PointTypeEnumes;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.operation.distance.DistanceOp;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class LaLonUtil {

    private static final double EARTH_RADIUS=6371000;//地球平均半径 单位米


    public static List<PointRpcDTO> draw(PointRpcDTO pointRpcDTOstart,PointRpcDTO pointRpcDTOend){
        List<PointRpcDTO> pointRpcDTOS=new ArrayList<>();
        List<PointRpcDTO> pointRpcDTOS2=new ArrayList<>();
        pointRpcDTOS2.add(pointRpcDTOstart);
        pointRpcDTOS2.add(pointRpcDTOend);
        double startLond=Double.valueOf(pointRpcDTOstart.getLongitude());
        double strLatd=Double.valueOf(pointRpcDTOstart.getLatitude());
        double endLond=Double.valueOf(pointRpcDTOend.getLongitude());
        double endLatd=Double.valueOf(pointRpcDTOend.getLatitude());
        double width = 4000; // 矩形的宽度
        // 计算矩形中心点的经纬度
        double centerLongitude = (startLond + endLond) / 2;
        double centerLatitude = (strLatd + endLatd) / 2;

        // 根据宽度和地球半径计算矩形在经度和纬度方向上的偏移量
        double offsetLongitude = width / (2 * Math.cos(Math.toRadians(centerLatitude))) / 111000; // 经度方向上的偏移量（单位：米）
        double offsetLatitude = width / 111000; // 纬度方向上的偏移量（单位：米）

        // 根据中心点和偏移量计算矩形四个顶点的经纬度坐标
        Coordinate corner1 = new Coordinate(centerLongitude - offsetLongitude, centerLatitude - offsetLatitude);
        Coordinate corner2 = new Coordinate(centerLongitude + offsetLongitude, centerLatitude - offsetLatitude);
        Coordinate corner3 = new Coordinate(centerLongitude + offsetLongitude, centerLatitude + offsetLatitude);
        Coordinate corner4 = new Coordinate(centerLongitude - offsetLongitude, centerLatitude + offsetLatitude);
        PointRpcDTO pointRpcDTO1=new PointRpcDTO();
        pointRpcDTO1.setSort("1");
        pointRpcDTO1.setSerial("1");
        pointRpcDTO1.setLongitude(String.valueOf(corner1.x));
        pointRpcDTO1.setLatitude(String.valueOf(corner1.y));
        pointRpcDTO1.setPointType("TARGET");
        pointRpcDTO1.setTargetType(PointTypeEnumes.LINE.toString());
        pointRpcDTO1.setPointRpcDTOS(pointRpcDTOS2);
        pointRpcDTOS.add(pointRpcDTO1);

        PointRpcDTO pointRpcDTO2=new PointRpcDTO();
        pointRpcDTO2.setSort("1");
        pointRpcDTO2.setSerial("1");
        pointRpcDTO2.setLongitude(String.valueOf(corner2.x));
        pointRpcDTO2.setLatitude(String.valueOf(corner2.y));
        pointRpcDTO2.setPointType("TARGET");
        pointRpcDTO2.setTargetType(PointTypeEnumes.LINE.toString());
        pointRpcDTO2.setPointRpcDTOS(pointRpcDTOS2);
        pointRpcDTOS.add(pointRpcDTO2);

        PointRpcDTO pointRpcDTO3=new PointRpcDTO();
        pointRpcDTO3.setSort("1");
        pointRpcDTO3.setSerial("1");
        pointRpcDTO3.setLongitude(String.valueOf(corner3.x));
        pointRpcDTO3.setLatitude(String.valueOf(corner3.y));
        pointRpcDTO3.setPointType("TARGET");
        pointRpcDTO3.setTargetType(PointTypeEnumes.LINE.toString());
        pointRpcDTO3.setPointRpcDTOS(pointRpcDTOS2);
        pointRpcDTOS.add(pointRpcDTO3);

        PointRpcDTO pointRpcDTO4=new PointRpcDTO();
        pointRpcDTO4.setSort("1");
        pointRpcDTO4.setSerial("1");
        pointRpcDTO4.setLongitude(String.valueOf(corner4.x));
        pointRpcDTO4.setLatitude(String.valueOf(corner4.y));
        pointRpcDTO4.setPointType("TARGET");
        pointRpcDTO4.setTargetType(PointTypeEnumes.LINE.toString());
        pointRpcDTO4.setPointRpcDTOS(pointRpcDTOS2);
        pointRpcDTOS.add(pointRpcDTO4);
        System.out.println("左上角坐标：" + "[" + corner1.x + ", " +corner1.y + "]");
        System.out.println("右上角坐标：" + "[" + corner2.x + ", " + corner2.y + "]");
        System.out.println("右下角坐标：" + "[" + corner3.x + ", " + corner3.y + "]");
        System.out.println("左下角坐标：" + "[" + corner4.x + ", " + corner4.y + "]");
        return pointRpcDTOS;
    }

    public static PointRpcDTO deadReckoning(String startlon ,String startlat,String speed,String time,String heading){
        double startlond=Double.valueOf(startlon);
        double startlatd=Double.valueOf(startlat);
        double speedd=Double.valueOf(speed); //公里每小时
        double timed=Double.valueOf(time);//小时
        double headingd=Double.valueOf(heading);//航向 度

/*        double deltaLat = calculateDeltaLat(speedd, timed, headingd, startlatd);
        double deltaLon = calculateDeltaLon(speedd, timed, headingd, startlond);

        double nextLatitude = deltaLat + deltaLat;
        double nextLongitude = deltaLon + deltaLon;*/

        double distance = speedd * timed; // 计算距离，单位可以是米或者千米
        double nextLatitude = startlatd + distance * Math.sin(Math.toRadians(headingd));
        double nextLongitude = startlond + distance * Math.cos(Math.toRadians(headingd)) / Math.cos(Math.toRadians(startlatd));


/*        BigDecimal nextLongitudeb = new BigDecimal(nextLongitude);
        nextLongitudeb.setScale(6,BigDecimal.ROUND_HALF_UP);*/
        String nextLongituden =String.format("%.6f",nextLongitude);

/*        BigDecimal nextLatitudeb = new BigDecimal(nextLatitude);
        nextLatitudeb.setScale(6, BigDecimal.ROUND_HALF_UP);*/
        /*String nextLatituden = nextLatitudeb.toPlainString();*/
        String nextLatituden = String.format("%.6f",nextLatitude);



        PointRpcDTO pointRpcDTO=new PointRpcDTO();
        pointRpcDTO.setLongitude(nextLongituden);
        pointRpcDTO.setLatitude(nextLatituden);
        System.out.println("下一个点的经纬度是: " + nextLatituden + ", " + nextLongituden);

        return pointRpcDTO;
    }

    public static double calculateDeltaLat(double speed, double time, double heading, double currentLatitude) {
        double radianHeading = Math.toRadians(heading);
        return speed * time * Math.cos(Math.toRadians(currentLatitude)) / (40075 * Math.cos(radianHeading));
    }

    public static double calculateDeltaLon(double speed, double time, double heading, double currentLongitude) {
        double radianHeading = Math.toRadians(heading);
        return speed * time / (40075 * Math.cos(radianHeading));
    }

    public  static double countdistance(double lat1,double lon1,double lat2,double lon2){
        double radLat1 = Math.toRadians(lat1);
        double radLon1 = Math.toRadians(lon1);
        double radLat2 = Math.toRadians(lat2);
        double radLon2 = Math.toRadians(lon2);

        double a = Math.sin((radLat2-radLat1)/2) * Math.sin((radLat2-radLat1)/2) +
                Math.cos(radLat1) * Math.cos(radLat2) *
                        Math.sin((radLon2-radLon1)/2) * Math.sin((radLon2-radLon1)/2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        double distanceInKilometers = EARTH_RADIUS * c;

        return distanceInKilometers;
    }

    public static List<PointRpcDTO> getregion(List<PointRpcDTO> pointRpcDTOS){
        List<PointRpcDTO> pointRpcDTOList=new ArrayList<>();
        // 初始化最大和最小经纬度值
        double maxLongitude = Double.NEGATIVE_INFINITY;
        double minLongitude = Double.POSITIVE_INFINITY;
        double maxLatitude = Double.NEGATIVE_INFINITY;
        double minLatitude = Double.POSITIVE_INFINITY;

        // 遍历经纬度点找出最大和最小经纬度
        for (PointRpcDTO point : pointRpcDTOS) {
            if (Double.valueOf(point.getLongitude()) > maxLongitude) {
                maxLongitude = Double.valueOf(point.getLongitude());
            }
            if (Double.valueOf(point.getLongitude()) < minLongitude) {
                minLongitude = Double.valueOf(point.getLongitude());
            }
            if (Double.valueOf(point.getLatitude())> maxLatitude) {
                maxLatitude = Double.valueOf(point.getLatitude());
            }
            if (Double.valueOf(point.getLatitude())< minLatitude) {
                minLatitude = Double.valueOf(point.getLatitude());
            }
        }

        // 输出外接矩形四个点的坐标
        System.out.println("左上角点坐标：" + maxLongitude + ", " + maxLatitude);
        System.out.println("右上角点坐标：" + maxLongitude + ", " + minLatitude);
        System.out.println("左下角点坐标：" + minLongitude + ", " + maxLatitude);
        System.out.println("右下角点坐标：" + minLongitude + ", " + minLatitude);
        PointRpcDTO pointRpcDTO1=new PointRpcDTO();
        pointRpcDTO1.setSort("1");
        pointRpcDTO1.setSerial("1");
        pointRpcDTO1.setLongitude(String.valueOf(maxLongitude));
        pointRpcDTO1.setLatitude(String.valueOf(maxLatitude));
        pointRpcDTO1.setPointType("TARGET");
        pointRpcDTO1.setTargetType(PointTypeEnumes.GROUPPOINT.toString());
        pointRpcDTO1.setPointRpcDTOS(pointRpcDTOS);
        pointRpcDTOList.add(pointRpcDTO1);

        PointRpcDTO pointRpcDTO2=new PointRpcDTO();
        pointRpcDTO2.setSort("1");
        pointRpcDTO2.setSerial("1");
        pointRpcDTO2.setLongitude(String.valueOf(maxLongitude));
        pointRpcDTO2.setLatitude(String.valueOf(minLatitude));
        pointRpcDTO2.setPointType("TARGET");
        pointRpcDTO2.setTargetType(PointTypeEnumes.GROUPPOINT.toString());
        pointRpcDTO2.setPointRpcDTOS(pointRpcDTOS);
        pointRpcDTOList.add(pointRpcDTO2);

        PointRpcDTO pointRpcDTO3=new PointRpcDTO();
        pointRpcDTO3.setSort("1");
        pointRpcDTO3.setSerial("1");
        pointRpcDTO3.setLongitude(String.valueOf(minLongitude));
        pointRpcDTO3.setLatitude(String.valueOf(minLatitude));
        pointRpcDTO3.setPointType("TARGET");
        pointRpcDTO3.setTargetType(PointTypeEnumes.GROUPPOINT.toString());
        pointRpcDTO3.setPointRpcDTOS(pointRpcDTOS);
        pointRpcDTOList.add(pointRpcDTO3);

        PointRpcDTO pointRpcDTO4=new PointRpcDTO();
        pointRpcDTO4.setSort("1");
        pointRpcDTO4.setSerial("1");
        pointRpcDTO4.setLongitude(String.valueOf(minLongitude));
        pointRpcDTO4.setLatitude(String.valueOf(maxLatitude));
        pointRpcDTO4.setPointType("TARGET");
        pointRpcDTO4.setTargetType(PointTypeEnumes.GROUPPOINT.toString());
        pointRpcDTO4.setPointRpcDTOS(pointRpcDTOS);
        pointRpcDTOList.add(pointRpcDTO4);

        return pointRpcDTOList;
    }

    public static boolean pointInRectangle(PointRpcDTO p,List<PointRpcDTO> pointRpcDTOSstrip){
        // 创建点对象
        Coordinate pointCoord = new Coordinate(Double.valueOf(p.getLongitude()), Double.valueOf(p.getLatitude())); // 经度和纬度

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        Point point = geometryFactory.createPoint(pointCoord);

        // 创建矩形区域对象
        PointRpcDTO p0=pointRpcDTOSstrip.get(0);
        PointRpcDTO p1=pointRpcDTOSstrip.get(1);
        PointRpcDTO p2=pointRpcDTOSstrip.get(2);
        PointRpcDTO p3=pointRpcDTOSstrip.get(3);
        Coordinate[] rectangleCoords = new Coordinate[]{
                new Coordinate(Double.valueOf(p0.getLongitude()), Double.valueOf(p0.getLatitude())), // 左上角坐标
                new Coordinate(Double.valueOf(p1.getLongitude()), Double.valueOf(p1.getLatitude())), // 右上角坐标
                new Coordinate(Double.valueOf(p2.getLongitude()), Double.valueOf(p2.getLatitude())), // 右下角坐标
                new Coordinate(Double.valueOf(p3.getLongitude()), Double.valueOf(p3.getLatitude())), // 左下角坐标
                new Coordinate(Double.valueOf(p0.getLongitude()), Double.valueOf(p0.getLatitude()))
        };
        Polygon rectangle = geometryFactory.createPolygon(rectangleCoords);

        // 判断点是否在矩形区域内
        boolean isInside = rectangle.contains(point);

        System.out.println("点是否在矩形区域内：" + isInside);
        return isInside;
    }

    public static double pointToLineSegment(PointRpcDTO p,PointRpcDTO p1,PointRpcDTO p2){
/*        GeometryFactory geometryFactory=new GeometryFactory();
        Point point=geometryFactory.createPoint(new Coordinate(Double.valueOf(p.getLongitude()), Double.valueOf(p.getLatitude())));
        LineString lineString=geometryFactory.createLineString(
                new Coordinate[]{new Coordinate(Double.valueOf(p1.getLongitude()), Double.valueOf(p1.getLatitude())),
                new Coordinate(Double.valueOf(p2.getLongitude()), Double.valueOf(p2.getLatitude()))}
        );
        double distance = point.distance(lineString);*/
        // 创建点对象
        Coordinate pointCoord = new Coordinate(Double.valueOf(p.getLongitude()), Double.valueOf(p.getLatitude()));
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        Point point = geometryFactory.createPoint(pointCoord);

        // 创建线段对象
        Coordinate lineStartCoord = new Coordinate(Double.valueOf(p1.getLongitude()), Double.valueOf(p1.getLatitude()));
        Coordinate lineEndCoord = new Coordinate(Double.valueOf(p2.getLongitude()), Double.valueOf(p2.getLatitude()));
        LineString line = geometryFactory.createLineString(new Coordinate[]{lineStartCoord, lineEndCoord});

        // 计算点到线段的最近距离
        double distance = DistanceOp.distance(point, line);

        System.out.println("点到线段的距离为米：" + distance);
        return distance;
    }

}
