using BHJD.DEMdll.Entity; using BHJD.DEMdll.Public; using System.Diagnostics; using static BHJD.DEMdll.Public.IHttpHelper; using Unity.Mathematics; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SJ; using Model; using MathNet.Numerics; namespace MuShiApp { public class EquationHelper { //数据库访问类,dll有 //IDbHelper _db = null; //http请求类,dll有 IHttpHelper m_HttpHelper = null; public string baseUrl; public double x; public EquationHelper(string baseUrl) { this.baseUrl = baseUrl; m_HttpHelper = new HttpHelper(); //this._db = db; //m_HttpHelper = Factory.Load(); } //a、b、c、d、r、e均为修正系数 double[] a = { 9.5128, 1.3738, 0.0875 }; double[] b = { -49.6937, -13.2945, -2.5112 }; double[] c = { 31.6031, 13.1456, 6.1604 }; double[] d = { 95.0664, 97.0952, 94.9145 }; double[][] r = new double[3][]; double[][] e = new double[3][]; double[] posibility = { 0, 0, 0 }; public double GetMushiSeaProbability(double3 aircraftPoint, double visibility, double wavehigh, TargetPoint targetPoint) { r[0] = new double[] { 4.375, 1.18, 1.01, 1 }; r[1] = new double[] { 2.85, 1.51, 1.18, 1 }; r[2] = new double[] { 2.75, 2.1, 1.2, 1 }; e[0] = new double[] { -10, -30, -50, -65, -80, -90 }; e[1] = new double[] { -2, -15, -30, -50, -70, -80 }; e[2] = new double[] { 0, 0, -10, -20, -30, -40 }; double[] posibility = { 0, 0, 0 }; var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude,aircraftPoint.y,targetPoint.TargetPointLatitude); if (distance >= 0 && distance < 2) { posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, wavehigh); while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0) { distance += 0.1; posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, wavehigh); } } if (distance >= 2) { posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d); while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0) { distance += 0.5; posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d); } if (distance > 3.5) { posibility[0] = 0; } if (distance > 5) { posibility[1] = 0; } if (distance > 10) { posibility[2] = 0; } } return posibility[GetType(targetPoint.TargetType.Type)]; } public double GetMushiLandProbability(double3 aircraftPoint, double visibility, TargetPoint targetPoint) { r[0] = new double[] { 4.375, 1.18, 1.01, 1 }; r[1] = new double[] { 2.85, 1.51, 1.18, 1 }; r[2] = new double[] { 2.75, 2.1, 1.2, 1 }; e[0] = new double[] { 0, -30, -50, -65, -80, -90 }; e[1] = new double[] { 0, -15, -30, -50, -70, -80 }; e[2] = new double[] { 0, 0, -10, -20, -30, -40 }; double[] posibility = { 0, 0, 0 }; var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude,aircraftPoint.y,targetPoint.TargetPointLatitude); if (distance >= 0 && distance < 2) { posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, 0); while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0) { distance += 0.1; posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, 0); } } if (distance >= 2) { posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d); while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0) { distance += 0.5; posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d); } if (distance > 3.5) { posibility[0] = 0; } if (distance > 5) { posibility[1] = 0; } if (distance > 10) { posibility[2] = 0; } } return posibility[GetType(targetPoint.TargetType.Type)]; } // Pd0 = 0.5 / Pf0 = Math.Pow(10,-6) / Pf = Math.Pow(10,-6) / R0 = 23645 / sigma0 = 5000 / sigma = Editor雷达截面面积 // R 单位m public double GetRadarPossibility(double Pd0, double Pf0, double Pf, double R0, double3 aircraftPoint , TargetPoint targetPoint, double sigma, double sigma0, double visibility) { var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude, aircraftPoint.y, targetPoint.TargetPointLatitude); double R = 1000 * distance; //修正系数 double RadarC = 1; //能见度单位:km if (visibility >= 1) { RadarC = 1; } else if (visibility >= 0.3 && visibility < 1) { RadarC = 0.8; } else if (visibility >= 0.09 && visibility < 0.3) { RadarC = 0.6; } else { RadarC = 0.2; } double Possibility0 = 0; double SNR = 1; //SNR为信噪比;sigma为实际目标雷达截面积,单位:平方米;sigma0为理论目标雷达截面积,单位:平方米 SNR = sigma * Math.Pow(R0, 4) / (sigma0 * Math.Pow(R, 4)); Possibility0 = Math.Pow(Math.E, Math.Log(Pd0, Math.E) * Math.Log(Pf, Math.E) / (SNR * Math.Log(Pf0, Math.E) + Math.Log(Pd0, Math.E))); double Possibility = RadarC * Possibility0; return Possibility; } // Lt = 探测目标亮度 Editor / At = 探测目标面积 Editor / τa = 1 / Lb = 3 / A0 = 1 / D0 = 0.075 / Dstar = 3 / τo = 0.8 / Ad = 0.0073728 / Δf = 0.125 / δ = 0.5 / Pf0 = Math.Pow(10, -6); public double GetInfraredDetectionProbability(double Lt, double At, double τa, double Lb, double A0, double3 aircraftPoint, TargetPoint targetPoint, double D0, double Dstar, double τo, double Ad, double Δf, double δ, double Pf0) { var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude, aircraftPoint.y, targetPoint.TargetPointLatitude); double R = 1000 * distance; //确定由Pfa确定的最小信噪比 double minSNR = Math.Sqrt(-2 * Math.Log(Pf0, Math.E)); // 计算信噪比 double a = (Lt * At * τa - Lb * A0) * Math.PI * Math.Pow(D0, 2) * Dstar * δ * τo; double b = 4 * Math.Sqrt(Ad * Δf) * Math.Pow(R, 2); double SNR = a / b; // 使用 Math.NET Numerics 库计算高斯积分 double Pd = GaussianIntegral(SNR - minSNR); return Pd; } public static double GaussianIntegral(double x) { double integral = 1; if (x < 0) { integral = 0.5 - Math.Pow(Math.Sqrt(2 * Math.PI), -1) * Integrate.OnClosedInterval(t => Math.Exp(-Math.Pow(t, 2) / 2), 0, -x, 1e-2); } else { integral = 0.5 + Math.Pow(Math.Sqrt(2 * Math.PI), -1) * Integrate.OnClosedInterval(t => Math.Exp(-Math.Pow(t, 2) / 2), 0, x, 1e-2); } return integral; } public int GetType(string type) { switch (type) { case "遇险人员": case "落水人员": return 0; case "车辆": case "救生筏": case "小于5700kg航空器": case "小于20m船舶": return 1; case "大于20m船舶": case "大于5700kg航空器": return 2; } return -1; } public static double GetDistance(double lon1, double lon2, double lat1, double lat2) { double R = 6371; // 地球的半径(公里) double dLat = (lat2 - lat1) * Math.PI / 180.0; double dLon = (lon2 - lon1) * Math.PI / 180.0; double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat1 * Math.PI / 180.0) * Math.Cos(lat2 * Math.PI / 180.0) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2); double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); double distance = R * c; return distance; } /// /// /// /// 飞机坐标 /// 目标点坐标 /// 航向(度数) /// (当前日期) /// 风速(km/h) /// 浪高(m) /// 遇险目标类型 /// 救援场景类型 /// public double getProbability(double3 aircraftPoint, double3 targetPoint, double pb, double course, double windspeed, double wavehigh, string targetpye, string type) { try { double Cw = 1; if (windspeed > 46 && wavehigh > 1.5) { if (targetpye == "落水人员") { Cw = 0.25; } else { Cw = 0.6; } } else if (28 < windspeed && windspeed < 46 && 1 < wavehigh && wavehigh < 1.5) { if (targetpye == "船") { Cw = 0.5; } else { Cw = 0.9; } } else if (0 < windspeed && windspeed < 28 && 0 < wavehigh && wavehigh < 1) { Cw = 1; } double Cv = 1; System.Random ran = new System.Random(); double x = getx(aircraftPoint, targetPoint, course); double V = 15;//getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH")); if (V < 6) { Cv = 0.4; } else if (6 < V && V < 9) { Cv = 0.6; } else if (9 < V && V < 19) { Cv = 0.8; } else if (19 < V && V < 28) { Cv = 0.9; } else if (37 < V) { Cv = 1; } double pt = this.nextDouble(ran, 0.800, 0.999, 8); //double pb = targetPoint;//getPb(targetPoint.x, targetPoint.y); double D = 0; double C = Math.Round((double)((pt - pb) / pt), 8); if (type == "陆地") { D = (V / 3.912) * Math.Log10(C / 0.02); } else if (type == "海上") { if (targetpye == "船") { D = 31 * Cv * Cw; } else if (targetpye == "落水人员") { D = 0.2 * Cv * Cw; } } double px = 1 - Math.Exp((-1 * D * D) / (4 * Math.PI * x * x)); return px; } catch (Exception ex) { Debug.Print("error!!!!!getProbability:" + ex.ToString()); return -1; } } /// /// /// /// 飞机坐标 /// 目标点坐标 /// 航向(度数) /// (当前日期) /// public double getProbability(double3 aircraftPoint, double3 targetPoint, double course) { try { x = getx(aircraftPoint, targetPoint, course); double V = getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH")); System.Random ran = new System.Random(); double pt = this.nextDouble(ran, 0.800, 0.999, 8); double pb = getPb(targetPoint.x, targetPoint.y); double C = Math.Round((double)((pt - pb) / pt), 8); double D = (V / 3.912) * Math.Log10(C / 0.02); double px = 1 - Math.Exp((-1 * D * D) / (4 * Math.PI * x * x)); return px; } catch (Exception ex) { Console.WriteLine("error!!!!!getProbability:" + ex.ToString()); return -1; } } public double getX(double3 targetPoint) { try { double result = -1; double V = getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH")); double pt = 0.85; double pb = getPb(targetPoint.x, targetPoint.y); double C = Math.Round((double)((pt - pb) / pt), 3); double D = (V / 3.912) * Math.Log10(C / 0.02); double x = Math.Sqrt(-1 * D * D / Math.Log(1 - 0.85) / 4 / Math.PI); return x; } catch (Exception ex) { Debug.Print("error!!!!!getX:" + ex.ToString()); return -1; } } private double nextDouble(System.Random ran, double minValue, double maxValue, int decimalPlace) { double randNum = ran.NextDouble() * (maxValue - minValue) + minValue; return Convert.ToDouble(randNum.ToString("f" + decimalPlace)); } public double getVisibility(string city_name, string weather_date) { try { //调在线气象接口,封装到服务中了 HttpCmd cmd = new HttpCmd { m_RequestType = HttpRequestType.GET, m_Addr = $"{baseUrl}rescue-platform-service/api/v1/tbMeteorology/getInfosByNowApi", m_Args = new List { "city_name", "weather_date" } }; string response = m_HttpHelper.Request(cmd, new List { city_name, weather_date }); R data = JsonConvert.DeserializeObject(response); if (data != null && data.code == 200) { NAdtListDto rt = JsonConvert.DeserializeObject(data.data.ToString()); double fl = Convert.ToDouble(rt.wtVisibility); if (fl.Equals(0)) { fl = 15; } return fl; } return 15; } catch (Exception ex) { Debug.Print("error!!!!!getVisibility"); Debug.Print(ex.ToString()); return 15; } } public double getVisibilityByDb(double centerLon, double centerLat, string visibility_date) { try { HttpCmd cmd = new HttpCmd { m_RequestType = HttpRequestType.GET, m_Addr = "http://10.130.100.5:7785//rescue-platform-service/api/v1/attribute/getVisibility", //10.130.100.5 127.0.0.1 m_Args = new List { "centerLon", "centerLat", "visibility_date" } }; string response = m_HttpHelper.Request(cmd, new List { centerLon.ToString(), centerLat.ToString(), visibility_date }); //Console.WriteLine(" centerLon:" + centerLon + " " + "centerLat:" + centerLat + " " + "visibility_date:" + visibility_date); //Console.WriteLine("response:" + response); R data = JsonConvert.DeserializeObject(response); if (data != null && data.code == 200) { string vi = data.data.ToString(); double fl = Convert.ToDouble(vi); if (fl.Equals(0)) { fl = 15; //Console.WriteLine("1:" + fl); } //Console.WriteLine("2:" + fl); return fl; } //Console.WriteLine("3:" + 15); return 15; } catch (Exception ex) { //Console.WriteLine("4:" + 15); Debug.Print("error!!!!!getVisibility"); Debug.Print(ex.ToString()); return 15; } } //rescue-platform-service/api/v1/dem/getCityName // { // "msg": "success", // "code": 200, // "cityName": "承德市" // } public string getCityName(double lon, double lat) { string cityName = "北京"; // try // { // string sql = string.Format("select a.f_xzqdm cityCode, a.f_xzqmc cityName from xzq_ds a where ST_Contains(shape,st_geomfromtext('POINT({0} {1})',4326)) limit 1", lon, lat); // DataTable dt = this._db.DoQueryEx(sql); // if (dt != null && dt.Rows.Count > 0) // { // cityName = dt.Rows[0][1].ToString().Replace("市", "").Replace("自治区", ""); // } // } // catch (Exception ex) // { // Debug.Print("error!!!!!getCityName"); // Debug.Print(ex.ToString()); // } try { //调在线气象接口,封装到服务中了 HttpCmd cmd = new HttpCmd { m_RequestType = HttpRequestType.GET, m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getCityName", m_Args = new List { "lon", "lat" } }; string response = m_HttpHelper.Request(cmd, new List { lon.ToString(), lat.ToString() }); JObject jObject = JObject.Parse(response); cityName = jObject["cityName"].ToString().Replace("市", "").Replace("自治区", ""); } catch (Exception ex) { Debug.Print("error!!!!!getVisibility"); Debug.Print(ex.ToString()); } return cityName; } //rescue-platform-service/api/v1/dem/getCategory // { // "msg": "success", // "code": 200, // "category": "7 草丛" // } public double getPb(double lon, double lat) { double pb = 0.13; try { // string sql_zb = string.Format("select f_category from ly_vegetation where ST_Contains(st_geomfromtext(st_astext(shape) ),st_geomfromtext('POINT({0} {1})'))", lon, lat); // DataTable dt_zb = _db.DoQueryEx(sql_zb); //调在线气象接口,封装到服务中了 HttpCmd cmd = new HttpCmd { m_RequestType = HttpRequestType.GET, m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getCategory", m_Args = new List { "lon", "lat" } }; string response = m_HttpHelper.Request(cmd, new List { lon.ToString(), lat.ToString() }); JObject jObject = JObject.Parse(response); string fcategory = jObject["category"].ToString(); switch (fcategory) { case "1 针叶林": pb = 0.13; break; case "10 高山植被": pb = 0.13; break; case "11 栽培植被": pb = 0.13; break; case "2 针阔叶混交林": pb = 0.13; break; case "3 阔叶林": pb = 0.13; break; case "4 灌丛": pb = 0.13; break; case "5 荒漠": pb = 0.13; break; case "6 草原": pb = 0.13; break; case "7 草丛": pb = 0.13; break; case "8 草甸": pb = 0.13; break; case "9 沼泽": pb = 0.13; break; default: pb = 0.13; break; } } catch (Exception ex) { Debug.Print("error!!!!!getPb"); Debug.Print(ex.ToString()); } return pb; } //rescue-platform-service/api/v1/dem/getDistance // { // "msg": "success", // "code": 200, // "data": { // "differ": 328.31408076, // "azimuth": 2.400469679065642 // } // } private double getx(double3 aircraftPoint, double3 targetPoint, double course) { double result = -1; // string sql = string.Format("select ST_Distance( ST_SetSRID(ST_MakePoint({0},{1}),4326)::geography, ST_SetSRID(ST_MakePoint({2},{3}),4326)::geography) as differ,ST_azimuth(st_geomfromtext('POINT({0} {1})'),st_geomfromtext('POINT({2} {3})')) as azimuth", aircraftPoint.x, aircraftPoint.y, targetPoint.x, targetPoint.y); // DataTable dt = _db.DoQueryEx(sql); HttpCmd cmd = new HttpCmd { m_RequestType = HttpRequestType.GET, m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getDistance", m_Args = new List { "lon_air", "lat_air", "lon_target", "lat_target" } }; string response = m_HttpHelper.Request(cmd, new List { aircraftPoint.x.ToString(), aircraftPoint.y.ToString(), targetPoint.x.ToString(), targetPoint.y.ToString() }); JObject jObject = JObject.Parse(response); double differ = double.Parse(jObject["data"]["differ"].ToString()); double azimuth = double.Parse(jObject["data"]["azimuth"].ToString()); // differ = Convert.ToDouble(dt.Rows[0][0].ToString()); azimuth = 180 / Math.PI * azimuth;//Convert.ToDouble(dt.Rows[0][1].ToString()); double angle = course - azimuth; if (angle < 0) { angle = -1 * angle; } double x = differ * Math.Sin(angle * Math.PI / 180) / 1000; return x; } } }