package com.base.core.config;


import com.base.core.utiles.AstroConst;
import lombok.Data;

/**
 * 成像卫星访问计算约束条件
 *
 * @author cxl
 */
@Data
public class ElectronImageLimitation {

    public final static String SHAPE_FOV_LINE = "LINE";
    public final static String SHAPE_FOV_SQURE = "SQURE";
    public final static String SHAPE_FOV_CIRCLE = "CIRCLE";
    private double minSunDegree;//弧度
    private double maxRollDegree;
    private double minRollDegree;

    //	/**
//	 * 轨道倾角
//	 */
//	private double inclination;
    private double maxPitchDegree;
    private double minPitchDegree;
    /**
     * 最大视场角
     */
    private double maxConeAngle;
    /**
     * 轨道高度
     */
    private double altitude;
    /**
     * 传感器类型，0:CCD, 1:SRA, 2:可见光, 3:红外, 4:高光谱, 5:可见光/红外/高光谱三合一
     */
    private int sensorType;
    /**
     * 访问时刻向后跳下小的长度，太阳同步可见光6A-1,6,10:22小时，太阳同步SAR5,7:10小时，太阳同步宽幅可见光9:1.5小时
     * timeStep与卫星侧摆能力和传感器幅宽有关，上述数值是考虑现有型号卫星能力得到
     */
    private double timeStep;
    /**
     * 轨道计算步长，单位：秒
     */
    private int stepLength = 1;
    /**
     * 访问时刻向后跳点的长度，根据timeStep, stepLength计算
     *///重放周期
    private long stepSpan;
    /**
     * 星下点距离目标多远可以开始成像计算的门限，单位：KM
     */
    private double maxDistance_to_shot;
    /**
     * 星下点距离目标多远可以开始对地面站可视计算的门限，单位：KM
     */
    private double maxDistance_to_stationView;
    //幅宽
    private double swath_rad;
    /**
     * 因相机光轴相对卫星本体坐标系Z轴沿飞行方向安装偏差导致的俯仰计算和访问计算偏置时间，沿飞行方向正向偏置为正，单位：秒
     */
    private long xSpan;
    /**
     * 因相机光轴相对卫星本体坐标系Z轴沿飞行方向安装偏差导致的俯仰角计算偏置角度，沿飞行方向前为正，单位：角度
     */
    private double xDrift;
    /**
     * 因相机光轴相对卫星本体坐标系Z轴沿飞行方向安装偏差导致的滚动角计算偏置角度，沿飞行方向右为正，单位：角度
     */
    private double yDrift;
    private String satName;
    /**
     * 升降轨成像标识，0：降轨成像，1：升轨成像，2：成像与升降轨无关
     */
    private int imageSign;
    /**
     * 判断能否访问的纬度条件
     */
    private double latLimit;
    private float swathInKM;
    private int minAccessDuration = 14;//最短成像时间16秒
    private int maxAccessDuration = 600;//最长成像时间600秒
    private String shapeOfFOV = "LINE";
    private int agilesat_pitch_inerval = 10;//敏捷卫星俯仰间隔10秒

    private double default_point_distance = 1;//拆分区域目标时默认点间距1度gaoyue20190625edit

    public ElectronImageLimitation() {
        // TODO Auto-generated constructor stub
    }

    public ElectronImageLimitation(ElectronImageLimitation imageLimitation) {
//		BeanUtils.copyProperties(imageLimitation, this);
    }

    public static ElectronImageLimitation getSampleImageLimit() {
        ElectronImageLimitation imageLimitation = new ElectronImageLimitation();
        imageLimitation.setMinSunDegree(1.0d);
        imageLimitation.setMaxRollDegree(60.0f);
        imageLimitation.setMinRollDegree(-60.0f);
//		imageLimitation.setInclination(97.4622f);
        imageLimitation.setAltitude(499.8968d);
        imageLimitation.setTimeStep(1.0);
        imageLimitation.setStepSpan(8 * 60 * 60);
        imageLimitation.setStepLength(1);
        imageLimitation.setSensorType(1);
        imageLimitation.setXDrift(0);
        imageLimitation.setYDrift(0);
        imageLimitation.setSatName("xxx");
        imageLimitation.setImageSign(0);
        imageLimitation.setLatLimit(3.0);
        imageLimitation.setMaxPitchDegree(45);
        imageLimitation.setMinPitchDegree(-45);
        imageLimitation.setXSpan(0);
        imageLimitation.setSwathInKM(24);
        imageLimitation.setAgilesat_pitch_inerval(1);

        double R = AstroConst.R_Earth / 1000;
        double altitude = imageLimitation.getAltitude();
        double theta = Math.acos(R / (R + altitude));
        double distance_km_to_stationView = theta * R + imageLimitation.getSwathInKM();
        double maxRollAngle = imageLimitation.getMaxRollDegree();
        double n = 1 + altitude / R;
        double a_rad = -Math.toRadians(maxRollAngle) + Math.asin(n * Math.sin(Math.toRadians(maxRollAngle)));
        double distance_km_to_shot = a_rad * R + imageLimitation.getSwathInKM();

        imageLimitation.setMaxDistance_to_shot(distance_km_to_shot);
//		imageLimitation.setSwath_rad(60d);
        return imageLimitation;
    }

    public static ElectronImageLimitation getSampleSudanImageLimit() {
        ElectronImageLimitation imageLimitation = new ElectronImageLimitation();
        imageLimitation.setMinSunDegree(1.0d);
        imageLimitation.setMaxRollDegree(40.0f);
        imageLimitation.setMinRollDegree(-40.0f);
//		imageLimitation.setInclination(97.4622f);
        imageLimitation.setAltitude(522);
        imageLimitation.setTimeStep(1.0);
        imageLimitation.setShapeOfFOV(SHAPE_FOV_SQURE);
        imageLimitation.setStepSpan(8 * 60 * 60);
        imageLimitation.setStepLength(1);
        imageLimitation.setSensorType(1);
        imageLimitation.setXDrift(0);
        imageLimitation.setYDrift(0);
        imageLimitation.setSatName("sudan-1");
        imageLimitation.setImageSign(0);
        imageLimitation.setLatLimit(3.0);
        imageLimitation.setMaxPitchDegree(45);
        imageLimitation.setMinPitchDegree(-45);
        imageLimitation.setXSpan(0);
        imageLimitation.setSwathInKM(15);
        imageLimitation.setAgilesat_pitch_inerval(20);
        imageLimitation.setMaxConeAngle(40);
        double R = AstroConst.R_Earth / 1000;
        double altitude = imageLimitation.getAltitude();
        double theta = Math.acos(R / (R + altitude));
        double distance_km_to_stationView = theta * R + imageLimitation.getSwathInKM();
        double maxConeAngle = imageLimitation.getMaxConeAngle();
        double n = 1 + altitude / R;
        double a_rad = -Math.toRadians(maxConeAngle) + Math.asin(n * Math.sin(Math.toRadians(maxConeAngle)));
        double distance_km_to_shot = a_rad * R + imageLimitation.getSwathInKM();

        imageLimitation.setMaxDistance_to_shot(distance_km_to_shot);
//		imageLimitation.setSwath_rad(60d);
        return imageLimitation;
    }

    public static ElectronImageLimitation getSample18ImageLimit() {
        ElectronImageLimitation imageLimitation = new ElectronImageLimitation();
        imageLimitation.setMinSunDegree(-90d);
        imageLimitation.setMaxRollDegree(0f);
        imageLimitation.setMinRollDegree(0f);
//		imageLimitation.setInclination(97.4622f);
        imageLimitation.setAltitude(600d);
        imageLimitation.setTimeStep(1.0);
        imageLimitation.setStepSpan(1);
        imageLimitation.setStepLength(1);
        imageLimitation.setSensorType(2);
        imageLimitation.setXDrift(0);
        imageLimitation.setYDrift(0);
        imageLimitation.setSatName("18");
        imageLimitation.setImageSign(2);
        imageLimitation.setLatLimit(3.0);
        imageLimitation.setMaxPitchDegree(0);
        imageLimitation.setMinPitchDegree(0);
        imageLimitation.setXSpan(0);
        imageLimitation.setMaxDistance_to_shot(1245.68);//最大半径1245.68公里，直径2491公里
        imageLimitation.setSwathInKM(2491);
        imageLimitation.maxAccessDuration = 30 * 60;
        imageLimitation.shapeOfFOV = SHAPE_FOV_CIRCLE;
        imageLimitation.maxConeAngle = 57;
        return imageLimitation;
    }

    public static ElectronImageLimitation getSample8ImageLimit() {
        ElectronImageLimitation imageLimitation = new ElectronImageLimitation();
        imageLimitation.setMinSunDegree(-90d);
        imageLimitation.setMaxRollDegree(0f);
        imageLimitation.setMinRollDegree(0f);
        imageLimitation.setMaxConeAngle(58.52);
//		imageLimitation.setInclination(97.4622f);
        imageLimitation.setAltitude(1100);
        imageLimitation.setTimeStep(1.0);
        imageLimitation.setStepSpan(1);
        imageLimitation.setStepLength(1);
        imageLimitation.setSensorType(2);
        imageLimitation.setXDrift(0);
        imageLimitation.setYDrift(0);
        imageLimitation.setSatName("8");
        imageLimitation.setImageSign(2);
        imageLimitation.setLatLimit(3.0);
        imageLimitation.setMaxPitchDegree(0);
        imageLimitation.setMinPitchDegree(0);
        imageLimitation.setXSpan(0);
        imageLimitation.setMaxDistance_to_shot(3507.5);//最大覆盖半径3507.5公里，直径7015公里//1270
        imageLimitation.setSwathInKM(7015);//1270//2540
        imageLimitation.maxAccessDuration = 30 * 60;
        imageLimitation.shapeOfFOV = SHAPE_FOV_CIRCLE;
        imageLimitation.maxConeAngle = 57;
        imageLimitation.default_point_distance = 3;
        return imageLimitation;
    }

    public void setSwathInKM(float swathInKM) {
        this.swathInKM = swathInKM;
        swath_rad = swathInKM * 1000 / AstroConst.R_Earth;///转为地球表面弧度
    }

    public float getHAFOV() {
        return (float) Math.toDegrees(Math.atan(swathInKM / 2 / altitude));
    }

}
