EquationHelper.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. using BHJD.DEMdll.Entity;
  2. using BHJD.DEMdll.Public;
  3. using System.Diagnostics;
  4. using static BHJD.DEMdll.Public.IHttpHelper;
  5. using Unity.Mathematics;
  6. using Newtonsoft.Json;
  7. using Newtonsoft.Json.Linq;
  8. using SJ;
  9. using Model;
  10. namespace MuShiApp
  11. {
  12. public class EquationHelper
  13. {
  14. //数据库访问类,dll有
  15. //IDbHelper _db = null;
  16. //http请求类,dll有
  17. IHttpHelper m_HttpHelper = null;
  18. public string baseUrl;
  19. public double x;
  20. public EquationHelper(string baseUrl)
  21. {
  22. this.baseUrl = baseUrl;
  23. m_HttpHelper = new HttpHelper();
  24. //this._db = db;
  25. //m_HttpHelper = Factory.Load();
  26. }
  27. //a、b、c、d、r、e均为修正系数
  28. double[] a = { 9.5128, 1.3738, 0.0875 };
  29. double[] b = { -49.6937, -13.2945, -2.5112 };
  30. double[] c = { 31.6031, 13.1456, 6.1604 };
  31. double[] d = { 95.0664, 97.0952, 94.9145 };
  32. double[][] r = new double[3][];
  33. double[][] e = new double[3][];
  34. double[] posibility = { 0, 0, 0 };
  35. public double GetMushiSeaProbability(double3 aircraftPoint, double visibility, double wavehigh, TargetPoint targetPoint)
  36. {
  37. r[0] = new double[] { 4.375, 1.18, 1.01, 1 };
  38. r[1] = new double[] { 2.85, 1.51, 1.18, 1 };
  39. r[2] = new double[] { 2.75, 2.1, 1.2, 1 };
  40. e[0] = new double[] { -10, -30, -50, -65, -80, -90 };
  41. e[1] = new double[] { -2, -15, -30, -50, -70, -80 };
  42. e[2] = new double[] { 0, 0, -10, -20, -30, -40 };
  43. double[] posibility = { 0, 0, 0 };
  44. var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude,aircraftPoint.y,targetPoint.TargetPointLatitude);
  45. if (distance >= 0 && distance < 2)
  46. {
  47. posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, wavehigh);
  48. while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0)
  49. {
  50. distance += 0.1;
  51. posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, wavehigh);
  52. }
  53. }
  54. if (distance >= 2)
  55. {
  56. posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d);
  57. while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0)
  58. {
  59. distance += 0.5;
  60. posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d);
  61. }
  62. if (distance > 3.5)
  63. {
  64. posibility[0] = 0;
  65. }
  66. if (distance > 5)
  67. {
  68. posibility[1] = 0;
  69. }
  70. if (distance > 10)
  71. {
  72. posibility[2] = 0;
  73. }
  74. }
  75. return posibility[GetType(targetPoint.TargetType.Type)];
  76. }
  77. public double GetMushiLandProbability(double3 aircraftPoint, double visibility, TargetPoint targetPoint)
  78. {
  79. r[0] = new double[] { 4.375, 1.18, 1.01, 1 };
  80. r[1] = new double[] { 2.85, 1.51, 1.18, 1 };
  81. r[2] = new double[] { 2.75, 2.1, 1.2, 1 };
  82. e[0] = new double[] { 0, -30, -50, -65, -80, -90 };
  83. e[1] = new double[] { 0, -15, -30, -50, -70, -80 };
  84. e[2] = new double[] { 0, 0, -10, -20, -30, -40 };
  85. double[] posibility = { 0, 0, 0 };
  86. var distance = GetDistance(aircraftPoint.x, targetPoint.TargetPointLongitude,aircraftPoint.y,targetPoint.TargetPointLatitude);
  87. if (distance >= 0 && distance < 2)
  88. {
  89. posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, 0);
  90. while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0)
  91. {
  92. distance += 0.1;
  93. posibility = MuShiModel.GetPosibilityClear(distance, a, b, c, d, r, e, visibility, 0);
  94. }
  95. }
  96. if (distance >= 2)
  97. {
  98. posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d);
  99. while (posibility[0] <= 0 || posibility[1] <= 0 || posibility[2] <= 0)
  100. {
  101. distance += 0.5;
  102. posibility = MuShiModel.GetPosibilityFar(distance, a, b, c, d);
  103. }
  104. if (distance > 3.5)
  105. {
  106. posibility[0] = 0;
  107. }
  108. if (distance > 5)
  109. {
  110. posibility[1] = 0;
  111. }
  112. if (distance > 10)
  113. {
  114. posibility[2] = 0;
  115. }
  116. }
  117. return posibility[GetType(targetPoint.TargetType.Type)];
  118. }
  119. public int GetType(string type)
  120. {
  121. switch (type)
  122. {
  123. case "遇险人员":
  124. case "落水人员":
  125. return 0;
  126. case "车辆":
  127. case "救生筏":
  128. case "小于5700kg航空器":
  129. case "小于20m船舶":
  130. return 1;
  131. case "大于20m船舶":
  132. case "大于5700kg航空器":
  133. return 2;
  134. }
  135. return -1;
  136. }
  137. public static double GetDistance(double lon1, double lon2, double lat1, double lat2)
  138. {
  139. double R = 6371; // 地球的半径(公里)
  140. double dLat = (lat2 - lat1) * Math.PI / 180.0;
  141. double dLon = (lon2 - lon1) * Math.PI / 180.0;
  142. double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
  143. Math.Cos(lat1 * Math.PI / 180.0) * Math.Cos(lat2 * Math.PI / 180.0) *
  144. Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
  145. double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
  146. double distance = R * c;
  147. return distance;
  148. }
  149. /// <summary>
  150. ///
  151. /// </summary>
  152. /// <param name="aircraftPoint">飞机坐标</param>
  153. /// <param name="targetPoint">目标点坐标</param>
  154. /// <param name="course">航向(度数)</param>
  155. /// <param name="currentDate">(当前日期)</param>
  156. /// <param name="windspeed">风速(km/h)</param>
  157. /// <param name="wavehigh">浪高(m)</param>
  158. /// <param name="targetpye">遇险目标类型</param>
  159. /// <param name="typee">救援场景类型</param>
  160. /// <returns></returns>
  161. public double getProbability(double3 aircraftPoint, double3 targetPoint, double pb, double course, double windspeed, double wavehigh, string targetpye, string type)
  162. {
  163. try
  164. {
  165. double Cw = 1;
  166. if (windspeed > 46 && wavehigh > 1.5)
  167. {
  168. if (targetpye == "落水人员")
  169. {
  170. Cw = 0.25;
  171. }
  172. else
  173. {
  174. Cw = 0.6;
  175. }
  176. }
  177. else if (28 < windspeed && windspeed < 46 && 1 < wavehigh && wavehigh < 1.5)
  178. {
  179. if (targetpye == "船")
  180. {
  181. Cw = 0.5;
  182. }
  183. else
  184. {
  185. Cw = 0.9;
  186. }
  187. }
  188. else if (0 < windspeed && windspeed < 28 && 0 < wavehigh && wavehigh < 1)
  189. {
  190. Cw = 1;
  191. }
  192. double Cv = 1;
  193. System.Random ran = new System.Random();
  194. double x = getx(aircraftPoint, targetPoint, course);
  195. double V = 15;//getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH"));
  196. if (V < 6)
  197. {
  198. Cv = 0.4;
  199. }
  200. else if (6 < V && V < 9)
  201. {
  202. Cv = 0.6;
  203. }
  204. else if (9 < V && V < 19)
  205. {
  206. Cv = 0.8;
  207. }
  208. else if (19 < V && V < 28)
  209. {
  210. Cv = 0.9;
  211. }
  212. else if (37 < V)
  213. {
  214. Cv = 1;
  215. }
  216. double pt = this.nextDouble(ran, 0.800, 0.999, 8);
  217. //double pb = targetPoint;//getPb(targetPoint.x, targetPoint.y);
  218. double D = 0;
  219. double C = Math.Round((double)((pt - pb) / pt), 8);
  220. if (type == "陆地")
  221. {
  222. D = (V / 3.912) * Math.Log10(C / 0.02);
  223. }
  224. else if (type == "海上")
  225. {
  226. if (targetpye == "船")
  227. { D = 31 * Cv * Cw; }
  228. else if (targetpye == "落水人员")
  229. { D = 0.2 * Cv * Cw; }
  230. }
  231. double px = 1 - Math.Exp((-1 * D * D) / (4 * Math.PI * x * x));
  232. return px;
  233. }
  234. catch (Exception ex)
  235. {
  236. Debug.Print("error!!!!!getProbability:" + ex.ToString());
  237. return -1;
  238. }
  239. }
  240. /// <summary>
  241. ///
  242. /// </summary>
  243. /// <param name="aircraftPoint">飞机坐标</param>
  244. /// <param name="targetPoint">目标点坐标</param>
  245. /// <param name="course">航向(度数)</param>
  246. /// <param name="currentDate">(当前日期)</param>
  247. /// <returns></returns>
  248. public double getProbability(double3 aircraftPoint, double3 targetPoint, double course, double V)
  249. {
  250. try
  251. {
  252. x = getx(aircraftPoint, targetPoint, course);
  253. //double V = getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH"));
  254. System.Random ran = new System.Random();
  255. double pt = this.nextDouble(ran, 0.800, 0.999, 8);
  256. double pb = getPb(targetPoint.x, targetPoint.y);
  257. double C = Math.Round((double)((pt - pb) / pt), 8);
  258. double D = (V / 3.912) * Math.Log10(C / 0.02);
  259. double px = 1 - Math.Exp((-1 * D * D) / (4 * Math.PI * x * x));
  260. return px;
  261. }
  262. catch (Exception ex)
  263. {
  264. Console.WriteLine("error!!!!!getProbability:" + ex.ToString());
  265. return -1;
  266. }
  267. }
  268. public double getX(double3 targetPoint)
  269. {
  270. try
  271. {
  272. double result = -1;
  273. double V = getVisibility(getCityName(targetPoint.x, targetPoint.y), DateTime.Now.ToString("yyyy-MM-dd HH"));
  274. double pt = 0.85;
  275. double pb = getPb(targetPoint.x, targetPoint.y);
  276. double C = Math.Round((double)((pt - pb) / pt), 3);
  277. double D = (V / 3.912) * Math.Log10(C / 0.02);
  278. double x = Math.Sqrt(-1 * D * D / Math.Log(1 - 0.85) / 4 / Math.PI);
  279. return x;
  280. }
  281. catch (Exception ex)
  282. {
  283. Debug.Print("error!!!!!getX:" + ex.ToString());
  284. return -1;
  285. }
  286. }
  287. private double nextDouble(System.Random ran, double minValue, double maxValue, int decimalPlace)
  288. {
  289. double randNum = ran.NextDouble() * (maxValue - minValue) + minValue;
  290. return Convert.ToDouble(randNum.ToString("f" + decimalPlace));
  291. }
  292. public double getVisibility(string city_name, string weather_date)
  293. {
  294. try
  295. {
  296. //调在线气象接口,封装到服务中了
  297. HttpCmd cmd = new HttpCmd
  298. {
  299. m_RequestType = HttpRequestType.GET,
  300. m_Addr = $"{baseUrl}rescue-platform-service/api/v1/tbMeteorology/getInfosByNowApi",
  301. m_Args = new List<string> { "city_name", "weather_date" }
  302. };
  303. string response = m_HttpHelper.Request(cmd, new List<string> { city_name, weather_date });
  304. R data = JsonConvert.DeserializeObject<R>(response);
  305. if (data != null && data.code == 200)
  306. {
  307. NAdtListDto rt = JsonConvert.DeserializeObject<NAdtListDto>(data.data.ToString());
  308. double fl = Convert.ToDouble(rt.wtVisibility);
  309. if (fl.Equals(0))
  310. {
  311. fl = 15;
  312. }
  313. return fl;
  314. }
  315. return 15;
  316. }
  317. catch (Exception ex)
  318. {
  319. Debug.Print("error!!!!!getVisibility");
  320. Debug.Print(ex.ToString());
  321. return 15;
  322. }
  323. }
  324. //rescue-platform-service/api/v1/dem/getCityName
  325. // {
  326. // "msg": "success",
  327. // "code": 200,
  328. // "cityName": "承德市"
  329. // }
  330. public string getCityName(double lon, double lat)
  331. {
  332. string cityName = "北京";
  333. // try
  334. // {
  335. // 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);
  336. // DataTable dt = this._db.DoQueryEx(sql);
  337. // if (dt != null && dt.Rows.Count > 0)
  338. // {
  339. // cityName = dt.Rows[0][1].ToString().Replace("市", "").Replace("自治区", "");
  340. // }
  341. // }
  342. // catch (Exception ex)
  343. // {
  344. // Debug.Print("error!!!!!getCityName");
  345. // Debug.Print(ex.ToString());
  346. // }
  347. try
  348. {
  349. //调在线气象接口,封装到服务中了
  350. HttpCmd cmd = new HttpCmd
  351. {
  352. m_RequestType = HttpRequestType.GET,
  353. m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getCityName",
  354. m_Args = new List<string> { "lon", "lat" }
  355. };
  356. string response = m_HttpHelper.Request(cmd, new List<string> { lon.ToString(), lat.ToString() });
  357. JObject jObject = JObject.Parse(response);
  358. cityName = jObject["cityName"].ToString().Replace("市", "").Replace("自治区", "");
  359. }
  360. catch (Exception ex)
  361. {
  362. Debug.Print("error!!!!!getVisibility");
  363. Debug.Print(ex.ToString());
  364. }
  365. return cityName;
  366. }
  367. //rescue-platform-service/api/v1/dem/getCategory
  368. // {
  369. // "msg": "success",
  370. // "code": 200,
  371. // "category": "7 草丛"
  372. // }
  373. public double getPb(double lon, double lat)
  374. {
  375. double pb = 0.13;
  376. try
  377. {
  378. // 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);
  379. // DataTable dt_zb = _db.DoQueryEx(sql_zb);
  380. //调在线气象接口,封装到服务中了
  381. HttpCmd cmd = new HttpCmd
  382. {
  383. m_RequestType = HttpRequestType.GET,
  384. m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getCategory",
  385. m_Args = new List<string> { "lon", "lat" }
  386. };
  387. string response = m_HttpHelper.Request(cmd, new List<string> { lon.ToString(), lat.ToString() });
  388. JObject jObject = JObject.Parse(response);
  389. string fcategory = jObject["category"].ToString();
  390. switch (fcategory)
  391. {
  392. case "1 针叶林":
  393. pb = 0.13;
  394. break;
  395. case "10 高山植被":
  396. pb = 0.13;
  397. break;
  398. case "11 栽培植被":
  399. pb = 0.13;
  400. break;
  401. case "2 针阔叶混交林":
  402. pb = 0.13;
  403. break;
  404. case "3 阔叶林":
  405. pb = 0.13;
  406. break;
  407. case "4 灌丛":
  408. pb = 0.13;
  409. break;
  410. case "5 荒漠":
  411. pb = 0.13;
  412. break;
  413. case "6 草原":
  414. pb = 0.13;
  415. break;
  416. case "7 草丛":
  417. pb = 0.13;
  418. break;
  419. case "8 草甸":
  420. pb = 0.13;
  421. break;
  422. case "9 沼泽":
  423. pb = 0.13;
  424. break;
  425. default:
  426. pb = 0.13;
  427. break;
  428. }
  429. }
  430. catch (Exception ex)
  431. {
  432. Debug.Print("error!!!!!getPb");
  433. Debug.Print(ex.ToString());
  434. }
  435. return pb;
  436. }
  437. //rescue-platform-service/api/v1/dem/getDistance
  438. // {
  439. // "msg": "success",
  440. // "code": 200,
  441. // "data": {
  442. // "differ": 328.31408076,
  443. // "azimuth": 2.400469679065642
  444. // }
  445. // }
  446. private double getx(double3 aircraftPoint, double3 targetPoint, double course)
  447. {
  448. double result = -1;
  449. // 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);
  450. // DataTable dt = _db.DoQueryEx(sql);
  451. HttpCmd cmd = new HttpCmd
  452. {
  453. m_RequestType = HttpRequestType.GET,
  454. m_Addr = $"{baseUrl}rescue-platform-service/api/v1/dem/getDistance",
  455. m_Args = new List<string> { "lon_air", "lat_air", "lon_target", "lat_target" }
  456. };
  457. string response = m_HttpHelper.Request(cmd, new List<string> { aircraftPoint.x.ToString(), aircraftPoint.y.ToString(), targetPoint.x.ToString(), targetPoint.y.ToString() });
  458. JObject jObject = JObject.Parse(response);
  459. double differ = double.Parse(jObject["data"]["differ"].ToString());
  460. double azimuth = double.Parse(jObject["data"]["azimuth"].ToString());
  461. // differ = Convert.ToDouble(dt.Rows[0][0].ToString());
  462. azimuth = 180 / Math.PI * azimuth;//Convert.ToDouble(dt.Rows[0][1].ToString());
  463. double angle = course - azimuth;
  464. if (angle < 0)
  465. {
  466. angle = -1 * angle;
  467. }
  468. double x = differ * Math.Sin(angle * Math.PI / 180) / 1000;
  469. return x;
  470. }
  471. }
  472. }