فهرست منبع

Merge branch 'main' into v1.0

# Conflicts:
#	KYFramework/bin/Debug/net7.0/KYFramework.dll
#	KYFramework/bin/Debug/net7.0/KYFramework.pdb
#	KYFramework/bin/Debug/net7.0/ThirdParty.dll
#	KYFramework/bin/Debug/net7.0/ThirdParty.pdb
#	Models/SimulationCommon/Define.cs
#	Models/SimulationCommon/EditorConfig.cs
#	Models/SimulationCommon/FXJHGenenrate.cs
#	Models/SimulationCommon/TaskConfig.cs
#	SimulationServer/Component/TaskComponent.cs
#	SimulationServer/Entity/AircraftEntity.cs
#	SimulationServer/Entity/Aircrafts/AircraftLandSJ.cs
#	SimulationServer/Entity/Aircrafts/AircraftSHJ.cs
#	SimulationServer/Entity/Aircrafts/AircraftSJ.cs
#	SimulationServer/Entity/Missions/LandSJRescueMission.cs
#	SimulationServer/Entity/Missions/SeaSJRescueMission.cs
#	SimulationServer/EventHandler/CreateTaskEventHandler.cs
#	SimulationServer/EventHandler/ServerStartEventHandler.cs
#	SimulationServer/bin/Debug/net7.0-windows/KYFramework.pdb
#	SimulationServer/bin/Debug/net7.0-windows/MathNet.Numerics.dll
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
#	SimulationServer/bin/Debug/net7.0-windows/Simulation.deps.json
#	SimulationServer/bin/Debug/net7.0-windows/ThirdParty.dll
#	SimulationServer/bin/Debug/net7.0/KYFramework.dll
#	SimulationServer/bin/Debug/net7.0/KYNetwork.dll
#	SimulationServer/bin/Debug/net7.0/KYNetwork.pdb
#	SimulationServer/bin/Debug/net7.0/Missions/editor_config.json
#	SimulationServer/bin/Debug/net7.0/Missions/task_config.json
#	SimulationServer/bin/Debug/net7.0/Reports/LSX/2024-08-30/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0/Reports/SSJ/2024-08-30/搜救任务总体指标报告.xls
#	SimulationServer/bin/Debug/net7.0/SimulationCommon.dll
#	SimulationServer/bin/Debug/net7.0/SimulationCommon.pdb
#	SimulationServer/bin/Debug/net7.0/SimulationServer.dll
#	SimulationServer/bin/Debug/net7.0/SimulationServer.exe
#	SimulationServer/bin/Debug/net7.0/SimulationServer.pdb
#	SimulationServer/bin/Debug/net7.0/ThirdParty.pdb
#	ThirdParty/bin/Debug/net7.0/ThirdParty.dll
#	ThirdParty/bin/Debug/net7.0/ThirdParty.pdb
zansimple 5 روز پیش
والد
کامیت
48b434773d
99فایلهای تغییر یافته به همراه7304 افزوده شده و 589 حذف شده
  1. 2 0
      KYFramework/KYFramework.csproj
  2. 786 0
      KYFramework/bin/Debug/net7.0/KYFramework.deps.json
  3. BIN
      KYFramework/bin/Debug/net7.0/KYFramework.dll
  4. BIN
      KYFramework/bin/Debug/net7.0/KYFramework.pdb
  5. BIN
      KYFramework/bin/Debug/net7.0/ThirdParty.dll
  6. BIN
      KYFramework/bin/Debug/net7.0/ThirdParty.pdb
  7. 2 0
      KYNetwork/KYNetwork.csproj
  8. 37 0
      Models/SimulationCommon/DataCalculate.cs
  9. 123 21
      Models/SimulationCommon/EditorConfig.cs
  10. 113 0
      Models/SimulationCommon/EquationHelper.cs
  11. 160 75
      Models/SimulationCommon/FXJHGenenrate.cs
  12. 1 0
      Models/SimulationCommon/FlightPlanEditor.cs
  13. 153 52
      Models/SimulationCommon/Rectangular_Area_Search_Function.cs
  14. 89 36
      Models/SimulationCommon/SeaSJ.cs
  15. 2 0
      Models/SimulationCommon/SimulationCommon.csproj
  16. 35 5
      Models/SimulationCommon/SurvivalTimeModel.cs
  17. 161 66
      Models/SimulationCommon/TaskConfig.cs
  18. 92 63
      Models/SimulationCommon/Text_readNC.cs
  19. 2 2
      Models/SimulationCommon/Util.cs
  20. 18 13
      Models/SimulationCommon/temp_readNC.cs
  21. 5 0
      Proto2CS/Proto2CS.csproj
  22. 20 12
      SimulationServer/Component/SJAllTotalTaskPerformance.cs
  23. 264 0
      SimulationServer/Component/SJStaticCapacityComponent.cs
  24. 641 8
      SimulationServer/Component/TaskComponent.cs
  25. 266 0
      SimulationServer/Entity/AircraftDY.cs
  26. 75 0
      SimulationServer/Entity/AircraftEntity.cs
  27. 112 0
      SimulationServer/Entity/AircraftJJ.cs
  28. 403 0
      SimulationServer/Entity/AircraftKTKS.cs
  29. 188 0
      SimulationServer/Entity/AircraftZS.cs
  30. 196 40
      SimulationServer/Entity/Aircrafts/AircraftLandSJ.cs
  31. 151 18
      SimulationServer/Entity/Aircrafts/AircraftSHJ.cs
  32. 240 66
      SimulationServer/Entity/Aircrafts/AircraftSJ.cs
  33. 187 0
      SimulationServer/Entity/JJJYMission.cs
  34. 189 0
      SimulationServer/Entity/KTKSMission.cs
  35. 190 0
      SimulationServer/Entity/KZDYMission.cs
  36. 37 25
      SimulationServer/Entity/Missions/LandSJRescueMission.cs
  37. 38 21
      SimulationServer/Entity/Missions/SeaSJRescueMission.cs
  38. 187 0
      SimulationServer/Entity/SHJMission.cs
  39. 188 0
      SimulationServer/Entity/ZSJYMission.cs
  40. 284 4
      SimulationServer/EventHandler/CreateTaskEventHandler.cs
  41. 30 0
      SimulationServer/EventHandler/EventStruct.cs
  42. 25 7
      SimulationServer/EventHandler/ServerStartEventHandler.cs
  43. 2 0
      SimulationServer/SimulationServer.csproj
  44. 37 22
      SimulationServer/Utils/DataTableExtensions.cs
  45. 1 1
      SimulationServer/Utils/Util.cs
  46. BIN
      SimulationServer/bin/Debug/net7.0-windows/MathNet.Numerics.dll
  47. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/搜救任务总体指标报告.xls
  48. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻任务总体指标报告.xls
  49. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
  50. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/搜救任务总体指标报告.xls
  51. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻任务总体指标报告.xls
  52. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
  53. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/搜救任务总体指标报告.xls
  54. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻任务总体指标报告.xls
  55. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
  56. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/搜救任务总体指标报告.xls
  57. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻任务总体指标报告.xls
  58. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
  59. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/搜救任务总体指标报告.xls
  60. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻任务总体指标报告.xls
  61. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls
  62. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/搜救任务总体指标报告.xls
  63. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜救任务总体指标报告.xls
  64. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  65. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/搜救任务总体指标报告.xls
  66. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜救任务总体指标报告.xls
  67. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  68. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/搜救任务总体指标报告.xls
  69. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜救任务总体指标报告.xls
  70. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  71. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/搜救任务总体指标报告.xls
  72. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜救任务总体指标报告.xls
  73. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  74. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/搜救任务总体指标报告.xls
  75. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜救任务总体指标报告.xls
  76. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  77. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/搜救任务总体指标报告.xls
  78. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜救任务总体指标报告.xls
  79. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  80. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/搜救任务总体指标报告.xls
  81. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜救任务总体指标报告.xls
  82. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  83. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/搜救任务总体指标报告.xls
  84. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜救任务总体指标报告.xls
  85. BIN
      SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls
  86. 758 32
      SimulationServer/bin/Debug/net7.0-windows/Simulation.deps.json
  87. BIN
      SimulationServer/bin/Debug/net7.0/KYFramework.dll
  88. BIN
      SimulationServer/bin/Debug/net7.0/KYNetwork.dll
  89. BIN
      SimulationServer/bin/Debug/net7.0/KYNetwork.pdb
  90. BIN
      SimulationServer/bin/Debug/net7.0/SimulationCommon.dll
  91. BIN
      SimulationServer/bin/Debug/net7.0/SimulationCommon.pdb
  92. BIN
      SimulationServer/bin/Debug/net7.0/SimulationServer.dll
  93. BIN
      SimulationServer/bin/Debug/net7.0/SimulationServer.exe
  94. BIN
      SimulationServer/bin/Debug/net7.0/SimulationServer.pdb
  95. BIN
      SimulationServer/bin/Debug/net7.0/ThirdParty.pdb
  96. 2 0
      ThirdParty/ThirdParty.csproj
  97. 812 0
      ThirdParty/bin/Debug/net7.0/ThirdParty.deps.json
  98. BIN
      ThirdParty/bin/Debug/net7.0/ThirdParty.dll
  99. BIN
      ThirdParty/bin/Debug/net7.0/ThirdParty.pdb

+ 2 - 0
KYFramework/KYFramework.csproj

@@ -8,6 +8,8 @@
 
 
   <ItemGroup>
+    <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+    <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
     <PackageReference Include="MongoDB.Bson" Version="2.0.0" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
     <PackageReference Include="NLog" Version="5.1.3" />

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 786 - 0
KYFramework/bin/Debug/net7.0/KYFramework.deps.json


BIN
KYFramework/bin/Debug/net7.0/KYFramework.dll


BIN
KYFramework/bin/Debug/net7.0/KYFramework.pdb


BIN
KYFramework/bin/Debug/net7.0/ThirdParty.dll


BIN
KYFramework/bin/Debug/net7.0/ThirdParty.pdb


+ 2 - 0
KYNetwork/KYNetwork.csproj

@@ -19,6 +19,8 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+    <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
     <PackageReference Include="UniTask" Version="2.5.0" />
   </ItemGroup>
 

+ 37 - 0
Models/SimulationCommon/DataCalculate.cs

@@ -0,0 +1,37 @@
+using System;
+
+static class DataCalculate
+{
+    static void Main()
+    {
+        Console.Write("请输入年份:");
+        int year = int.Parse(Console.ReadLine());
+        Console.Write("请输入月份:");
+        int month = int.Parse(Console.ReadLine());
+        Console.Write("请输入日期:");
+        int day = int.Parse(Console.ReadLine());
+
+        int daysInYear = GetDaysInYear(year, month, day);
+        Console.WriteLine($"{year}年{month}月{day}日是该年的第{daysInYear}天。");
+    }
+
+    public static int GetDaysInYear(int year, int month, int day)
+    {
+        int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+        if (IsLeapYear(year))
+        {
+            daysInMonths[1] = 29;
+        }
+        int days = day;
+        for (int i = 0; i < month - 1; i++)
+        {
+            days += daysInMonths[i];
+        }
+        return days;
+    }
+
+    public static bool IsLeapYear(int year)
+    {
+        return (year % 4 == 0 && year % 100!= 0) || (year % 400 == 0);
+    }
+}

+ 123 - 21
Models/SimulationCommon/EditorConfig.cs

@@ -5,8 +5,8 @@ public class Base
 {
     [JsonProperty("基地名称")]
     public string BaseName;
-    [JsonProperty("位置信息")]
-    public string BasePositionInfo;
+    //[JsonProperty("位置信息")]
+    //public string BasePositionInfo;
     [JsonProperty("基地编号")]
     public int BaseId;
     [JsonProperty("基地经度")]
@@ -29,12 +29,12 @@ public struct AircraftParameter
     public string AircraftSubType;
     [JsonProperty("所属机场ID")]
     public int AirportId;
-    [JsonProperty("状态")]
-    public string AircraftState;
-    [JsonProperty("已连续工作时间")]
-    public double AircraftRunTime;
-    //[JsonProperty("任务载荷型号")]
-    //public Dictionary<string,string> taskLoadType;
+    //[JsonProperty("状态")]
+    //public string AircraftState;
+    //[JsonProperty("已连续工作时间")]
+    //public double AircraftRunTime;
+    [JsonProperty("任务载荷型号")]
+    public TaskLoadType taskLoadType;
     [JsonProperty("最大起飞重量")]
     public double MaxTakeoffWeight;
     [JsonProperty("最大载油量")]
@@ -118,18 +118,110 @@ public class TargetPoint//搜救目标点初始坐标
     public double TargetPointLatitude;
     [JsonProperty("目标点海拔")]
     public double TargetPointHeight;
+    [JsonProperty("目标气象信息")]
+    public TargetQiXiangInfo TargetQiXiangInfo;
     [JsonProperty("目标类型")]
     public TargetType TargetType;
 }
 
+public class TargetQiXiangInfo
+{
+    [JsonProperty("00-08温度")]
+    public double Temperature_00_08;
+    [JsonProperty("00-08湿度")]
+    public double Humidity_00_08;
+    [JsonProperty("00-08能见度")]
+    public double Visibility_00_08;
+    [JsonProperty("00-08风速")]
+    public double WindSpeed_00_08;
+    [JsonProperty("00-08风向")]
+    public double WindDirection_00_08;
+    [JsonProperty("00-08天气")]
+    public string Weather_00_08;
+    [JsonProperty("08-19温度")]
+    public double Temperature_08_19;
+    [JsonProperty("08-19湿度")]
+    public double Humidity_08_19;
+    [JsonProperty("08-19能见度")]
+    public double Visibility_08_19;
+    [JsonProperty("08-19风速")]
+    public double WindSpeed_08_19;
+    [JsonProperty("08-19风向")]
+    public double WindDirection_08_19;
+    [JsonProperty("08-19天气")]
+    public string Weather_08_19;
+    [JsonProperty("19-24温度")]
+    public double Temperature_19_24;
+    [JsonProperty("19-24湿度")]
+    public double Humidity_19_24;
+    [JsonProperty("19-24能见度")]
+    public double Visibility_19_24;
+    [JsonProperty("19-24风速")]
+    public double WindSpeed_19_24;
+    [JsonProperty("19-24风向")]
+    public double WindDirection_19_24;
+    [JsonProperty("19-24天气")]
+    public string Weather_19_24;
+}
+
 public class TargetType
 {
     [JsonProperty("类型")]
     public string Type;
-    [JsonProperty("目标大小")]
-    public string Size;
-    [JsonProperty("目标吨位")]
-    public string Tonnage;
+    [JsonProperty("人员数量")]
+    public int Count;
+    [JsonProperty("重量")]
+    public double Weight;
+    [JsonProperty("载人数")]
+    public int LoadCount;
+    [JsonProperty("吨位")]
+    public double Tonnage;
+    [JsonProperty("长度")]
+    public double Length;
+    [JsonProperty("携带定位设备")]
+    public bool GPS;
+    [JsonProperty("预计剩余存活时间")]
+    public double LiveTime;
+    [JsonProperty("雷达截面面积")]
+    public double RadarArea;
+    [JsonProperty("探测目标面积")]
+    public double TargetArea;
+    [JsonProperty("探测目标亮度")]
+    public double TargetBrightness;
+    [JsonProperty("时间窗口")]
+    public double Time;
+}
+
+public class RescueDemandInfo//救援需求信息
+{
+    [JsonProperty("需求点名称")]
+    public string DemandPointName;
+    [JsonProperty("需求点ID")]
+    public int DemandPointID;
+    [JsonProperty("目标点经度")]
+    public double TargetPointLongitude;
+    [JsonProperty("目标点纬度")]
+    public double TargetPointLatitude;
+    [JsonProperty("目标点海拔")]
+    public double TargetPointHeight;
+    [JsonProperty("目标气象信息")]
+    public TargetQiXiangInfo TargetQiXiangInfo;
+    [JsonProperty("目标类型")]
+    public TargetType TargetType;
+}
+
+public class GoodsPersonPoint//物资人员点
+{
+    [JsonProperty("物资点名称")]
+    public string GoodsPointName;
+    [JsonProperty("物资点编号")]
+    public int GoodsPointID;
+    [JsonProperty("取水点经度")]
+    public double WaterPointLongitude;
+    [JsonProperty("取水点纬度")]
+    public double WaterPointLatitude;
+    [JsonProperty("取水点海拔")]
+    public double WaterPointHeight;
 }
 
 public class ClimbSegment
@@ -259,15 +351,25 @@ public class GridArea
 
 public class EditorConfig
 {
-    [JsonProperty("仿真次数")] public int runCounts;
-    [JsonProperty("想定信息")] public ScenarioInfo scenarioInfo = new ScenarioInfo();
-    [JsonProperty("基地信息")] public List<Base> bases = new List<Base>();
-    [JsonProperty("飞行器信息")] public List<AircraftParameter> aircraftParameters = new List<AircraftParameter>();
-    [JsonProperty("火点")] public List<FirePoint> firePoints = new List<FirePoint>();
-    [JsonProperty("取水点")] public List<WaterPoint> waterPoints = new List<WaterPoint>();
-    [JsonProperty("天气信息")] public CityWeather cityWeather = new CityWeather();
-    [JsonProperty("搜救目标点初始坐标")] public List<TargetPoint> targetPoints = new List<TargetPoint>();
-    [JsonProperty("通信对象设定")] public CommunicationSet communicationSets = new CommunicationSet();
+    [JsonProperty("仿真次数")]
+    public int runCounts;
+    [JsonProperty("想定信息")]
+    public ScenarioInfo scenarioInfo = new ScenarioInfo();
+    [JsonProperty("基地信息")]
+    public List<Base> bases = new List<Base>();
+    [JsonProperty("飞行器信息")]
+    public List<AircraftParameter>aircraftParameters = new List<AircraftParameter>();
+    [JsonProperty("火点")]
+    public List<FirePoint> firePoints = new List<FirePoint>();
+    [JsonProperty("天气信息")]
+    public CityWeather cityWeather = new CityWeather();
+    [JsonProperty("搜救目标点初始坐标")]
+    public List<TargetPoint> targetPoints = new List<TargetPoint>();
+    [JsonProperty("救援需求信息")]
+    public List<RescueDemandInfo> rescueDemandInfos = new List<RescueDemandInfo>();
+    [JsonProperty("物资人员点")]
+    public List<GoodsPersonPoint> goodsPersonPoints = new List<GoodsPersonPoint>();
+     [JsonProperty("通信对象设定")] public CommunicationSet communicationSets = new CommunicationSet();
 }
 
 

+ 113 - 0
Models/SimulationCommon/EquationHelper.cs

@@ -7,6 +7,7 @@ using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using SJ;
 using Model;
+using MathNet.Numerics;
 
 namespace MuShiApp
 {
@@ -133,6 +134,80 @@ namespace MuShiApp
             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)
@@ -363,6 +438,44 @@ namespace MuShiApp
             }
         }
 
+        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<string> { "centerLon", "centerLat", "visibility_date" }
+                };
+                string response = m_HttpHelper.Request(cmd, new List<string> { centerLon.ToString(), centerLat.ToString(), visibility_date });
+                //Console.WriteLine(" centerLon:" + centerLon + " " + "centerLat:" + centerLat + " " + "visibility_date:" + visibility_date);
+                //Console.WriteLine("response:" + response);
+                R data = JsonConvert.DeserializeObject<R>(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
 
         // {

+ 160 - 75
Models/SimulationCommon/FXJHGenenrate.cs

@@ -192,6 +192,18 @@ namespace Model
                 SegmentFlightTime = resulttime,
                 RemainingFuel = 0,
             });
+
+            turningPoints.Add(new TurningPoint
+            {
+                TurningPointName = "索滑降",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "索滑降",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
         }
 
         public static void XunHu(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
@@ -346,6 +358,135 @@ namespace Model
             });
         }
 
+
+        public static void KouTouKouSong(FlightPlanEditor editor, ref List<TurningPoint> turningPoint)
+        {
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
+        }
+
+        public static void KouTouKouSong1(MissionPoint missionpoint, ref List<TurningPoint> turningPoint)
+        {
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = missionpoint.MissionPointLongitude,
+                TurningPointLatitude = missionpoint.MissionPointLatitude,
+                TurningPointHeight = missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
+        }
+
+        public static void JijiangJiuYuan1(FlightPlanEditor editor, ref List<TurningPoint> turningPoint)
+        {
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 600,
+                RemainingFuel = 0,
+            });
+
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
+        }
+        public static void JijiangJiuYuan(FlightPlanEditor editor, ref List<TurningPoint> turningPoint)
+        {
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.originbase.BaseLongitude,
+                TurningPointLatitude = editor.originbase.BaseLatitude,
+                TurningPointHeight = editor.originbase.BaseHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
+
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 600,
+                RemainingFuel = 0,
+            });
+
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
+                TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
+                TurningPointHeight = editor.missionpoint.MissionPointHeight,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 2,
+                SegmentFlightTime = 0,
+                RemainingFuel = 0,
+            });
+        }
+
+        public static void ZhaoShuiJiuYuan(List<AirRoute> airRoutes, ref List<TurningPoint> turningPoint)
+        {
+            for (int i = 0;i < airRoutes.Count; i++)
+            {
+                turningPoint.Add(new TurningPoint
+                {
+                    TurningPointName = "转运",
+                    TurningPointLongitude = airRoutes[i].AirRouteLongitude,
+                    TurningPointLatitude = airRoutes[i].AirRouteLatitude,
+                    TurningPointHeight = 1000,
+                    TurningPointType = "转运",
+                    SegmentFlightFuelConsumption = 3,
+                    SegmentFlightTime = 0,
+                    RemainingFuel = 0,
+                });
+            }
+        }
+
+        public static void ZhaoShuiJiuYuan1(List<AirRoute> airRoutes, ref List<TurningPoint> turningPoint)
+        {
+            turningPoint.Add(new TurningPoint
+            {
+                TurningPointName = "转运",
+                TurningPointLongitude = airRoutes[airRoutes.Count - 1].AirRouteLongitude,
+                TurningPointLatitude = airRoutes[airRoutes.Count - 1].AirRouteLatitude,
+                TurningPointHeight = 1000,
+                TurningPointType = "转运",
+                SegmentFlightFuelConsumption = 3,
+                SegmentFlightTime = 1800,
+                RemainingFuel = 0,
+            });
+        }
+
         public static void SeaSouJiu(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
         {
             int i;
@@ -356,7 +497,7 @@ namespace Model
                     TurningPointName = "巡航",
                     TurningPointLongitude = editor.airroute[i].AirRouteLongitude,
                     TurningPointLatitude = editor.airroute[i].AirRouteLatitude,
-                    TurningPointHeight = 2000,
+                    TurningPointHeight = 150,
                     TurningPointType = "普通",
                     SegmentFlightFuelConsumption = 3,
                     SegmentFlightTime = 0,
@@ -677,88 +818,32 @@ namespace Model
             }
         }
 
-        public static void BackToEnd(FlightPlanEditor editor, MissionEndPoint missionEndPoint,
-            ref List<TurningPoint> turningPoints, int index)
-        {
-            
-            turningPoints.Insert(index,new TurningPoint
-            {
-                TurningPointName = "平飞",
-                TurningPointLongitude = missionEndPoint.MissionEndPointLongitude,
-                TurningPointLatitude = missionEndPoint.MissionEndPointLatitude,
-                TurningPointHeight = missionEndPoint.MissionEndPointHeight,
-                TurningPointType = "普通",
-                SegmentFlightFuelConsumption = 3,
-                SegmentFlightTime = 0,
-                RemainingFuel = 0,
-            });
-
-
-            //double k;
-            double lat2, lon2;
-            lat2 = (turningPoints[^1].TurningPointLatitude + editor.endbase.BaseLatitude) / 2;
-            lon2 = (turningPoints[^1].TurningPointLongitude + editor.endbase.BaseLongitude) / 2;
-
-            turningPoints.Insert(index + 1,new TurningPoint
-            {
-                TurningPointName = "降高",
-                TurningPointLongitude = lon2,
-                TurningPointLatitude = lat2,
-                TurningPointHeight = 2000,
-                TurningPointType = "普通",
-                SegmentFlightFuelConsumption = 4,
-                SegmentFlightTime = 0,
-                RemainingFuel = 0,
-            });
-            
-            turningPoints.Insert(index+2,new TurningPoint
-            {
-                TurningPointName = "返回基地",
-                TurningPointLongitude = editor.endbase.BaseLongitude,
-                TurningPointLatitude = editor.endbase.BaseLatitude,
-                TurningPointHeight = editor.endbase.BaseHeight,
-                TurningPointType = "普通",
-                SegmentFlightFuelConsumption = 4,
-                SegmentFlightTime = 0,
-                RemainingFuel = 0,
-            });
-        }
-
 
-        public static double CalculateTotalFuelConsumption(FlightPlanEditor editor, List<TurningPoint> turningPoints)
+        public static void CalculateTrueHeading(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
         {
-            double initialFuel = editor.aircraftparameter.MaxFuelCapacity; // 起始燃油量
-            double totalFuelConsumption = 0; // 总燃油消耗量
-            double totalRefuelAmount = 0; // 总加油量
-
-            for (int i = 0; i < turningPoints.Count; i++)
+            for (int i = 0; i < turningPoints.Count - 1; i++)
             {
-                //// 更新飞行过程中的燃油消耗
-                //if (i ==0)
-                //{
-                //    double segmentFuelConsumed = initialFuel - turningPoints[i].RemainingFuel;
-                //}
-                //else
-                //{
-                //    double segmentFuelConsumed = (turningPoints[i - 1].RemainingFuel - turningPoints[i].RemainingFuel);
-                //    totalFuelConsumption += segmentFuelConsumed;
-                //}
+                // 转换为弧度
+                double lat1Rad = turningPoints[i].TurningPointLatitude * Math.PI / 180;
+                double lon1Rad = turningPoints[i].TurningPointLongitude * Math.PI / 180;
+                double lat2Rad = turningPoints[i + 1].TurningPointLatitude * Math.PI / 180;
+                double lon2Rad = turningPoints[i + 1].TurningPointLongitude * Math.PI / 180;
+                double deltaLon = lon2Rad - lon1Rad;
 
-                // 如果当前航路点是加油点,更新燃油并记录加油量
-                if (turningPoints[i].TurningPointType == "加油")
-                {
-                    double refuelAmount = editor.aircraftparameter.MaxFuelCapacity - turningPoints[i - 2].RemainingFuel;
-                    totalRefuelAmount += refuelAmount;
-                }
-            }
+                double x = Math.Sin(deltaLon) * Math.Cos(lat2Rad);
+                double y = Math.Cos(lat1Rad) * Math.Sin(lat2Rad) - Math.Sin(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(deltaLon);
 
-            // 最终燃油消耗 = 初始燃油 + 总加油量 - 最终剩余燃油
-            double finalFuel = turningPoints.Last().RemainingFuel;
-            totalFuelConsumption = (initialFuel + totalRefuelAmount) - finalFuel;
+                // 计算航向角
+                double headingRad = Math.Atan2(x, y);
 
-            return totalFuelConsumption;
+                // 转换为度并标准化
+                double headingDeg = headingRad * 180 / Math.PI;
+                headingDeg = (headingDeg + 360) % 360;
+                turningPoints[i].HeadingAngle = headingDeg;
+            }
         }
 
+
         /// <summary>
         /// 巡护用
         /// </summary>

+ 1 - 0
Models/SimulationCommon/FlightPlanEditor.cs

@@ -17,6 +17,7 @@ public class FlightPlanEditor
   
     [JsonProperty("任务点")]
     public MissionPoint missionpoint = new MissionPoint();
+
     [JsonProperty("火点")]
     public FirePoint[] firepoint = new FirePoint[1];
     [JsonProperty("搜救目标初始点")]

+ 153 - 52
Models/SimulationCommon/Rectangular_Area_Search_Function.cs

@@ -106,89 +106,190 @@ public class Rectangular_Area_Search_Function
 
     public static List<double[]> MinEnclosingRectangle(Point2f[] hull)
     {
-         double min_rectangular_area = double.PositiveInfinity;
-            List<double[]> Point_muster = new List<double[]>{};
+        double min_rectangular_area = double.PositiveInfinity;
+        List<double[]> Point_muster = new List<double[]> { };
 
-            for (int num = 0; num < hull.Length - 1; num++)
+        for (int num = 0; num < hull.Length - 1; num++)
+        {
+            double[] Base_line = GetLinearEquation(hull[num], hull[num + 1]);
+            double max_Ditance = 0;
+            Point2f Point = hull[num + 1];
+            Point2f Point_left = hull[num + 1];
+            Point2f Point_right = hull[num + 1];
+
+            foreach (Point2f i_point in hull)
             {
-                double[] Base_line = GetLinearEquation(hull[num], hull[num + 1]);
-                double max_Ditance = 0;
-                Point2f Point = hull[num + 1];
+                if ((i_point.X == hull[num].X && i_point.Y == hull[num].Y) ||
+                    (i_point.X == hull[num + 1].X && i_point.Y == hull[num + 1].Y))
+                {
+                    continue;
+                }
 
-                foreach (Point2f i_point in hull)
+                double distance = GetDistance(i_point, Base_line);
+
+                if (distance > max_Ditance)
                 {
-                    if ((i_point.X == hull[num].X && i_point.Y == hull[num].Y) ||
-                        (i_point.X == hull[num + 1].X && i_point.Y == hull[num + 1].Y))
+                    max_Ditance = distance;
+                    Point = i_point;
+                }
+            }
+
+            double[] line_Parallel_Base = GetParallelLine(Point, Base_line);
+
+            double[] line_Perpendicular_Base_right = null;
+            double[] line_Perpendicular_Base_left = null;
+
+            foreach (Point2f j_point in hull)
+            {
+                double[] line_Preparatory = GetpPerpendicular(j_point, Base_line);
+                int point_right = 0;
+                int point_left = 0;
+
+                foreach (Point2f k_point in hull)
+                {
+                    if (k_point.X == j_point.X && k_point.Y == j_point.Y)
                     {
                         continue;
                     }
 
-                    double distance = GetDistance(i_point, Base_line);
-
-                    if (distance > max_Ditance)
+                    //添加点在直线上的条件
+                    if (CheckDirection(k_point, line_Preparatory) <= 0)
                     {
-                        max_Ditance = distance;
-                        Point = i_point;
+                        point_left++;
+                    }
+                    else if (CheckDirection(k_point, line_Preparatory) >= 0)
+                    {
+                        point_right++;
                     }
                 }
 
-                double[] line_Parallel_Base = GetParallelLine(Point, Base_line);
-
-                double[] line_Perpendicular_Base_right = null;
-                double[] line_Perpendicular_Base_left = null;
+                if (point_right == hull.Length - 1)
+                {
+                    line_Perpendicular_Base_right = line_Preparatory;
+                }
 
-                foreach (Point2f j_point in hull)
+                if (point_left == hull.Length - 1)
                 {
-                    double[] line_Preparatory = GetpPerpendicular(j_point, Base_line);
-                    int point_right = 0;
-                    int point_left = 0;
+                    line_Perpendicular_Base_left = line_Preparatory;
+                }
+            }
 
-                    foreach (Point2f k_point in hull)
-                    {
-                        if (k_point.X == j_point.X && k_point.Y == j_point.Y)
-                        {
-                            continue;
-                        }
+            if (line_Perpendicular_Base_left == null || line_Perpendicular_Base_right == null)
+            {
+                double max_Ditance_left = 0;
+                double distance_left = 0;
+                double max_Distance_right = 0;
+                double distance_right = 0;
 
-                        if (CheckDirection(k_point, line_Preparatory) < 0)
-                        {
-                            point_left++;
-                        }
-                        else
+                double[] line_inite_Preparatory = GetpPerpendicular(hull[num], Base_line);
+
+                foreach (Point2f m_point in hull)
+                {
+                    if (CheckDirection(m_point, line_inite_Preparatory) <= 0)
+                    {
+                        distance_left = GetDistance(m_point, line_inite_Preparatory);
+                        if (distance_left >= max_Ditance_left)
                         {
-                            point_right++;
+                            max_Ditance_left = distance_left;
+                            Point_left = m_point;
+                            line_Perpendicular_Base_left = GetpPerpendicular(Point_left, Base_line);
                         }
                     }
-
-                    if (point_right == hull.Length - 1)
+                    if (CheckDirection(m_point, line_inite_Preparatory) >= 0)
                     {
-                        line_Perpendicular_Base_right = line_Preparatory;
+                        distance_right = GetDistance(m_point, line_inite_Preparatory);
+                        if (distance_right >= max_Distance_right)
+                        {
+                            max_Distance_right = distance_right;
+                            Point_right = m_point;
+                            line_Perpendicular_Base_right = GetpPerpendicular(Point_right, Base_line);
+                        }
                     }
 
-                    if (point_left == hull.Length - 1)
-                    {
-                        line_Perpendicular_Base_left = line_Preparatory;
-                    }
                 }
 
-                double[] Point0 = GetCrossPoint(Base_line, line_Perpendicular_Base_left);
-                double[] Point1 = GetCrossPoint(Base_line, line_Perpendicular_Base_right);
-                double[] Point2 = GetCrossPoint(line_Parallel_Base, line_Perpendicular_Base_right);
-                double[] Point3 = GetCrossPoint(line_Parallel_Base, line_Perpendicular_Base_left);
-                double rectangular_area = GetRectangularArea(Point0, Point1, Point2, Point3);
+            }
 
-                if (rectangular_area < min_rectangular_area)
-                {
-                    min_rectangular_area = rectangular_area;
-                    Point_muster = new List<double[]> {
+            double[] Point0 = GetCrossPoint(Base_line, line_Perpendicular_Base_left);
+            double[] Point1 = GetCrossPoint(Base_line, line_Perpendicular_Base_right);
+            double[] Point2 = GetCrossPoint(line_Parallel_Base, line_Perpendicular_Base_right);
+            double[] Point3 = GetCrossPoint(line_Parallel_Base, line_Perpendicular_Base_left);
+
+            //List<double> temp0 = new List<double>();
+            //List<double> temp1 = new List<double>();
+            //List<double> temp2 = new List<double>();
+            //List<double> temp3 = new List<double>();
+
+            //double lat0 = Point0[0];
+            //double lon0 = Point0[1];
+            //double lat1 = Point1[0];
+            //double lon1 = Point1[1];
+            //double lat2 = Point2[0];
+            //double lon2 = Point2[1];
+            //double lat3 = Point3[0];
+            //double lon3 = Point3[1];
+
+            //temp0.Add(Math.Max(Math.Max(Math.Max(lat0, lat1), lat2), lat3));
+            //temp0.Add(Math.Min(Math.Min(Math.Min(lon0, lon1), lon2), lon3));
+
+            //temp1.Add(Math.Max(Math.Max(Math.Max(lat0, lat1), lat2), lat3));
+            //temp1.Add(Math.Max(Math.Max(Math.Max(lon0, lon1), lon2), lon3));
+
+            //temp2.Add(Math.Min(Math.Min(Math.Min(lat0, lat1), lat2), lat3));
+            //temp2.Add(Math.Max(Math.Max(Math.Max(lon0, lon1), lon2), lon3));
+
+            //temp3.Add(Math.Min(Math.Min(Math.Min(lat0, lat1), lat2), lat3));
+            //temp3.Add(Math.Min(Math.Min(Math.Min(lon0, lon1), lon2), lon3));
+
+            //Point0 = temp0.ToArray();
+            //Point1 = temp1.ToArray();
+            //Point2 = temp2.ToArray();
+            //Point3 = temp3.ToArray();
+
+            double rectangular_area = GetRectangularArea(Point0, Point1, Point2, Point3);
+
+            if (rectangular_area < min_rectangular_area)
+            {
+                min_rectangular_area = rectangular_area;
+                Point_muster = new List<double[]> {
                         Point0,
                         Point1,
                         Point2,
                         Point3
                     };
-                }
             }
 
-            return Point_muster;
+
+
+            //double lat = Rectangular_Area_Search_Function.RMokatuoLat(Point0[0]);
+            //double lon = Rectangular_Area_Search_Function.RMokatuoLon(Point0[1]);
+            //Console.WriteLine("Point0:" + lat + "-" + lon);
+
+            //double lat1 = Rectangular_Area_Search_Function.RMokatuoLat(Point1[0]);
+            //double lon1 = Rectangular_Area_Search_Function.RMokatuoLon(Point1[1]);
+            //Console.WriteLine("Point1:" + lat1 + "-" + lon1);
+
+            //double lat2 = Rectangular_Area_Search_Function.RMokatuoLat(Point2[0]);
+            //double lon2 = Rectangular_Area_Search_Function.RMokatuoLon(Point2[1]);
+            //Console.WriteLine("Point2:" + lat2 + "-" + lon2);
+
+            //double lat3 = Rectangular_Area_Search_Function.RMokatuoLat(Point3[0]);
+            //double lon3 = Rectangular_Area_Search_Function.RMokatuoLon(Point3[1]);
+            //Console.WriteLine("Point3:" + lat3 + "-" + lon3);
         }
+
+        //foreach (var item in Point_muster)
+        //{
+        //    Console.WriteLine("Point_muster:" + item[0] + "-" + item[1]);
+        //}
+        min_area = GetRectangularArea(Point_muster[0], Point_muster[1], Point_muster[2], Point_muster[3]);
+
+        //double width = Math.Sqrt(Math.Pow(Point_muster[0][0] - Point_muster[1][0], 2) + Math.Pow(Point_muster[0][1] - Point_muster[1][1], 2));
+        //double height = Math.Sqrt(Math.Pow(Point_muster[1][0] - Point_muster[2][0], 2) + Math.Pow(Point_muster[1][1] - Point_muster[2][1], 2));
+        //Console.WriteLine("width:" + width + "-" + "height:" + height);
+        return Point_muster;
+    }
+
+
+    public static double min_area;
 }

+ 89 - 36
Models/SimulationCommon/SeaSJ.cs

@@ -26,12 +26,12 @@ public class Current
 
 public class NCread
 {
-        
+
     //各数组来源文件'Text_readNC.cs';时间范围:2024-06-04T00:00:00 ... 2024-06-04T23:00:00;
     //地点范围:落水点为中心100公里
     public float[] longitudeArray = new float[10];//经度一维数组来源自文件'Text_readNC.cs'
     public float[] latitudeArray = new float[7];//纬度一维数组来源自文件'Text_readNC.cs'
-    public float[][][] u10Array ;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs'
+    public float[][][] u10Array;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs'
     public float[][][] v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs'
     public float[][][] p140208Array;//海洋上空的自由对流速度三维数组来源自文件'Text_readNC.cs'
     public float[][][] mwdArray;//平均波向(单位:度;0度表示北方,90度表示东方)三维数组来源自文件'Text_readNC.cs'       
@@ -52,15 +52,15 @@ public class SeaSJ
     }
 
     // 交付类方法
-    public static List<double[]> GetDrift(NCread nCread,double[] initialPosition, double dt, double totalTime)
+    public static List<double[]> GetDrift(NCread nCread, double[] initialPosition, double dt, double totalTime, int times, int latitudes, int longitudes, int times1, int latitudes1, int longitudes1, int times2, int latitudes2, int longitudes2, int times3, int latitudes3, int longitudes3, int days, int hour, double initlatitudes, double initlongitudes)
     {
         // run 获取轨迹的函数
         // initialPosition --> 初始位置; dt --> 时间步长; totalTime --> 总时长
-        List<double[]> trajectory = CalculateDriftTrajectory(nCread,initialPosition, dt, totalTime);
+        List<double[]> trajectory = CalculateDriftTrajectory(nCread, initialPosition, dt, totalTime, times, latitudes, longitudes, times1, latitudes1, longitudes1, times2, latitudes2, longitudes2, times3, latitudes3, longitudes3, days, hour, initlatitudes, initlongitudes);
         return trajectory;
     }
 
-    public static List<double[]> CalculateDriftTrajectory(NCread nCread,double[] initialPosition, double dt, double totalTime)
+    public static List<double[]> CalculateDriftTrajectory(NCread nCread, double[] initialPosition, double dt, double totalTime, int times, int latitudes, int longitudes, int times1, int latitudes1, int longitudes1, int times2, int latitudes2, int longitudes2, int times3, int latitudes3, int longitudes3, int days, int hour, double initlatitudes, double initlongitudes)
     {
         int timeSteps = (int)(totalTime / dt);
         List<double[]> trajectory = new List<double[]>();
@@ -72,20 +72,36 @@ public class SeaSJ
 
             int outputTime = 3600 * t;
             // 动态获取当前位置的风力和洋流数据
-            double[] windVelocity = GetWindVelocityFromAPI(nCread,currentPos[0], currentPos[1], outputTime);
-            double[] currentVelocity = GetCurrentVelocityFromAPI(nCread,currentPos[0], currentPos[1], outputTime);
-
+            double[] windVelocity = GetWindVelocityFromAPI(nCread, currentPos[0], currentPos[1], outputTime, times, latitudes, longitudes, times1, latitudes1, longitudes1, days, hour);
+            double[] currentVelocity = GetCurrentVelocityFromAPI(nCread, currentPos[0], currentPos[1], outputTime, times2, latitudes2, longitudes2, times3, latitudes3, longitudes3, days, hour);
+            //foreach (var item in windVelocity)
+            //{
+            //    Console.WriteLine("windVelocity:" + item);
+            //}
+            //foreach (var item in currentVelocity)
+            //{
+            //    Console.WriteLine("currentVelocity:" + item);
+            //}
             // 计算漂移速度(m/s)
             double[] driftVelocity = {
                 currentVelocity[0] + windVelocity[0],
                 currentVelocity[1] + windVelocity[1]
             };
-
+            //foreach (var item in driftVelocity)
+            //{
+            //    Console.WriteLine("driftVelocity:" + item);
+            //}
             // 更新位置(漂移速度单位是m/s,需要转换成经纬度的变化量)
             double[] newPosition = {
                 currentPos[0] + (driftVelocity[0] * dt * 3600) / ((6371000 * Math.Cos(currentPos[0] * Math.PI / 180)) * 180 / Math.PI), // 纬度变化量
                 currentPos[1] + (driftVelocity[1] * dt * 3600) / ((6371000 * Math.Cos(currentPos[1] * Math.PI / 180)) * 180 / Math.PI)  // 经度变化量
             };
+            //foreach (var item in newPosition)
+            //{
+            //    Console.WriteLine("newPosition:" + item);
+            //}
+            //Console.WriteLine("currentPos[0]:" + (driftVelocity[0] * dt * 3600) / ((6371000 * Math.Cos(currentPos[0] * Math.PI / 180)) * 180 / Math.PI));
+            //Console.WriteLine("currentPos[1]:" + (driftVelocity[1] * dt * 3600) / ((6371000 * Math.Cos(currentPos[1] * Math.PI / 180)) * 180 / Math.PI));
 
             trajectory.Add(newPosition);
         }
@@ -93,7 +109,7 @@ public class SeaSJ
         return trajectory;//(纬度,经度)
     }
 
-    public static double[] GetWindVelocityFromAPI(NCread windNCread,double latitude, double longitude, double temptime)
+    public static double[] GetWindVelocityFromAPI(NCread windNCread, double latitude, double longitude, double temptime, int times, int latitudes, int longitudes, int times1, int latitudes1, int longitudes1, int days, int hour)
     {
         float[] longitudeArray = windNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs'
         float[] latitudeArray = windNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs'
@@ -105,7 +121,7 @@ public class SeaSJ
         int temptimeNum = 0;
         //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
         //经度连续化
-        for (int i = 0; i < 9; i++)
+        for (int i = 0; i < longitudes - 1; i++)
         {
             if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
             {
@@ -115,7 +131,7 @@ public class SeaSJ
         }
 
         //纬度连续化
-        for (int i = 0; i < 6; i++)
+        for (int i = 0; i < latitudes - 1; i++)
         {
             if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
             {
@@ -123,9 +139,9 @@ public class SeaSJ
                 latitudeNum = i;
             }
         }
-        
+
         //时间连续化
-        for (int i = 0; i < 23 ; i ++)
+        for (int i = 0; i < times - 1; i++)
         {
             if (temptime >= 3600 * i && temptime < (3600 * (i + 1)))
             {
@@ -133,19 +149,31 @@ public class SeaSJ
             }
         }
 
+        temptimeNum += (days - 1) * 24 + hour;
+
         double windX = (double)u10Array[temptimeNum][latitudeNum][longitudeNum];
-        double windY = (double)v10Array[temptimeNum][latitudeNum][ longitudeNum];
+        double windY = (double)v10Array[temptimeNum][latitudeNum][longitudeNum];
 
         return new double[] { windX, windY };
     }
 
-    public static double[] GetCurrentVelocityFromAPI(NCread CurrentNCread,double latitude, double longitude, double temptime)
+    public static double[] GetCurrentVelocityFromAPI(NCread CurrentNCread, double latitude, double longitude, double temptime, int times2, int latitudes2, int longitudes2, int times3, int latitudes3, int longitudes3, int days, int hour)
     {
         float[] longitudeArray = CurrentNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs'
         float[] latitudeArray = CurrentNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs'
         float[][][] u10Array = CurrentNCread.u10Array;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs'
         float[][][] v10Array = CurrentNCread.v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs'
         float[][][] p140208Array = CurrentNCread.p140208Array;//海洋上空的自由对流速度三维数组来源自文件'Text_readNC.cs'
+        //foreach (var item in p140208Array)
+        //{
+        //    foreach (var item1 in item)
+        //    {
+        //        foreach (var item2 in item1)
+        //        {
+        //            Console.WriteLine("p140208Array:" + item2);
+        //        }
+        //    }
+        //}
         float[][][] mwdArray = CurrentNCread.mwdArray;//平均波向(单位:度;0度表示北方,90度表示东方)三维数组来源自文件'Text_readNC.cs'
 
         int longitudeNum = 0;
@@ -153,7 +181,7 @@ public class SeaSJ
         int temptimeNum = 0;
         //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
         //经度连续化
-        for (int i = 0; i < 9; i++)
+        for (int i = 0; i < longitudes2 - 1; i++)
         {
             if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
             {
@@ -163,7 +191,7 @@ public class SeaSJ
         }
 
         //纬度连续化
-        for (int i = 0; i < 6; i++)
+        for (int i = 0; i < latitudes2 - 1; i++)
         {
             if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
             {
@@ -171,27 +199,39 @@ public class SeaSJ
                 latitudeNum = i;
             }
         }
-        
+
         //时间连续化
-        for (int i = 0; i < 23; i++)
+        for (int i = 0; i < times2 - 1; i++)
         {
-            if (temptime >= 3600 * 1 && temptime < 3600 * (i + 1))
+            if (temptime >= 3600 * i && temptime < 3600 * (i + 1))
             {
                 temptimeNum = i;
             }
         }
-        double currentSpeed = (double)p140208Array[temptimeNum][latitudeNum][ longitudeNum];
-        double currentDirection = (double)mwdArray[temptimeNum][latitudeNum][ longitudeNum];
-
+        temptimeNum += (days - 1) * 24 + hour;
+        //foreach (var item in p140208Array)
+        //{
+        //    Console.WriteLine("p140208Array:" + (double)p140208Array[0][1][2]);
+        //}
+        //Console.WriteLine("p140208Array:" + (double)p140208Array[2640][1][2]);
+        double currentSpeed = (double)p140208Array[temptimeNum][latitudeNum][longitudeNum];
+        Random random = new Random();
+        if (currentSpeed > 10)
+            currentSpeed = random.NextDouble();
+        //Console.WriteLine("temptimeNum:" + temptimeNum + "_" + "latitudeNum:" + latitudeNum + "_" + "longitudeNum:" + longitudeNum);
+        double currentDirection = (double)mwdArray[temptimeNum][latitudeNum][longitudeNum];
+        //double currentSpeed = (double)p140208Array[2401][0][0];
+        //Console.WriteLine("currentSpeed:" + currentSpeed);
+        //Console.WriteLine("currentDirection:" + currentDirection);
         double currentDirectionInRadians = currentDirection * (Math.PI / 180);
         double currentX = currentSpeed * Math.Cos(currentDirectionInRadians);
         double currentY = currentSpeed * Math.Sin(currentDirectionInRadians);
 
         return new double[] { currentX, currentY };
-    } 
-    
+    }
+
     //海浪高度获取
-   public static double GetWaveHeightFromAPI(NCread WaveNCread,double latitude, double longitude, double temptime)//temptime:仿真时间(秒)
+    public static double GetWaveHeightFromAPI(NCread WaveNCread, double latitude, double longitude, double temptime, int times4, int latitudes4, int longitudes4, int days, int hour)//temptime:仿真时间(秒)
     {
         float[] longitudeArray = WaveNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs'
         float[] latitudeArray = WaveNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs'
@@ -203,7 +243,7 @@ public class SeaSJ
 
         //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
         //经度连续化
-        for (int i = 0; i < 9; i++)
+        for (int i = 0; i < longitudes4 - 1; i++)
         {
             if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
             {
@@ -213,7 +253,7 @@ public class SeaSJ
         }
 
         //纬度连续化
-        for (int i = 0; i < 6; i++)
+        for (int i = 0; i < latitudes4 - 1; i++)
         {
             if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
             {
@@ -223,19 +263,19 @@ public class SeaSJ
         }
 
         //时间连续化
-        for (int i = 0; i < 23 ; i ++)
+        for (int i = 0; i < times4 - 1; i++)
         {
             if (temptime >= 3600 * i && temptime < (3600 * (i + 1)))
             {
                 temptimeNum = i;
             }
         }
-
-        double WaveHeight = (double)hmaxArray[temptimeNum][ latitudeNum][ longitudeNum];
+        temptimeNum += (days - 1) * 24 + hour;
+        double WaveHeight = (double)hmaxArray[temptimeNum][latitudeNum][longitudeNum];
 
         return WaveHeight;
     }
-    
+
     // 交付部分方法代码
     public static List<double[]> getminEnclosingRect(List<double[]> latLonList)
     {
@@ -250,7 +290,7 @@ public class SeaSJ
 
         // 获取凸包
         Point2f[] convexHull = Rectangular_Area_Search_Function.GetConvexHull(pointList);
-        
+
         //获取凸包各点经纬度坐标
         List<double[]> hullPoint = new List<double[]>();
         for (int num = 0; num < convexHull.Length - 1; num++)
@@ -265,9 +305,16 @@ public class SeaSJ
             double pointLon = Rectangular_Area_Search_Function.RMokatuoLon(point[0]);
             hullPointLatLon.Add(new double[] { pointLat, pointLon });
         }
-        
+
         // 计算最小包围矩形
         List<double[]> minEnclosingRect = Rectangular_Area_Search_Function.MinEnclosingRectangle(convexHull);
+        //foreach (var point in minEnclosingRect)
+        //{
+        //    foreach (var item in point)
+        //    {
+        //        Console.WriteLine("item:" + item);
+        //    }
+        //}
 
         // 最小包围矩形顶点经纬度坐标
         List<double[]> startPoint = new List<double[]>();
@@ -277,7 +324,13 @@ public class SeaSJ
             double lon = Rectangular_Area_Search_Function.RMokatuoLon(minEnclosingRectPoint[1]);
             startPoint.Add(new double[] { lat, lon });
         }
-
+        //foreach (var point in startPoint)
+        //{
+        //    foreach (var item in point)
+        //    {
+        //        Console.WriteLine("startPoint:" + item);
+        //    }
+        //}
         return startPoint;
     }
 }

+ 2 - 0
Models/SimulationCommon/SimulationCommon.csproj

@@ -7,6 +7,8 @@
     </PropertyGroup>
 
     <ItemGroup>
+      <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+      <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
       <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
       <PackageReference Include="OpenCvSharp4" Version="4.10.0.20240616" />
       <PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20240616" />

+ 35 - 5
Models/SimulationCommon/SurvivalTimeModel.cs

@@ -11,7 +11,7 @@ public class tempNCread
 public class SurvivalTimeModel
 {
     //得到在某经纬度、任务运行时间下的落水人员幸存时间
-    public static double SurvivalTime(tempNCread tempNCread, double latitude, double longitude, double time)
+    public static double SurvivalTime(tempNCread tempNCread, double latitude, double longitude, double time, int times, int latitudes, int longitudes, int days, int hour)
         //time表示任务执行时间,单位:秒,后续可以转换单位
     {
         int latitudeNum = 0;
@@ -22,9 +22,39 @@ public class SurvivalTimeModel
         float[] latitudeArray = tempNCread.latitudeArray; //纬度一维数组来源自文件'Text_readNC.cs'
         float[][][] tempArray = tempNCread.tempArray;
 
+        foreach (var item in tempArray)
+        {
+            foreach (var item1 in item)
+            {
+                for (int i = 0; i < item1.Length; i++)
+                {
+                    if (item1[i] > 60)
+                    {
+                        int index = i;
+                        while (item1[index] > 60 && index < item1.Length) {
+                            index++;
+                        }
+                        if(index < item1.Length)
+                        {
+                            item1[i] = item1[index];
+                        }
+                        else
+                        {
+                            index--;
+                            while (item1[index] > 60 && index >= 0)
+                            {
+                                index--;
+                            }
+                            item1[i] = item1[index];
+                        }
+                    }
+                }
+            }
+        }
+
         //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
         //经度连续化
-        for (int i = 0; i < 9; i++)
+        for (int i = 0; i < longitudes - 1; i++)
         {
             if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
             {
@@ -34,7 +64,7 @@ public class SurvivalTimeModel
         }
 
         //纬度连续化
-        for (int i = 0; i < 6; i++)
+        for (int i = 0; i < latitudes - 1; i++)
         {
             if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
             {
@@ -44,14 +74,14 @@ public class SurvivalTimeModel
         }
 
         //时间连续化
-        for (int i = 0; i < 23; i++)
+        for (int i = 0; i < times - 1; i++)
         {
             if (time >= (i * 3600) && time < ((i + 1) * 3600))
             {
                 timeNum = i;
             }
         }
-
+        timeNum += (days - 1) * 24 + hour;
         double temp = (double)tempArray[timeNum][ latitudeNum][ longitudeNum]; //得到该坐标和时间下的温度
 
         double time1 = 1.2860 * Math.Exp(0.1604 * temp);

+ 161 - 66
Models/SimulationCommon/TaskConfig.cs

@@ -20,6 +20,10 @@ public class MissionInformation
     public string WaterId;
     [JsonProperty("目标点ID")]
     public int TargetPointId;
+    [JsonProperty("目标点")]
+    public string TargetPoint;
+    [JsonProperty("物资人员点")]
+    public string GoodsPersonPoint;
     [JsonProperty("开始日期")]
     public string StartDate;
     [JsonProperty("开始时间")]
@@ -55,8 +59,8 @@ public class AircraftInfo
     public string AircraftId;
     [JsonProperty("加油基地")]
     public string RefuelingBase;
-    [JsonProperty("加油基地编号")]
-    public string RefuelingBaseId;
+    //[JsonProperty("加油基地编号")]
+    //public string RefuelingBaseId;
     [JsonProperty("任务结束返回点")]
     public string TaskEndReturnPoint;
     
@@ -79,6 +83,52 @@ public class AircraftInfo
     
 }
 
+public class TaskParameter
+{
+    [JsonProperty("应用飞机编号")]
+    public string AircraftId;
+    [JsonProperty("索滑降高度")]
+    public double H;
+    [JsonProperty("投送人数")]
+    public int person_number;
+    [JsonProperty("风速")]
+    public double windspeed;
+    [JsonProperty("能见度")]
+    public double vis;
+    [JsonProperty("索滑降速度")]
+    public double descendspeed;
+    [JsonProperty("索滑降点")]
+    public MissionPoint[] MissionPoints_SHJ;
+    [JsonProperty("单机总机降人数")]
+    public int LandingPersonnel;
+    [JsonProperty("机降点")]
+    public MissionPoint[] MissionPoints_JJJY;
+    [JsonProperty("单次救援人数")]
+    public int RescuePersonnel;
+    [JsonProperty("观察盘旋圈数")]
+    public int TurnsNumber;
+    [JsonProperty("开伞空投")]
+    public bool isParachute;
+    [JsonProperty("空投重量")]
+    public double airdropWeight;
+    [JsonProperty("空投迎风面积")]
+    public double airdropWindArea;
+    [JsonProperty("空投方式")]  // 悬停空投/带速空投"
+    public string airdropWay;
+    [JsonProperty("空投点")]
+    public MissionPoint[] MissionPoints_KTKS;
+    [JsonProperty("高度")]
+    public double Height;
+    [JsonProperty("吊运人数")]
+    public int liftPersonnel;
+    [JsonProperty("吊运上升速度")]
+    public double liftUpSpeed;
+    [JsonProperty("吊运下降速度")]
+    public double liftDownSpeed;
+    [JsonProperty("任务点")]
+    public MissionPoint[] MissionPoints_KZDY;
+}
+
 public class MissionPoint
 {
     [JsonProperty("任务点经度")]
@@ -136,14 +186,54 @@ public class ZCMethod
     public int SurroundNum;
 }
 
-public class SHJTask
+public class LandSouXunTask
 {
     [JsonProperty("任务信息")]
     public MissionInformation missionInformation;
     [JsonProperty("应用航空器")]
     public AircraftInfo[] aircraftInfos;
-    [JsonProperty("索滑降参数")]
-    public SHJParameter[] SHJParameters;
+    [JsonProperty("协同模式")]
+    public CollaborativeMode collaborativeMode;
+    [JsonProperty("运行约束")]
+    public RunConstraints RunConstraints;
+    //搜索任务载荷
+    [JsonProperty("搜索任务载荷")]
+    public SearchMissionPayload[] missionSearchPayloads;
+    //搜索方式
+    [JsonProperty("搜索方式")]
+    public SearchMissionMode[] SearchModes;
+    //[JsonProperty("下一个任务ID")]
+    //public string NextTaskId;
+}
+
+public class SeaSouJiuTask
+{
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("协同模式")]
+    public CollaborativeMode collaborativeMode;
+    [JsonProperty("运行约束")]
+    public RunConstraints RunConstraints;
+    //[JsonProperty("目标点ID")]
+    //public int TargetPointId;
+    [JsonProperty("搜索任务载荷")]
+    public SearchMissionPayload[] missionSearchPayloads;
+    [JsonProperty("搜索方式")]
+    public SearchMissionMode[] SearchModes;
+    //[JsonProperty("下一个任务ID")]
+    //public string NextTaskId;
+}
+
+public class SHJTask //索滑降救援任务
+{
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("任务参数")]
+    public TaskParameter[] SHJParameters;
     //[JsonProperty("索滑降高度")]
     //public double H;
     //[JsonProperty("投送人数")]
@@ -162,22 +252,50 @@ public class SHJTask
     //public string NextTaskId;
 }
 
-public class SHJParameter
+public class JJJYTask //机降救援任务
 {
-    [JsonProperty("应用飞机编号")]
-    public string AircraftId;
-    [JsonProperty("索滑降高度")]
-    public double H;
-    [JsonProperty("投送人数")]
-    public int person_number;
-    [JsonProperty("风速")]
-    public double windspeed;
-    [JsonProperty("能见度")]
-    public double vis;
-    [JsonProperty("索滑降速度")]
-    public double descendspeed;
-    [JsonProperty("索滑降点")]
-    public MissionPoint[] MissionPoints;
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("任务参数")]
+    public TaskParameter[] JJJYParameters;
+    //[JsonProperty("单机总机降人数")]
+    //public double LandingPersonnel;
+    //[JsonProperty("机降点")]
+    //public MissionPoint[] MissionPoints;
+    //[JsonProperty("下一个任务ID")]
+    //public string NextTaskId;
+}
+
+public class ZSJYTask //着水救援任务
+{
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("任务参数")]
+    public TaskParameter[] ZSJYParameters;
+}
+
+public class KTKSTask //空投空送任务
+{
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("任务参数")]
+    public TaskParameter[] KTKSParameters;
+}
+
+public class KZDYTask //空中吊运救援任务
+{
+    [JsonProperty("任务信息")]
+    public MissionInformation missionInformation;
+    [JsonProperty("应用航空器")]
+    public AircraftInfo[] aircraftInfos;
+    [JsonProperty("任务参数")]
+    public TaskParameter[] KZDYParameters;
 }
 
 public class DMMHTask
@@ -244,31 +362,10 @@ public class XHTaskParamter
     
 }
 
-
-public class SeaSouJiuTask
+public class CollaborativeMode
 {
-    [JsonProperty("任务信息")]
-    public MissionInformation missionInformation;
-    [JsonProperty("应用航空器")]
-    public AircraftInfo[] aircraftInfos;
-    [JsonProperty("战术战法")]
-    public Tactic Tactic;
-    [JsonProperty("运行约束")]
-    public RunConstraints RunConstraints;
-    //[JsonProperty("目标点ID")]
-    //public int TargetPointId;
-    [JsonProperty("搜索任务载荷")]
-    public SearchMissionPayload[] missionSearchPayloads;
-    [JsonProperty("搜索方式")]
-    public SearchMissionMode[] SearchModes;
-    //[JsonProperty("下一个任务ID")]
-    //public string NextTaskId;
-}
-
-public class Tactic
-{
-    [JsonProperty("战术战法")]
-    public string tactic;
+    [JsonProperty("协同模式")]
+    public string Mode;
     [JsonProperty("跟进间距")]
     public double Spacing;
     [JsonProperty("跟进高度差")]
@@ -277,6 +374,10 @@ public class Tactic
 
 public class RunConstraints
 {
+    [JsonProperty("搜寻速度")]
+    public double searchSpeed;
+    [JsonProperty("夜间工作")]
+    public bool nightWork;
     [JsonProperty("搜索飞行速度限制")]
     public double speedLimit;
 }
@@ -308,6 +409,9 @@ public class SearchMissionPayload //搜索任务载荷
     //红外探测器视场角
     [JsonProperty("红外探测器视场角")]
     public double InfraredDetectorFieldAngle;
+    //背景亮度
+    [JsonProperty("背景亮度")]
+    public double BgBrightness;
     //飞行高度
     [JsonProperty("飞行高度")]
     public double FlightHeight;
@@ -332,26 +436,8 @@ public class SearchMissionMode //搜索方式
     public double TrueH;
     [JsonProperty("输出等高线节点间隔")]
     public int JG;
-}
-
-public class LandSouXunTask
-{
-    [JsonProperty("任务信息")]
-    public MissionInformation missionInformation;
-    [JsonProperty("应用航空器")]
-    public AircraftInfo[] aircraftInfos;
-    [JsonProperty("战术战法")]
-    public Tactic Tactic;
-    [JsonProperty("运行约束")]
-    public RunConstraints RunConstraints;
-    //搜索任务载荷
-    [JsonProperty("搜索任务载荷")]
-    public SearchMissionPayload[] missionSearchPayloads;
-    //搜索方式
-    [JsonProperty("搜索方式")]
-    public SearchMissionMode[] SearchModes;
-    //[JsonProperty("下一个任务ID")]
-    //public string NextTaskId;
+    [JsonProperty("环境搜索覆盖面积")]
+    public double LandArea;
 }
 
 public class MHTaskConfig
@@ -513,9 +599,18 @@ public class TaskConfig
     public List<SeaSouJiuTask> seaSouJiuTasks = new List<SeaSouJiuTask>();
     [JsonProperty("陆上搜寻任务")]
     public List<LandSouXunTask> LandSouXunTasks = new List<LandSouXunTask>();
-    [JsonProperty("应急通信飞行")]
+    [JsonProperty("空中吊运救援任务")]
+    public List<KZDYTask> KZDYTasks = new List<KZDYTask>();
+    [JsonProperty("空投空送任务")]
+    public List<KTKSTask> KTKSTasks = new List<KTKSTask>();
+    [JsonProperty("着水救援任务")]
+    public List<ZSJYTask> ZSJYTasks = new List<ZSJYTask>();
+    [JsonProperty("机降救援任务")]
+    public List<JJJYTask> JJJYTasks = new List<JJJYTask>();
+    [JsonProperty("索滑降救援任务")]
+    public List<SHJTask> SHJTasks = new List<SHJTask>();
+        [JsonProperty("应急通信飞行")]
     public List<YJTXFlyTask> yJTXFlyTasks = new List<YJTXFlyTask>();
     [JsonProperty("应急通信计算")]
     public List<YJTXCompuTask> yJTXCompuTasks = new List<YJTXCompuTask>();
-    
 }

+ 92 - 63
Models/SimulationCommon/Text_readNC.cs

@@ -6,10 +6,30 @@ namespace SimulationCommon;
 public class Text_readNC
 {
     public NCread windNCread = new NCread();
-    public void GetNCData()
+    public int times;
+    public int latitudes;
+    public int longitudes;
+    public int times1;
+    public int latitudes1;
+    public int longitudes1;
+    public int times2;
+    public int latitudes2;
+    public int longitudes2;
+    public int times3;
+    public int latitudes3;
+    public int longitudes3;
+    public int times4;
+    public int latitudes4;
+    public int longitudes4;
+
+    public double initlatitudes;
+    public double initlongitudes;
+
+    public bool GetNCData()
     {
-        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/DATA.nc&varName=v10&centerLon=116.41992593821296&centerLat=40.18801994965735";
-
+        //"http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/DATA.nc&varName=v10&centerLon=116.41992593821296&centerLat=40.18801994965735"
+        //string url1 = "http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_u10_v10_temp.nc&varName=v10";
+        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_u10_v10_temp.nc&varName=v10&centerLon=" + initlongitudes.ToString() + "&centerLat=" + initlatitudes.ToString();
         // Create a GET request to the specified URL
         HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(url1);
         request1.Method = "GET";
@@ -20,23 +40,26 @@ public class Text_readNC
             using (StreamReader reader1 = new StreamReader(response1.GetResponseStream()))
             {
                 string result1 = reader1.ReadToEnd();
-
+                //Console.WriteLine("result1:" + result1);
                 // Parse the JSON string into a JObject
                 JObject resultObject1 = JObject.Parse(result1);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray1 = (JArray)resultObject1["data"];
 
+                if (dataArray1 == null)
+                    return false;
+
                 // Determine the dimensions of the data array
-                int timeSteps = dataArray1.Count;
-                int latitudes = ((JArray)dataArray1[0]).Count;
-                int longitudes = ((JArray)dataArray1[0][0]).Count;
+                times = dataArray1.Count;
+                latitudes = ((JArray)dataArray1[0]).Count;
+                longitudes = ((JArray)dataArray1[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] v10Array = new float[timeSteps][][];
+                float[][][] v10Array = new float[times][][];
 
                 // Convert each element to float and populate v10Array
-                for (int t = 0; t < timeSteps; t++)
+                for (int t = 0; t < times; t++)
                 {
                     v10Array[t] = new float[latitudes][];
 
@@ -86,7 +109,7 @@ public class Text_readNC
             }
         }
 
-        string url2 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/DATA.nc&varName=u10&centerLon=116.41992593821296&centerLat=40.18801994965735";
+        string url2 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_u10_v10_temp.nc&varName=u10&centerLon=" + initlongitudes + "&centerLat=" + initlatitudes;
 
         // Create a GET request to the specified URL
         HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(url2);
@@ -98,44 +121,45 @@ public class Text_readNC
             using (StreamReader reader2 = new StreamReader(response2.GetResponseStream()))
             {
                 string result2 = reader2.ReadToEnd();
-
+                //Console.WriteLine("result2:" + result2);
                 // Parse the JSON string into a JObject
                 JObject resultObject2 = JObject.Parse(result2);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray2 = (JArray)resultObject2["data"];
-
+                if (dataArray2 == null)
+                    return false;
                 // Determine the dimensions of the data array
-                int timeSteps2 = dataArray2.Count;
-                int latitudes2 = ((JArray)dataArray2[0]).Count;
-                int longitudes2 = ((JArray)dataArray2[0][0]).Count;
+                times1 = dataArray2.Count;
+                latitudes1 = ((JArray)dataArray2[0]).Count;
+                longitudes1 = ((JArray)dataArray2[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] u10Array = new float[timeSteps2][][];
+                float[][][] u10Array = new float[times1][][];
 
                 // Convert each element to float and populate v10Array
-                for (int t = 0; t < timeSteps2; t++)
+                for (int t = 0; t < times1; t++)
                 {
-                    u10Array[t] = new float[latitudes2][];
+                    u10Array[t] = new float[latitudes1][];
 
-                    for (int lat = 0; lat < latitudes2; lat++)
+                    for (int lat = 0; lat < latitudes1; lat++)
                     {
-                        u10Array[t][lat] = new float[longitudes2];
+                        u10Array[t][lat] = new float[longitudes1];
 
-                        for (int lon = 0; lon < longitudes2; lon++)
+                        for (int lon = 0; lon < longitudes1; lon++)
                         {
                             u10Array[t][lat][lon] = (float)dataArray2[t][lat][lon];
                         }
                     }
                 }
-                
-             
+
+
                 windNCread.u10Array = u10Array;
 
             }
         }
 
-        string url3 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/DATA.nc&varName=p140208&centerLon=116.41992593821296&centerLat=40.18801994965735";
+        string url3 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_mwd_currentV_waveHeight.nc&varName=p140208&centerLon=" + initlongitudes + "&centerLat=" + initlatitudes;
 
         // Create a GET request to the specified URL
         HttpWebRequest request3 = (HttpWebRequest)WebRequest.Create(url3);
@@ -147,42 +171,43 @@ public class Text_readNC
             using (StreamReader reader3 = new StreamReader(response3.GetResponseStream()))
             {
                 string result3 = reader3.ReadToEnd();
-
+                //Console.WriteLine("result3:" + result3);
                 // Parse the JSON string into a JObject
                 JObject resultObject3 = JObject.Parse(result3);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray3 = (JArray)resultObject3["data"];
-
+                if (dataArray3 == null)
+                    return false;
                 // Determine the dimensions of the data array
-                int timeSteps3 = dataArray3.Count;
-                int latitudes3 = ((JArray)dataArray3[0]).Count;
-                int longitudes3 = ((JArray)dataArray3[0][0]).Count;
+                times2 = dataArray3.Count;
+                latitudes2 = ((JArray)dataArray3[0]).Count;
+                longitudes2 = ((JArray)dataArray3[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] p140208Array = new float[timeSteps3][][];
+                float[][][] p140208Array = new float[times2][][];
 
                 // Convert each element to float and populate v10Array
-                for (int t = 0; t < timeSteps3; t++)
+                for (int t = 0; t < times2; t++)
                 {
-                    p140208Array[t] = new float[latitudes3][];
+                    p140208Array[t] = new float[latitudes2][];
 
-                    for (int lat = 0; lat < latitudes3; lat++)
+                    for (int lat = 0; lat < latitudes2; lat++)
                     {
-                        p140208Array[t][lat] = new float[longitudes3];
+                        p140208Array[t][lat] = new float[longitudes2];
 
-                        for (int lon = 0; lon < longitudes3; lon++)
+                        for (int lon = 0; lon < longitudes2; lon++)
                         {
                             p140208Array[t][lat][lon] = (float)dataArray3[t][lat][lon];
                         }
                     }
                 }
-                
+
                 windNCread.p140208Array = p140208Array;
             }
         }
 
-        string url4 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/DATA.nc&varName=mwd&centerLon=116.41992593821296&centerLat=40.18801994965735";
+        string url4 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_mwd_currentV_waveHeight.nc&varName=mwd&centerLon=" + initlongitudes + "&centerLat=" + initlatitudes;
 
         // Create a GET request to the specified URL
         HttpWebRequest request4 = (HttpWebRequest)WebRequest.Create(url4);
@@ -194,46 +219,48 @@ public class Text_readNC
             using (StreamReader reader4 = new StreamReader(response4.GetResponseStream()))
             {
                 string result4 = reader4.ReadToEnd();
-
+                //Console.WriteLine("result4:" + result4);
                 // Parse the JSON string into a JObject
                 JObject resultObject4 = JObject.Parse(result4);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray4 = (JArray)resultObject4["data"];
-
+                if (dataArray4 == null)
+                    return false;
                 // Determine the dimensions of the data array
-                int timeSteps4 = dataArray4.Count;
-                int latitudes4 = ((JArray)dataArray4[0]).Count;
-                int longitudes4 = ((JArray)dataArray4[0][0]).Count;
+                times3 = dataArray4.Count;
+                latitudes3 = ((JArray)dataArray4[0]).Count;
+                longitudes3 = ((JArray)dataArray4[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] mwdArray = new float[timeSteps4][][];
+                float[][][] mwdArray = new float[times3][][];
 
                 // Convert each element to float and populate v10Array
-                for (int t = 0; t < timeSteps4; t++)
+                for (int t = 0; t < times3; t++)
                 {
-                    mwdArray[t] = new float[latitudes4][];
+                    mwdArray[t] = new float[latitudes3][];
 
-                    for (int lat = 0; lat < latitudes4; lat++)
+                    for (int lat = 0; lat < latitudes3; lat++)
                     {
-                        mwdArray[t][lat] = new float[longitudes4];
+                        mwdArray[t][lat] = new float[longitudes3];
 
-                        for (int lon = 0; lon < longitudes4; lon++)
+                        for (int lon = 0; lon < longitudes3; lon++)
                         {
                             mwdArray[t][lat][lon] = (float)dataArray4[t][lat][lon];
                         }
                     }
                 }
-                
+
                 windNCread.mwdArray = mwdArray;
             }
         }
+        return true;
     }
 
-    public void GetWaveHighData()
+    public bool GetWaveHighData()
     {
-         //中心点坐标应该选取伤员初始位置坐标
-        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/WaveHeight.nc&varName=hmax&centerLon=116.41992593821296&centerLat=40.18801994965735";
+        //中心点坐标应该选取伤员初始位置坐标
+        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_mwd_currentV_waveHeight.nc&varName=hmax&centerLon=" + initlongitudes + "&centerLat=" + initlatitudes;
 
         // Create a GET request to the specified URL
         HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(url1);
@@ -245,30 +272,31 @@ public class Text_readNC
             using (StreamReader reader1 = new StreamReader(response1.GetResponseStream()))
             {
                 string result1 = reader1.ReadToEnd();
-
+                //Console.WriteLine("result1:" + result1);
                 // Parse the JSON string into a JObject
                 JObject resultObject1 = JObject.Parse(result1);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray1 = (JArray)resultObject1["data"];
-
+                if (dataArray1 == null)
+                    return false;
                 // Determine the dimensions of the data array
-                int timeSteps = dataArray1.Count;
-                int latitudes = ((JArray)dataArray1[0]).Count;
-                int longitudes = ((JArray)dataArray1[0][0]).Count;
+                times4 = dataArray1.Count;
+                latitudes4 = ((JArray)dataArray1[0]).Count;
+                longitudes4 = ((JArray)dataArray1[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] hmaxArray = new float[timeSteps][][];
+                float[][][] hmaxArray = new float[times4][][];
 
-                for (int t = 0; t < timeSteps; t++)
+                for (int t = 0; t < times4; t++)
                 {
-                    hmaxArray[t] = new float[latitudes][];
+                    hmaxArray[t] = new float[latitudes4][];
 
-                    for (int lat = 0; lat < latitudes; lat++)
+                    for (int lat = 0; lat < latitudes4; lat++)
                     {
-                        hmaxArray[t][lat] = new float[longitudes];
+                        hmaxArray[t][lat] = new float[longitudes4];
 
-                        for (int lon = 0; lon < longitudes; lon++)
+                        for (int lon = 0; lon < longitudes4; lon++)
                         {
                             hmaxArray[t][lat][lon] = (float)dataArray1[t][lat][lon];
                         }
@@ -300,5 +328,6 @@ public class Text_readNC
                 //Console.WriteLine("a value of timeArray: " + timeArray[0]);
             }
         }
+        return true;
     }
 }

+ 2 - 2
Models/SimulationCommon/Util.cs

@@ -33,12 +33,12 @@ public class Util
                 fuel = fuelDb.data[0];
             else
             {
-                Console.WriteLine($"没有找到【{json}】对应的油耗信息");
+                //Console.WriteLine($"没有找到【{json}】对应的油耗信息");
             }
         }
         catch (Exception e)
         {
-            Console.WriteLine($"没有找到【{json}】对应的油耗信息");
+            //Console.WriteLine($"没有找到【{json}】对应的油耗信息");
         }
 
         return fuel;

+ 18 - 13
Models/SimulationCommon/temp_readNC.cs

@@ -8,13 +8,16 @@ using SimulationCommon;
 public class GetNCData
 {
     public tempNCread tempreadNC = new tempNCread();
+
+    public double initlatitudes;
+    public double initlongitudes;
     //longitudeArray:经度一维数组;
     //latitudeArray:纬度一维数组;
     //tempArray:海面温度_24(时间)*7(纬度)*10(经度);
-    public void GetData()
+    public bool GetData()
     {
         //中心点坐标应该选取伤员初始位置坐标
-        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/temp.nc&varName=d2m&centerLon=116.41992593821296&centerLat=40.18801994965735";
+        string url1 = $"{Util.baseURl}rescue-platform-service/api/v1/dem/getNcInfos?ncPath=D:/data/haiyang/2023_u10_v10_temp.nc&varName=sst&centerLon=" + initlongitudes + "&centerLat=" + initlatitudes;
 
         // Create a GET request to the specified URL
         HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(url1);
@@ -26,30 +29,32 @@ public class GetNCData
             using (StreamReader reader1 = new StreamReader(response1.GetResponseStream()))
             {
                 string result1 = reader1.ReadToEnd();
+                //Console.WriteLine("result1:" + result1);
 
                 // Parse the JSON string into a JObject
                 JObject resultObject1 = JObject.Parse(result1);
 
                 // Extract the 'data' field from the parsed JObject
                 JArray dataArray1 = (JArray)resultObject1["data"];
-
+                if(dataArray1 == null)
+                    return false;
                 // Determine the dimensions of the data array
-                int timeSteps = dataArray1.Count;
-                int latitudes = ((JArray)dataArray1[0]).Count;
-                int longitudes = ((JArray)dataArray1[0][0]).Count;
+                int times5 = dataArray1.Count;
+                int latitudes5 = ((JArray)dataArray1[0]).Count;
+                int longitudes5 = ((JArray)dataArray1[0][0]).Count;
 
                 // Initialize float[][][] array
-                float[][][] tempArray = new float[timeSteps][][];
+                float[][][] tempArray = new float[times5][][];
 
-                for (int t = 0; t < timeSteps; t++)
+                for (int t = 0; t < times5; t++)
                 {
-                    tempArray[t] = new float[latitudes][];
+                    tempArray[t] = new float[latitudes5][];
 
-                    for (int lat = 0; lat < latitudes; lat++)
+                    for (int lat = 0; lat < latitudes5; lat++)
                     {
-                        tempArray[t][lat] = new float[longitudes];
+                        tempArray[t][lat] = new float[longitudes5];
 
-                        for (int lon = 0; lon < longitudes; lon++)
+                        for (int lon = 0; lon < longitudes5; lon++)
                         {
                             tempArray[t][lat][lon] = (float)dataArray1[t][lat][lon] - 273.15f;
                         }
@@ -87,7 +92,7 @@ public class GetNCData
                 tempreadNC.tempArray = tempArray;
             }
         }
-
+        return true;
     }
     
 

+ 5 - 0
Proto2CS/Proto2CS.csproj

@@ -5,5 +5,10 @@
     <TargetFramework>net7.0</TargetFramework>
   </PropertyGroup>
 
+  <ItemGroup>
+    <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+    <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
+  </ItemGroup>
+
 
 </Project>

+ 20 - 12
SimulationServer/Component/SJAllTotalTaskPerformance.cs

@@ -9,10 +9,10 @@ public class SJAllTotalTaskPerformance
     public string 平均搜索时间;
     public string 平均救助时间;
     public string 总飞行时间;
-    public string 海情覆盖率;
+    public string 海上搜索覆盖面积;
     public string 任务是否成功;
     public string 人员存活率;
-    public string 环境覆盖率;
+    public string 环境搜索覆盖面积;
 }
 
 public class SJAllTotalTaskPerformanceComponent
@@ -30,6 +30,8 @@ public class SJAllTotalTaskPerformanceComponent
         double 人员存活率 = 0;
         double 任务是否成功 = 0;
         float 识别成功率 = 0f;
+        double 平均救助时间 = 0;
+        float 人员数量 = 0;
 
 
         double aircreftCount = 0;
@@ -49,9 +51,11 @@ public class SJAllTotalTaskPerformanceComponent
             foreach (var item in mhRescueMission.aircraftSJDatas)
             {
                 识别成功率 += float.Parse(item.Value["识别成功率"][sIndex]);
+                人员数量 += float.Parse(item.Value["人员数量"][sIndex]);
                 if (任务准备时间 < float.Parse(item.Value["任务准备时间"][sIndex]))
                     任务准备时间 = float.Parse(item.Value["任务准备时间"][sIndex]);
                 平均搜索时间 += float.Parse(item.Value["平均搜索时间"][sIndex]);
+                平均救助时间 += float.Parse(item.Value["平均救助时间"][sIndex]);
                 总飞行时间 += float.Parse(item.Value["总飞行时间"][sIndex]);
                 人员存活率 += float.Parse(item.Value["人员存活率"][sIndex]);
                 aircreftCount++;
@@ -60,14 +64,14 @@ public class SJAllTotalTaskPerformanceComponent
         }
         if (人员存活率 != 0)
             任务是否成功 = 1;
-        SSJAllTotalTaskPerformance.识别成功率 = (识别成功率 / aircreftCount).ToString();
+        SSJAllTotalTaskPerformance.识别成功率 = (识别成功率 / 人员数量).ToString();
         SSJAllTotalTaskPerformance.任务准备时间 = 任务准备时间.ToString();
         SSJAllTotalTaskPerformance.平均搜索时间 = (平均搜索时间 / aircreftCount).ToString("f4");
-        SSJAllTotalTaskPerformance.平均救助时间 = 5.ToString();
+        SSJAllTotalTaskPerformance.平均救助时间 = (平均救助时间 / aircreftCount).ToString("f4");
         SSJAllTotalTaskPerformance.总飞行时间 = 总飞行时间.ToString("f4");
-        SSJAllTotalTaskPerformance.海情覆盖率 = "0.6".ToString();//"60%"
+        SSJAllTotalTaskPerformance.海上搜索覆盖面积 = "0.6".ToString();//"60%"
         SSJAllTotalTaskPerformance.任务是否成功 = 任务是否成功.ToString();
-        SSJAllTotalTaskPerformance.人员存活率 = (人员存活率 / aircreftCount).ToString();
+        SSJAllTotalTaskPerformance.人员存活率 = (人员存活率 / 人员数量).ToString();
         sIndex++;
     }
 
@@ -79,6 +83,8 @@ public class SJAllTotalTaskPerformanceComponent
         double 人员存活率 = 0;
         double 任务是否成功 = 0;
         float 识别成功率 = 0f;
+        double 平均救助时间 = 0;
+        float 人员数量 = 0;
 
 
         double aircreftCount = 0;
@@ -98,9 +104,11 @@ public class SJAllTotalTaskPerformanceComponent
             foreach (var item in mhRescueMission.aircraftSJDatas)
             {
                 识别成功率 += float.Parse(item.Value["识别成功率"][lIndex]);
+                人员数量 += float.Parse(item.Value["人员数量"][sIndex]);
                 if (任务准备时间 < float.Parse(item.Value["任务准备时间"][lIndex]))
                     任务准备时间 = float.Parse(item.Value["任务准备时间"][lIndex]);
                 平均搜索时间 += float.Parse(item.Value["平均搜索时间"][lIndex]);
+                平均救助时间 += float.Parse(item.Value["平均救助时间"][sIndex]);
                 总飞行时间 += float.Parse(item.Value["总飞行时间"][lIndex]);
                 人员存活率 += float.Parse(item.Value["人员存活率"][lIndex]);
                 aircreftCount++;
@@ -109,14 +117,14 @@ public class SJAllTotalTaskPerformanceComponent
         }
         if (人员存活率 != 0)
             任务是否成功 = 1;
-        LSJAllTotalTaskPerformance.识别成功率 = (识别成功率 / aircreftCount).ToString();
+        LSJAllTotalTaskPerformance.识别成功率 = (识别成功率 / 人员数量).ToString();
         LSJAllTotalTaskPerformance.任务准备时间 = 任务准备时间.ToString();
         LSJAllTotalTaskPerformance.平均搜索时间 = (平均搜索时间 / aircreftCount).ToString("f4");
-        LSJAllTotalTaskPerformance.平均救助时间 = 5.ToString();
+        LSJAllTotalTaskPerformance.平均救助时间 = (平均救助时间 / aircreftCount).ToString();
         LSJAllTotalTaskPerformance.总飞行时间 = 总飞行时间.ToString("f4");
-        LSJAllTotalTaskPerformance.环境覆盖率 = "0.6".ToString();//"60%"
+        LSJAllTotalTaskPerformance.环境搜索覆盖面积 = "0.6".ToString();//"60%"
         LSJAllTotalTaskPerformance.任务是否成功 = 任务是否成功.ToString();
-        LSJAllTotalTaskPerformance.人员存活率 = (人员存活率 / aircreftCount).ToString();
+        LSJAllTotalTaskPerformance.人员存活率 = (人员存活率 / 人员数量).ToString();
         lIndex++;
     }
 
@@ -130,7 +138,7 @@ public class SJAllTotalTaskPerformanceComponent
             { "平均搜索时间", SSJAllTotalTaskPerformance.平均搜索时间.ToString() },
             { "平均救助时间", SSJAllTotalTaskPerformance.平均救助时间.ToString() },
             { "总飞行时间", SSJAllTotalTaskPerformance.总飞行时间.ToString() },
-            { "海情覆盖率", SSJAllTotalTaskPerformance.海情覆盖率.ToString() },
+            { "海情覆盖率", SSJAllTotalTaskPerformance.海上搜索覆盖面积.ToString() },
             { "任务是否成功", SSJAllTotalTaskPerformance.任务是否成功.ToString() },
             { "人员存活率", SSJAllTotalTaskPerformance.人员存活率.ToString() }
         };
@@ -147,7 +155,7 @@ public class SJAllTotalTaskPerformanceComponent
             { "平均搜索时间", LSJAllTotalTaskPerformance.平均搜索时间.ToString() },
             { "平均救助时间", LSJAllTotalTaskPerformance.平均救助时间.ToString() },
             { "总飞行时间", LSJAllTotalTaskPerformance.总飞行时间.ToString() },
-            { "环境覆盖率", LSJAllTotalTaskPerformance.环境覆盖率.ToString() },
+            { "环境覆盖率", LSJAllTotalTaskPerformance.环境搜索覆盖面积.ToString() },
             { "任务是否成功", LSJAllTotalTaskPerformance.任务是否成功.ToString() },
             { "人员存活率", LSJAllTotalTaskPerformance.人员存活率.ToString() }
         };

+ 264 - 0
SimulationServer/Component/SJStaticCapacityComponent.cs

@@ -98,6 +98,131 @@ public class SJStaticCapacityComponent : Component
         SJStaticCapacity.有效探测距离 = 2.ToString();
     }
 
+    public void FillData2(AircraftDB db)
+    {
+        var aircraft = GetParent<AircraftDY>();
+
+        SJStaticCapacity.初次出动准备时间 = "30";
+        SJStaticCapacity.再次补给时间 = "5";
+        SJStaticCapacity.舱内载荷 = db.fzdnz == null ? "0" : db.fzdnz.ToString();
+        //SJStaticCapacity.机舱容量 = db.fjcrll == null ? "0" : db.fjcrll.ToString();
+        SJStaticCapacity.最大平飞速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        SJStaticCapacity.巡航速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        //SJStaticCapacity.搜救速度 = db.fsjfxsd == null ? "0" : db.fsjfxsd.ToString();
+        //SJStaticCapacity.单人救助时间 = db.fdrjzsj == null ? "0" : db.fdrjzsj.ToString();
+        SJStaticCapacity.抗风等级 = "八级";
+        SJStaticCapacity.最大起降高度 = "";
+        //SJStaticCapacity.抗浪等级 = db.fkldj == null ? "0" : db.fkldj.ToString();
+        //SJStaticCapacity.起降距离 = db.fjjcdc == null ? "0" : db.fjjcdc.ToString();
+        SJStaticCapacity.夜间作业能力 = 0.ToString();
+        SJStaticCapacity.仪表飞行能力 = 0.ToString();
+        SJStaticCapacity.可靠性 = "0.9";
+        //SJStaticCapacity.航程 = db.fhc == null ? "0" : db.fhc.ToString();
+        SJStaticCapacity.悬停相对耗油率 = FXJHGenerate.GetHoverFuelConsumptionRate(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.搜救相对耗油率 = FXJHGenerate.GetCruisingVelocity(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.有效探测距离 = 2.ToString();
+    }
+
+    public void FillData3(AircraftDB db)
+    {
+        var aircraft = GetParent<AircraftKTKS>();
+
+        SJStaticCapacity.初次出动准备时间 = "30";
+        SJStaticCapacity.再次补给时间 = "5";
+        SJStaticCapacity.舱内载荷 = db.fzdnz == null ? "0" : db.fzdnz.ToString();
+        //SJStaticCapacity.机舱容量 = db.fjcrll == null ? "0" : db.fjcrll.ToString();
+        SJStaticCapacity.最大平飞速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        SJStaticCapacity.巡航速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        //SJStaticCapacity.搜救速度 = db.fsjfxsd == null ? "0" : db.fsjfxsd.ToString();
+        //SJStaticCapacity.单人救助时间 = db.fdrjzsj == null ? "0" : db.fdrjzsj.ToString();
+        SJStaticCapacity.抗风等级 = "八级";
+        SJStaticCapacity.最大起降高度 = "";
+        //SJStaticCapacity.抗浪等级 = db.fkldj == null ? "0" : db.fkldj.ToString();
+        //SJStaticCapacity.起降距离 = db.fjjcdc == null ? "0" : db.fjjcdc.ToString();
+        SJStaticCapacity.夜间作业能力 = 0.ToString();
+        SJStaticCapacity.仪表飞行能力 = 0.ToString();
+        SJStaticCapacity.可靠性 = "0.9";
+        //SJStaticCapacity.航程 = db.fhc == null ? "0" : db.fhc.ToString();
+        SJStaticCapacity.悬停相对耗油率 = FXJHGenerate.GetHoverFuelConsumptionRate(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.搜救相对耗油率 = FXJHGenerate.GetCruisingVelocity(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.有效探测距离 = 2.ToString();
+    }
+
+    public void FillData4(AircraftDB db)
+    {
+        var aircraft = GetParent<AircraftZS>();
+
+        SJStaticCapacity.初次出动准备时间 = "30";
+        SJStaticCapacity.再次补给时间 = "5";
+        SJStaticCapacity.舱内载荷 = db.fzdnz == null ? "0" : db.fzdnz.ToString();
+        //SJStaticCapacity.机舱容量 = db.fjcrll == null ? "0" : db.fjcrll.ToString();
+        SJStaticCapacity.最大平飞速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        SJStaticCapacity.巡航速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        //SJStaticCapacity.搜救速度 = db.fsjfxsd == null ? "0" : db.fsjfxsd.ToString();
+        //SJStaticCapacity.单人救助时间 = db.fdrjzsj == null ? "0" : db.fdrjzsj.ToString();
+        SJStaticCapacity.抗风等级 = "八级";
+        SJStaticCapacity.最大起降高度 = "";
+        //SJStaticCapacity.抗浪等级 = db.fkldj == null ? "0" : db.fkldj.ToString();
+        //SJStaticCapacity.起降距离 = db.fjjcdc == null ? "0" : db.fjjcdc.ToString();
+        SJStaticCapacity.夜间作业能力 = 0.ToString();
+        SJStaticCapacity.仪表飞行能力 = 0.ToString();
+        SJStaticCapacity.可靠性 = "0.9";
+        //SJStaticCapacity.航程 = db.fhc == null ? "0" : db.fhc.ToString();
+        SJStaticCapacity.悬停相对耗油率 = FXJHGenerate.GetHoverFuelConsumptionRate(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.搜救相对耗油率 = FXJHGenerate.GetCruisingVelocity(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.有效探测距离 = 2.ToString();
+    }
+
+    public void FillData5(AircraftDB db)
+    {
+        var aircraft = GetParent<AircraftJJ>();
+
+        SJStaticCapacity.初次出动准备时间 = "30";
+        SJStaticCapacity.再次补给时间 = "5";
+        SJStaticCapacity.舱内载荷 = db.fzdnz == null ? "0" : db.fzdnz.ToString();
+        //SJStaticCapacity.机舱容量 = db.fjcrll == null ? "0" : db.fjcrll.ToString();
+        SJStaticCapacity.最大平飞速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        SJStaticCapacity.巡航速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        //SJStaticCapacity.搜救速度 = db.fsjfxsd == null ? "0" : db.fsjfxsd.ToString();
+        //SJStaticCapacity.单人救助时间 = db.fdrjzsj == null ? "0" : db.fdrjzsj.ToString();
+        SJStaticCapacity.抗风等级 = "八级";
+        SJStaticCapacity.最大起降高度 = "";
+        //SJStaticCapacity.抗浪等级 = db.fkldj == null ? "0" : db.fkldj.ToString();
+        //SJStaticCapacity.起降距离 = db.fjjcdc == null ? "0" : db.fjjcdc.ToString();
+        SJStaticCapacity.夜间作业能力 = 0.ToString();
+        SJStaticCapacity.仪表飞行能力 = 0.ToString();
+        SJStaticCapacity.可靠性 = "0.9";
+        //SJStaticCapacity.航程 = db.fhc == null ? "0" : db.fhc.ToString();
+        SJStaticCapacity.悬停相对耗油率 = FXJHGenerate.GetHoverFuelConsumptionRate(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.搜救相对耗油率 = FXJHGenerate.GetCruisingVelocity(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.有效探测距离 = 2.ToString();
+    }
+
+    public void FillData6(AircraftDB db)
+    {
+        var aircraft = GetParent<AircraftSHJ>();
+
+        SJStaticCapacity.初次出动准备时间 = "30";
+        SJStaticCapacity.再次补给时间 = "5";
+        SJStaticCapacity.舱内载荷 = db.fzdnz == null ? "0" : db.fzdnz.ToString();
+        //SJStaticCapacity.机舱容量 = db.fjcrll == null ? "0" : db.fjcrll.ToString();
+        SJStaticCapacity.最大平飞速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        SJStaticCapacity.巡航速度 = db.fzdss == null ? "0" : db.fzdss.ToString();
+        //SJStaticCapacity.搜救速度 = db.fsjfxsd == null ? "0" : db.fsjfxsd.ToString();
+        //SJStaticCapacity.单人救助时间 = db.fdrjzsj == null ? "0" : db.fdrjzsj.ToString();
+        SJStaticCapacity.抗风等级 = "八级";
+        SJStaticCapacity.最大起降高度 = "";
+        //SJStaticCapacity.抗浪等级 = db.fkldj == null ? "0" : db.fkldj.ToString();
+        //SJStaticCapacity.起降距离 = db.fjjcdc == null ? "0" : db.fjjcdc.ToString();
+        SJStaticCapacity.夜间作业能力 = 0.ToString();
+        SJStaticCapacity.仪表飞行能力 = 0.ToString();
+        SJStaticCapacity.可靠性 = "0.9";
+        //SJStaticCapacity.航程 = db.fhc == null ? "0" : db.fhc.ToString();
+        SJStaticCapacity.悬停相对耗油率 = FXJHGenerate.GetHoverFuelConsumptionRate(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.搜救相对耗油率 = FXJHGenerate.GetCruisingVelocity(aircraft.FlightPlanEditor, 50).ToString();
+        SJStaticCapacity.有效探测距离 = 2.ToString();
+    }
+
 
     public Dictionary<string, Dictionary<string, string>> GetReport()
     {
@@ -154,4 +279,143 @@ public class SJStaticCapacityComponent : Component
         return report;
     }
 
+    public Dictionary<string, Dictionary<string, string>> GetReport2()
+    {
+        Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+        report["静态能力"] = new Dictionary<string, string>
+        {
+            { "初次出动准备时间/s", SJStaticCapacity.初次出动准备时间.ToString() },
+            { "再次补给时间/s", SJStaticCapacity.再次补给时间.ToString() },
+            { "舱内载荷/kg", SJStaticCapacity.舱内载荷.ToString() },
+            { "机舱容量/kg", SJStaticCapacity.机舱容量.ToString() },
+            { "最大平飞速度/km/h", SJStaticCapacity.最大平飞速度.ToString() },
+            { "巡航速度/km/h", SJStaticCapacity.巡航速度.ToString() },
+            { "搜救速度/km/h", SJStaticCapacity.搜救速度.ToString() },
+            { "单人救助时间/s", SJStaticCapacity.单人救助时间.ToString() },
+            { "抗风等级", SJStaticCapacity.抗风等级.ToString() },
+            { "抗浪等级", SJStaticCapacity.抗浪等级.ToString() },
+            { "起降距离/m", SJStaticCapacity.起降距离.ToString() },
+            { "夜间作业能力", SJStaticCapacity.夜间作业能力.ToString() },
+            { "仪表飞行能力", SJStaticCapacity.仪表飞行能力.ToString() },
+            { "可靠性", SJStaticCapacity.可靠性.ToString() },
+            { "航程/km", SJStaticCapacity.航程.ToString() },
+            { "悬停相对耗油率", SJStaticCapacity.悬停相对耗油率.ToString() },
+            { "搜救相对耗油率", SJStaticCapacity.搜救相对耗油率.ToString() },
+            { "有效探测距离/m", SJStaticCapacity.有效探测距离.ToString() }
+
+        };
+        return report;
+    }
+
+    public Dictionary<string, Dictionary<string, string>> GetReport3()
+    {
+        Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+        report["静态能力"] = new Dictionary<string, string>
+        {
+            { "初次出动准备时间/s", SJStaticCapacity.初次出动准备时间.ToString() },
+            { "再次补给时间/s", SJStaticCapacity.再次补给时间.ToString() },
+            { "舱内载荷/kg", SJStaticCapacity.舱内载荷.ToString() },
+            { "机舱容量/kg", SJStaticCapacity.机舱容量.ToString() },
+            { "最大平飞速度/km/h", SJStaticCapacity.最大平飞速度.ToString() },
+            { "巡航速度/km/h", SJStaticCapacity.巡航速度.ToString() },
+            { "搜救速度/km/h", SJStaticCapacity.搜救速度.ToString() },
+            { "单人救助时间/s", SJStaticCapacity.单人救助时间.ToString() },
+            { "抗风等级", SJStaticCapacity.抗风等级.ToString() },
+            { "抗浪等级", SJStaticCapacity.抗浪等级.ToString() },
+            { "起降距离/m", SJStaticCapacity.起降距离.ToString() },
+            { "夜间作业能力", SJStaticCapacity.夜间作业能力.ToString() },
+            { "仪表飞行能力", SJStaticCapacity.仪表飞行能力.ToString() },
+            { "可靠性", SJStaticCapacity.可靠性.ToString() },
+            { "航程/km", SJStaticCapacity.航程.ToString() },
+            { "悬停相对耗油率", SJStaticCapacity.悬停相对耗油率.ToString() },
+            { "搜救相对耗油率", SJStaticCapacity.搜救相对耗油率.ToString() },
+            { "有效探测距离/m", SJStaticCapacity.有效探测距离.ToString() }
+
+        };
+        return report;
+    }
+
+    public Dictionary<string, Dictionary<string, string>> GetReport4()
+    {
+        Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+        report["静态能力"] = new Dictionary<string, string>
+        {
+            { "初次出动准备时间/s", SJStaticCapacity.初次出动准备时间.ToString() },
+            { "再次补给时间/s", SJStaticCapacity.再次补给时间.ToString() },
+            { "舱内载荷/kg", SJStaticCapacity.舱内载荷.ToString() },
+            { "机舱容量/kg", SJStaticCapacity.机舱容量.ToString() },
+            { "最大平飞速度/km/h", SJStaticCapacity.最大平飞速度.ToString() },
+            { "巡航速度/km/h", SJStaticCapacity.巡航速度.ToString() },
+            { "搜救速度/km/h", SJStaticCapacity.搜救速度.ToString() },
+            { "单人救助时间/s", SJStaticCapacity.单人救助时间.ToString() },
+            { "抗风等级", SJStaticCapacity.抗风等级.ToString() },
+            { "抗浪等级", SJStaticCapacity.抗浪等级.ToString() },
+            { "起降距离/m", SJStaticCapacity.起降距离.ToString() },
+            { "夜间作业能力", SJStaticCapacity.夜间作业能力.ToString() },
+            { "仪表飞行能力", SJStaticCapacity.仪表飞行能力.ToString() },
+            { "可靠性", SJStaticCapacity.可靠性.ToString() },
+            { "航程/km", SJStaticCapacity.航程.ToString() },
+            { "悬停相对耗油率", SJStaticCapacity.悬停相对耗油率.ToString() },
+            { "搜救相对耗油率", SJStaticCapacity.搜救相对耗油率.ToString() },
+            { "有效探测距离/m", SJStaticCapacity.有效探测距离.ToString() }
+
+        };
+        return report;
+    }
+
+    public Dictionary<string, Dictionary<string, string>> GetReport5()
+    {
+        Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+        report["静态能力"] = new Dictionary<string, string>
+        {
+            { "初次出动准备时间/s", SJStaticCapacity.初次出动准备时间.ToString() },
+            { "再次补给时间/s", SJStaticCapacity.再次补给时间.ToString() },
+            { "舱内载荷/kg", SJStaticCapacity.舱内载荷.ToString() },
+            { "机舱容量/kg", SJStaticCapacity.机舱容量.ToString() },
+            { "最大平飞速度/km/h", SJStaticCapacity.最大平飞速度.ToString() },
+            { "巡航速度/km/h", SJStaticCapacity.巡航速度.ToString() },
+            { "搜救速度/km/h", SJStaticCapacity.搜救速度.ToString() },
+            { "单人救助时间/s", SJStaticCapacity.单人救助时间.ToString() },
+            { "抗风等级", SJStaticCapacity.抗风等级.ToString() },
+            { "抗浪等级", SJStaticCapacity.抗浪等级.ToString() },
+            { "起降距离/m", SJStaticCapacity.起降距离.ToString() },
+            { "夜间作业能力", SJStaticCapacity.夜间作业能力.ToString() },
+            { "仪表飞行能力", SJStaticCapacity.仪表飞行能力.ToString() },
+            { "可靠性", SJStaticCapacity.可靠性.ToString() },
+            { "航程/km", SJStaticCapacity.航程.ToString() },
+            { "悬停相对耗油率", SJStaticCapacity.悬停相对耗油率.ToString() },
+            { "搜救相对耗油率", SJStaticCapacity.搜救相对耗油率.ToString() },
+            { "有效探测距离/m", SJStaticCapacity.有效探测距离.ToString() }
+
+        };
+        return report;
+    }
+
+    public Dictionary<string, Dictionary<string, string>> GetReport6()
+    {
+        Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+        report["静态能力"] = new Dictionary<string, string>
+        {
+            { "初次出动准备时间/s", SJStaticCapacity.初次出动准备时间.ToString() },
+            { "再次补给时间/s", SJStaticCapacity.再次补给时间.ToString() },
+            { "舱内载荷/kg", SJStaticCapacity.舱内载荷.ToString() },
+            { "机舱容量/kg", SJStaticCapacity.机舱容量.ToString() },
+            { "最大平飞速度/km/h", SJStaticCapacity.最大平飞速度.ToString() },
+            { "巡航速度/km/h", SJStaticCapacity.巡航速度.ToString() },
+            { "搜救速度/km/h", SJStaticCapacity.搜救速度.ToString() },
+            { "单人救助时间/s", SJStaticCapacity.单人救助时间.ToString() },
+            { "抗风等级", SJStaticCapacity.抗风等级.ToString() },
+            { "抗浪等级", SJStaticCapacity.抗浪等级.ToString() },
+            { "起降距离/m", SJStaticCapacity.起降距离.ToString() },
+            { "夜间作业能力", SJStaticCapacity.夜间作业能力.ToString() },
+            { "仪表飞行能力", SJStaticCapacity.仪表飞行能力.ToString() },
+            { "可靠性", SJStaticCapacity.可靠性.ToString() },
+            { "航程/km", SJStaticCapacity.航程.ToString() },
+            { "悬停相对耗油率", SJStaticCapacity.悬停相对耗油率.ToString() },
+            { "搜救相对耗油率", SJStaticCapacity.搜救相对耗油率.ToString() },
+            { "有效探测距离/m", SJStaticCapacity.有效探测距离.ToString() }
+
+        };
+        return report;
+    }
 }

+ 641 - 8
SimulationServer/Component/TaskComponent.cs

@@ -1,24 +1,657 @@
 using KYFramework;
+using Model;
+using OpenQA.Selenium.Remote;
+using SimulationCommon;
 using SimulationServer.Utils;
 
 namespace SimulationServer;
 
 public class TaskComponent : Component
 {
-    public static bool SimulationStart = false;
-    
     public static Weather Weather;
-    
     public static int Speed = 100;
 
-    public static DateTime TaskTime;
-    
+    // 救援任务列表
+    public List<MHRescueMission> MHRescueMissions;
+    public List<XHRescueMission> XHRescueMissions;
+    public List<ZCRescueMission> ZCRescueMissions;
+    public List<SeaSJRescueMission> SeaSJRescueMissions;
+    public List<LandSJRescueMission> LandSJRescueMissions;
+    public List<KZDYMission> KZDYMissions;
+    public List<KTKSMission> KTKSMissions;
+    public List<ZSJYMission> ZSJYMissions;
+    public List<JJJYMission> JJJYMissions;
+    public List<SHJMission> SHJMissions;
 
-    // 根据任务id 排列任务执行顺序
-    public List<BaseMission> Missions = new List<BaseMission>();
+    public SJAllTotalTaskPerformanceComponent SSJAllTotalTaskPerformance = new SJAllTotalTaskPerformanceComponent();
+    public Dictionary<string, Dictionary<string, List<string>>> alltotalReportSea = new();
+    public Dictionary<string, Dictionary<string, List<string>>> alltotalReportLand = new();
+    // <sheet,<指标名,值列表>>
+    public Dictionary<string, Dictionary<string, List<string>>> totalReportSea = new();
+    public Dictionary<string, Dictionary<string, List<string>>> totalReportLand = new();
 
-    public List<List<AircraftEntity>> asyncAircrafts = new List<List<AircraftEntity>>();
+    private int currentSeaExecuteCount = 1;
+    private int currentLandExecuteCount = 1;
+    public int ExecutionContext = 0;
 
+    public int seaSuccessCount = 0;
+    public int landSuccessCount = 0;
+
+    public bool isSea;
+    public bool isLand;
+
+    public string date;
+
+    public int missionCount;
+
+    public void Start()
+    {
+        MHRescueMissions?.ForEach(r => r.Reset());
+        XHRescueMissions?.ForEach(r => r.Reset());
+
+        MHRescueMissions?.ForEach(r => r.Start());
+        XHRescueMissions?.ForEach(r => r.Start());
+        ZCRescueMissions?.ForEach(r => r.Start());
+
+        SeaSJRescueMissions?.ForEach(r => r.Start());
+        LandSJRescueMissions?.ForEach(r => r.Start());
+        KZDYMissions?.ForEach(r => r.Start());
+        KTKSMissions?.ForEach(r => r.Start());
+        ZSJYMissions?.ForEach(r => r.Start());
+        JJJYMissions?.ForEach(r => r.Start());
+        SHJMissions?.ForEach(r => r.Start());
+    }
+
+    public void SaveSeaSJ(Dictionary<string, Dictionary<string, string>> totalReport)
+    {
+        //把totalReport保存到alltotalReport
+        foreach (var kv in totalReport)
+        {
+            if (!alltotalReportSea.ContainsKey(kv.Key)) alltotalReportSea[kv.Key] = new Dictionary<string, List<string>>();
+
+
+            foreach (var kv2 in kv.Value)
+            {
+                if (!alltotalReportSea[kv.Key].ContainsKey(kv2.Key)) alltotalReportSea[kv.Key][kv2.Key] = new List<string>();
+
+                alltotalReportSea[kv.Key][kv2.Key].Add(kv2.Value);
+            }
+        }
+
+        if (currentSeaExecuteCount == ExecutionContext)
+        {
+            // 求一个平均值放到最后一位
+            foreach (var kv in alltotalReportSea)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    var sum = 0f;
+                    foreach (var value in kv2.Value)
+                    {
+                        bool isfloat = float.TryParse(value, out float f);
+                        if (isfloat)
+                            sum += float.Parse(value);
+                        else
+                            sum = -1f;
+                    }
+                    if (sum != -1f)
+                        kv2.Value.Add((sum / kv2.Value.Count).ToString());
+                    else
+                        kv2.Value.Add("");
+                }
+            }
+        }
+
+        currentSeaExecuteCount++;
+    }
+
+    public void SaveLandSJ(Dictionary<string, Dictionary<string, string>> totalReport)
+    {
+        //把totalReport保存到alltotalReport
+        foreach (var kv in totalReport)
+        {
+            if (!alltotalReportLand.ContainsKey(kv.Key)) alltotalReportLand[kv.Key] = new Dictionary<string, List<string>>();
+
+
+            foreach (var kv2 in kv.Value)
+            {
+                if (!alltotalReportLand[kv.Key].ContainsKey(kv2.Key)) alltotalReportLand[kv.Key][kv2.Key] = new List<string>();
+
+                alltotalReportLand[kv.Key][kv2.Key].Add(kv2.Value);
+            }
+        }
+
+        if (currentLandExecuteCount == ExecutionContext)
+        {
+            // 求一个平均值放到最后一位
+            foreach (var kv in alltotalReportLand)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    var sum = 0f;
+                    foreach (var value in kv2.Value)
+                    {
+                        bool isfloat = float.TryParse(value, out float f);
+                        if (isfloat)
+                            sum += float.Parse(value);
+                        else
+                            sum = -1f;
+                    }
+                    if (sum != -1f)
+                        kv2.Value.Add((sum / kv2.Value.Count).ToString());
+                    else
+                        kv2.Value.Add("");
+                }
+            }
+        }
+
+        currentLandExecuteCount++;
+    }
+
+    public void ReportAllSJSea()
+    {
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        string totalPath = "";
+        if (isSea)
+            totalPath = $"{path}/{"海上搜救任务总体指标报告"}.xls";
+        if (isLand)
+            totalPath = $"{path}/{"陆上搜救任务总体指标报告"}.xls";
+        DataTableExtensions.SaveToExcel(totalPath, alltotalReportSea, true, true, (seaSuccessCount * 1f / ExecutionContext).ToString());
+
+
+        //string totalPath1 = $"{path}/{"搜救任务总体指标报告"}.xls";
+        //DataTableExtensions.SaveToExcel(totalPath1, totalReportSea);
+    }
+
+    public void ReportAllSJLand()
+    {
+        string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+
+        string totalPath = $"{path}/{"陆上搜寻任务总体指标报告"}.xls";
+        DataTableExtensions.SaveToExcel(totalPath, alltotalReportLand, true, true, (landSuccessCount * 1f / ExecutionContext).ToString());
+
+
+        //string totalPath1 = $"{path}/{"搜救任务总体指标报告"}.xls";
+        //DataTableExtensions.SaveToExcel(totalPath1, totalReportLand);
+    }
+
+    public void SaveTotalMHSea()
+    {
+        if (!totalReportSea.ContainsKey("总任务表现")) totalReportSea["总任务表现"] = new Dictionary<string, List<string>>();
+        if (!totalReportSea["总任务表现"].ContainsKey("任务成功率")) totalReportSea["总任务表现"]["任务成功率"] = new List<string>();
+        totalReportSea["总任务表现"]["任务成功率"].Add((seaSuccessCount * 1f / ExecutionContext).ToString());
+    }
+
+    public void SaveTotalMHLand()
+    {
+        if (!totalReportLand.ContainsKey("总任务表现")) totalReportLand["总任务表现"] = new Dictionary<string, List<string>>();
+        if (!totalReportLand["总任务表现"].ContainsKey("任务成功率")) totalReportLand["总任务表现"]["任务成功率"] = new List<string>();
+        totalReportLand["总任务表现"]["任务成功率"].Add((landSuccessCount * 1f / ExecutionContext).ToString());
+    }
 }
 
+[ObjectSystem]
+public class TaskComponentAwakeSystem : AwakeSystem<TaskComponent>
+{
+    public override void Awake(TaskComponent self)
+    {
+        self.MHRescueMissions = new List<MHRescueMission>();
+        self.ZCRescueMissions = new List<ZCRescueMission>();
+        self.XHRescueMissions = new List<XHRescueMission>();
+        self.SeaSJRescueMissions = new List<SeaSJRescueMission>();
+        self.LandSJRescueMissions = new List<LandSJRescueMission>();
+        self.KZDYMissions = new List<KZDYMission>();
+        self.KTKSMissions = new List<KTKSMission>();
+        self.ZSJYMissions = new List<ZSJYMission>();
+        self.JJJYMissions = new List<JJJYMission>();
+        self.SHJMissions = new List<SHJMission>();
+    }
+}
+
+[ObjectSystem]
+public class TaskComponentUpdateSystem : UpdateSystem<TaskComponent>
+{
+    double 任务准备时间 = 0;
+    double 平均搜索时间 = 0;
+    double 总飞行时间 = 0;
+    double 人员存活率 = 0;
+    double 任务是否成功 = 0;
+    float 识别成功率 = 0f;
+    double 平均救助时间 = 0;
+    float 人员数量 = 0;
+    float 识别数量 = 0;
+    double 环境搜索覆盖面积 = 0;
+    double 海上搜索覆盖面积 = 0;
+    double aircreftCount = 0;
+
+    double searchCount = 0;
+    double jzCount = 0;
+
+    public bool isSeaSJRescueMissionsOver = false;
+    public bool isLandSJRescueMissionsOver = false;
+    public bool isKZDYMissionsOver = false;
+    public bool isKTKSMissionsOver = false;
+    public bool isZSJYMissionsOver = false;
+    public bool isJJJYMissionsOver = false;
+    public bool isSHJMissionsOver = false;
+
+    public bool isReport;
+
+    public override void Update(TaskComponent self)
+    {
+        if (self.SeaSJRescueMissions.Count > 0)
+        {
+            if (self.SeaSJRescueMissions.All(m => m.IsOver) && !isSeaSJRescueMissionsOver)
+            {
+                self.missionCount -= self.SeaSJRescueMissions.Count;
+                isSeaSJRescueMissionsOver = true;
+                //for (int i = 0; i < self.ExecutionContext; i++)
+                //{
+                //    self.SSJAllTotalTaskPerformance.FillData(self.SeaSJRescueMissions);
+                //    var report = self.SSJAllTotalTaskPerformance.GetReport();
+                //    if (report["总任务表现"]["任务是否成功"] == "1")
+                //        self.seaSuccessCount++;
+                //    self.SaveSeaSJ(report);
+                //}
+                ////self.SaveTotalMHSea();
+                //self.ReportAllSJSea();
+                //self.SeaSJRescueMissions.Clear();
+            }
+        }
+
+        if (self.LandSJRescueMissions.Count > 0)
+        {
+            if (self.LandSJRescueMissions.All(m => m.IsOver) && !isLandSJRescueMissionsOver)
+            {
+                self.missionCount -= self.LandSJRescueMissions.Count;
+                isLandSJRescueMissionsOver = true;
+                //for (int i = 0; i < self.ExecutionContext; i++)
+                //{
+                //    self.SSJAllTotalTaskPerformance.FillData1(self.LandSJRescueMissions);
+                //    var report = self.SSJAllTotalTaskPerformance.GetReport1();
+                //    if (report["总任务表现"]["任务是否成功"] == "1")
+                //        self.landSuccessCount++;
+                //    self.SaveLandSJ(report);
+                //}
+                ////self.SaveTotalMHLand();
+                //self.ReportAllSJLand();
+                //self.LandSJRescueMissions.Clear();
+            }
+        }
+
+        if (self.KZDYMissions.Count > 0)
+        {
+            if (self.KZDYMissions.All(m => m.IsOver) && !isKZDYMissionsOver)
+            {
+                self.missionCount -= self.KZDYMissions.Count;
+                isKZDYMissionsOver = true;
+            }
+        }
+
+        if (self.KTKSMissions.Count > 0)
+        {
+            if (self.KTKSMissions.All(m => m.IsOver) && !isKTKSMissionsOver)
+            {
+                self.missionCount -= self.KTKSMissions.Count;
+                isKTKSMissionsOver = true;
+            }
+        }
+
+        if (self.ZSJYMissions.Count > 0)
+        {
+            if (self.ZSJYMissions.All(m => m.IsOver) && !isZSJYMissionsOver)
+            {
+                self.missionCount -= self.ZSJYMissions.Count;
+                isZSJYMissionsOver = true;
+            }
+        }
+
+        if (self.JJJYMissions.Count > 0)
+        {
+            if (self.JJJYMissions.All(m => m.IsOver) && !isJJJYMissionsOver)
+            {
+                self.missionCount -= self.JJJYMissions.Count;
+                isJJJYMissionsOver = true;
+            }
+        }
+
+        if (self.SHJMissions.Count > 0)
+        {
+            if (self.SHJMissions.All(m => m.IsOver) && !isSHJMissionsOver)
+            {
+                self.missionCount -= self.SHJMissions.Count;
+                isSHJMissionsOver = true;
+            }
+        }
+
+        //Console.WriteLine("self.missionCount:" + self.missionCount);
+        if (self.missionCount == 0 && !isReport)
+        {
+            for (int i = 0; i < self.ExecutionContext; i++)
+            {
+                任务准备时间 = 0;
+                平均搜索时间 = 0;
+                总飞行时间 = 0;
+                人员存活率 = 0;
+                任务是否成功 = 0;
+                识别成功率 = 0f;
+                平均救助时间 = 0;
+                人员数量 = 0;
+                识别数量 = 0;
+                环境搜索覆盖面积 = 0;
+                海上搜索覆盖面积 = 0;
+
+                aircreftCount = 0;
+                searchCount = 0;
+                jzCount = 0;
+
+                foreach (var item in self.SeaSJRescueMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        海上搜索覆盖面积 += float.Parse(item1.Value["海上搜索覆盖面积"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("海上搜救" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("海上搜救" + item1.Key + "海上搜索覆盖面积:" + item1.Value["海上搜索覆盖面积"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+                foreach (var item in self.LandSJRescueMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        环境搜索覆盖面积 += float.Parse(item1.Value["环境搜索覆盖面积"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("路上搜寻" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("路上搜寻" + item1.Key + "环境搜索覆盖面积:" + item1.Value["环境搜索覆盖面积"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+                foreach (var item in self.KZDYMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("空中吊运" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("空中吊运" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+                foreach (var item in self.KTKSMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("空投空送" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("空投空送" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+                foreach (var item in self.ZSJYMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("着水救援" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("着水救援" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+
+                foreach (var item in self.JJJYMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("机降救援" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("机降救援" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+
+                foreach (var item in self.SHJMissions)
+                {
+                    foreach (var item1 in item.aircraftSJDatas)
+                    {
+                        识别成功率 += float.Parse(item1.Value["识别成功率"][i]);
+                        人员数量 += float.Parse(item1.Value["人员数量"][i]);
+                        识别数量 += float.Parse(item1.Value["识别数量"][i]);
+                        if (任务准备时间 < float.Parse(item1.Value["任务准备时间"][i]))
+                            任务准备时间 = float.Parse(item1.Value["任务准备时间"][i]);
+                        平均搜索时间 += float.Parse(item1.Value["平均搜索时间"][i]);
+                        平均救助时间 += float.Parse(item1.Value["平均救助时间"][i]);
+                        总飞行时间 += float.Parse(item1.Value["总飞行时间"][i]);
+                        人员存活率 += float.Parse(item1.Value["人员存活率"][i]);
+                        aircreftCount++;
+                        if (item1.Value["平均搜索时间"][i] != "0")
+                            searchCount++;
+                        if (item1.Value["平均救助时间"][i] != "0")
+                            jzCount++;
+                        Console.WriteLine("索滑降" + item1.Key + "识别成功数:" + item1.Value["识别成功率"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "识别数量:" + item1.Value["识别数量"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "任务准备时间:" + item1.Value["任务准备时间"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "平均搜索时间:" + item1.Value["平均搜索时间"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "平均救助时间:" + item1.Value["平均救助时间"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "总飞行时间:" + item1.Value["总飞行时间"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "存活人数:" + item1.Value["人员存活率"][i]);
+                        Console.WriteLine("索滑降" + item1.Key + "人员数量:" + item1.Value["人员数量"][i]);
+                        Console.WriteLine("===============================================================");
+                    }
+                }
+
+                SJAllTotalTaskPerformance allTotalTaskPerformance = new SJAllTotalTaskPerformance();
+
+                if (人员存活率 != 0)
+                    任务是否成功 = 1;
+
+                if (任务是否成功 == 1)
+                    self.seaSuccessCount++;
+
+                if (识别数量 != 0)
+                    allTotalTaskPerformance.识别成功率 = (识别成功率 / 识别数量).ToString();
+                else
+                    allTotalTaskPerformance.识别成功率 = "0";
+
+                allTotalTaskPerformance.任务准备时间 = 任务准备时间.ToString();
+
+                if (searchCount != 0)
+                    allTotalTaskPerformance.平均搜索时间 = (平均搜索时间 / searchCount).ToString("f4"); // aircreftCount
+                else
+                    allTotalTaskPerformance.平均搜索时间 = "0";
+
+                if (jzCount != 0)
+                    allTotalTaskPerformance.平均救助时间 = (平均救助时间 / jzCount).ToString("f4"); // aircreftCount
+                else
+                    allTotalTaskPerformance.平均救助时间 = "0";
+
+                allTotalTaskPerformance.总飞行时间 = 总飞行时间.ToString("f4");
+
+                allTotalTaskPerformance.海上搜索覆盖面积 = 海上搜索覆盖面积.ToString();//"0.6".ToString();//"60%"
+
+                allTotalTaskPerformance.环境搜索覆盖面积 = 环境搜索覆盖面积.ToString();//"0.6".ToString();
+
+                allTotalTaskPerformance.任务是否成功 = 任务是否成功.ToString();
+
+
+                if (人员数量 != 0)
+                    allTotalTaskPerformance.人员存活率 = (人员存活率 / 人员数量).ToString();
+                else
+                    allTotalTaskPerformance.人员存活率 = "0";
+
+                Console.WriteLine("单轮次总体指标识别成功率:" + allTotalTaskPerformance.识别成功率);
+                Console.WriteLine("单轮次总体指标任务准备时间:" + allTotalTaskPerformance.任务准备时间);
+                Console.WriteLine("单轮次总体指标平均搜索时间:" + allTotalTaskPerformance.平均搜索时间);
+                Console.WriteLine("单轮次总体指标平均救助时间:" + allTotalTaskPerformance.平均救助时间);
+                Console.WriteLine("单轮次总体指标总飞行时间:" + allTotalTaskPerformance.总飞行时间);
+                Console.WriteLine("单轮次总体指标海上搜索覆盖面积:" + allTotalTaskPerformance.海上搜索覆盖面积);
+                Console.WriteLine("单轮次总体指标环境搜索覆盖面积:" + allTotalTaskPerformance.环境搜索覆盖面积);
+                Console.WriteLine("单轮次总体指标任务是否成功:" + allTotalTaskPerformance.任务是否成功);
+                Console.WriteLine("单轮次总体指标人员存活率:" + allTotalTaskPerformance.人员存活率);
+                Console.WriteLine("===============================================================");
+
+                Dictionary<string, Dictionary<string, string>> report = new Dictionary<string, Dictionary<string, string>>();
+
+                if (self.isSea)
+                {
+                    report["总任务表现"] = new Dictionary<string, string>
+                {
+                    { "识别成功率", allTotalTaskPerformance.识别成功率.ToString() },
+                    { "任务准备时间", allTotalTaskPerformance.任务准备时间.ToString() },
+                    { "平均搜索时间", allTotalTaskPerformance.平均搜索时间.ToString() },
+                    { "平均救助时间", allTotalTaskPerformance.平均救助时间.ToString() },
+                    { "总飞行时间", allTotalTaskPerformance.总飞行时间.ToString() },
+                    { "海上搜索覆盖面积", allTotalTaskPerformance.海上搜索覆盖面积.ToString() },
+                    { "任务是否成功", allTotalTaskPerformance.任务是否成功.ToString() },
+                    { "人员存活率", allTotalTaskPerformance.人员存活率.ToString() }
+                };
+                }
+                else if (self.isLand)
+                {
+                    report["总任务表现"] = new Dictionary<string, string>
+                {
+                    { "识别成功率", allTotalTaskPerformance.识别成功率.ToString() },
+                    { "任务准备时间", allTotalTaskPerformance.任务准备时间.ToString() },
+                    { "平均搜索时间", allTotalTaskPerformance.平均搜索时间.ToString() },
+                    { "平均救助时间", allTotalTaskPerformance.平均救助时间.ToString() },
+                    { "总飞行时间", allTotalTaskPerformance.总飞行时间.ToString() },
+                    { "环境搜索覆盖面积", allTotalTaskPerformance.环境搜索覆盖面积.ToString() },
+                    { "任务是否成功", allTotalTaskPerformance.任务是否成功.ToString() },
+                    { "人员存活率", allTotalTaskPerformance.人员存活率.ToString() }
+                };
+                }
+
+                self.SaveSeaSJ(report);
+            }
+            self.ReportAllSJSea();
+            isReport = true;
 
+            Console.WriteLine("所有任务执行完成");
+        }
+    }
+}

+ 266 - 0
SimulationServer/Entity/AircraftDY.cs

@@ -0,0 +1,266 @@
+using KYFramework;
+using Model;
+using MongoDB.Bson;
+using SimulationCommon;
+
+namespace SimulationServer;
+
+public class AircraftDY : AircraftEntity
+{
+    public TaskParameter SHJParameter;
+    public KZDYTask taskContent;
+    public MissionEndPoint MissionEndPoint;
+    public bool IsOver;
+    public bool Success;
+    public TaskParameter taskParameter;
+    public GetNCData getNCData;
+    public double resulttime;
+
+    public int targetCount;
+
+    public bool isReadNC;
+
+    Text_readNC text_ReadNC;
+    public override void End()
+    {
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[^1].RemainingFuel;
+    }
+
+    public override void Reset()
+    {
+        base.Reset();
+        IsOver = false;
+        Success = false;
+        TotalTime = 0;
+        targetCount = 0;
+    }
+
+    public override void Start()
+    {
+        targetCount = FlightPlanEditor.targetpoint[0].TargetType.Count;
+
+        if (!isReadNC)
+        {
+            getNCData = new GetNCData();
+            getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+            getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+            bool isSuccess3 = false;
+            while (!isSuccess3)
+            {
+                isSuccess3 = getNCData.GetData();
+            }
+            text_ReadNC = new Text_readNC();
+            text_ReadNC.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+            text_ReadNC.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+            //text_ReadNC = new Text_readNC();
+            bool isSuccess = false;
+            while (!isSuccess)
+            {
+                isSuccess = text_ReadNC.GetNCData();
+            }
+            isReadNC = true;
+        }
+
+        int hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]);
+        //Console.WriteLine("hour:" + hour);
+        double windSpeed = Convert.ToDouble(TargetQiXiangInfoSave("风速", hour));
+        //Console.WriteLine("windSpeed:" + windSpeed);
+        double vis = Convert.ToDouble(TargetQiXiangInfoSave("能见度", hour));
+        //Console.WriteLine("vis:" + vis);
+
+        FlightPlanEditor.missionpoint.MissionPointLatitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+        FlightPlanEditor.missionpoint.MissionPointLongitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+        FlightPlanEditor.missionpoint.MissionPointHeight = FlightPlanEditor.targetpoint[0].TargetPointHeight;
+        //Console.WriteLine("Latitude:" + FlightPlanEditor.missionpoint.MissionPointLatitude + "_" + "Longitude:" + FlightPlanEditor.missionpoint.MissionPointLongitude + "_" + "Height:" + FlightPlanEditor.missionpoint.MissionPointHeight);
+
+        FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints);//生成从起点到任务段起点的航路点
+        // 吊运上升速度  吊运下降速度 Task文件读取 // Editor里读天气根据时间
+        resulttime = get_result_time_rope(taskParameter.Height, taskParameter.liftPersonnel, windSpeed, vis, taskParameter.liftUpSpeed, taskParameter.liftDownSpeed).time;//索滑降模型输出的索滑降时间
+        Console.WriteLine("resulttime:" + resulttime);
+        FXJHGenerate.SuoHuaJiang(resulttime, FlightPlanEditor, ref TurningPoints);
+
+        FXJHGenerate.FromMissionToEnd(FlightPlanEditor, FXJHGenerate.SuoHuaJiangMissionEndPoint(FlightPlanEditor), ref TurningPoints); 
+        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
+
+        // 飞到目标点时间与人员存活时间做对比  有一个人活着,整个任务成功
+        double time = 0;
+        for (int i = 0; i < TurningPoints.Count - 1; i++)
+        {
+            time += TurningPoints[i].SegmentFlightTime; // 判断幸存-1
+        }
+        //Console.WriteLine("time:" + time);
+
+        // 类型只有人,其它不影响任务成功率 ,所有目标都影响识别成功率  任务准备时间 分钟 平均搜索时间 小时 平均救助时间 秒 总飞行时间 小时 第一列加单位
+
+        if (FlightPlanEditor.targetpoint[0].TargetType.Type == "落水人员")
+        {
+            double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用
+            double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用
+            int Days;
+            int Hour;
+            int Year = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[0]);
+            int Month = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]);
+            int Day = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]);
+            Hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]);
+            Days = GetDaysInYear(Year, Month, Day);
+            double survivalTime = SurvivalTimeModel.SurvivalTime(getNCData.tempreadNC, latitude, longitude, time, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, Days, Hour); //幸存时间
+            //Console.WriteLine("survivalTime:" + survivalTime * 3600);
+            if (survivalTime * 3600 > time)
+            {
+                Success = true;
+                //Console.WriteLine("Success:" + true);
+            }
+        }
+
+        if (FlightPlanEditor.targetpoint[0].TargetType.Type == "遇险人员")
+        {
+            if (FlightPlanEditor.targetpoint[0].TargetType.LiveTime > time)   //陆上搜寻预期存活时间读配置文件
+            {
+                Success = true;
+                //Console.WriteLine("Success:" + true);
+            }
+        }
+
+        for (int i = 0; i < TurningPoints.Count; i++) // 总飞行时间
+        {
+            TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间   //仿真轮次1 数值1
+        }
+        Console.WriteLine("TotalTime:" + TotalTime);
+        IsOver = true;
+        End();
+    }
+
+    // --接口
+    // --输入
+    // --
+    // 1)吊运高度(m)
+    //--H(double)
+    // 2)吊运人数
+    //--person_number(int)
+    // 3)风速(m/s)
+    //--windspeed(double)
+    // 4)能见度(m/)
+    // --vis(double)
+    // 5)吊运上升速度(m/s)
+    //--upspeed(double)
+    // 6)吊运下降速度(m/s)
+    //--downspeed(double)
+    // --
+    // --输出
+    // --
+    // 1)能否吊运、吊运时间
+    //--result(handling_result)
+    // --
+    //--定义handling_result类
+
+    // 吊运函数
+    public static handling_result get_result_time_rope(double H, int person_number, double windspeed, double vis, double upspeed, double downspeed)
+    {
+
+        handling_result result = new handling_result();
+
+        if (windspeed < 8 && vis > 3)
+        {
+            result.time = (person_number * H) / downspeed + (person_number * H) / upspeed;
+            result.success = true;
+        }
+        else
+        {
+            result.success = false;
+        }
+        return result;
+    }
+
+    public string TargetQiXiangInfoSave(string s, int hour)
+    {
+        string result = hour.ToString() + "-" + s;
+        switch (s)
+        {
+            case "温度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_19_24.ToString();
+                break;
+            case "湿度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_19_24.ToString();
+                break;
+            case "能见度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_19_24.ToString();
+                break;
+            case "风速":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_19_24.ToString();
+                break;
+            case "风向":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_19_24.ToString();
+                break;
+            case "天气":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_00_08;
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_08_19;
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_19_24;
+                break;
+        }
+        return result;
+    }
+
+    public static int GetDaysInYear(int year, int month, int day)
+    {
+        int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+        if (IsLeapYear(year))
+        {
+            daysInMonths[1] = 29;
+        }
+        int days = day;
+        for (int i = 0; i < month - 1; i++)
+        {
+            days += daysInMonths[i];
+        }
+        return days;
+    }
+
+    public static bool IsLeapYear(int year)
+    {
+        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
+    }
+}
+
+public class handling_result
+{
+    public bool success { get; set; }
+    public double time { get; set; }
+}
+
+[ObjectSystem]
+public class AircraftDYAwakeSystem : AwakeSystem<AircraftDY, FlightPlanEditor>
+{
+    public override void Awake(AircraftDY self, FlightPlanEditor flightPlanEditor)
+    {
+        self.FlightPlanEditor = flightPlanEditor;
+        self.Awake();
+    }
+}

+ 75 - 0
SimulationServer/Entity/AircraftEntity.cs

@@ -0,0 +1,75 @@
+using KYFramework;
+using Model;
+using SimulationServer.Utils;
+
+namespace SimulationServer;
+
+public class AircraftEntity : Entity
+{
+    public string TaskName { get; set; } // 任务名称
+    public string Name { get; set; } // 飞机名称
+    public string AircraftId { get; set; } // 飞机编号
+    public string AircraftIndex { get; set; } // 飞机索引
+    public string Type { get; set; } // 飞机类型
+    public AircraftDB Db { get; set; } // 飞机数据库参数
+    public FlightPlanEditor? FlightPlanEditor { get; set; } // 飞行计划编辑器
+    public string Airport { get; set; } // 飞机机场
+    public double T { get; set; } // 飞机飞到火场需要的时间
+    public double TotalFuelConsumption { get; set; } // 总燃油消耗
+    public double FirstTime { get; set; } //单机入场时间
+    public double TaskResponseTime { get; set; } = 600; // 任务响应时间
+    public double EffMisTime { get; set; } // 单机有效任务时长
+
+    //搜索时间
+    public double SearchTime { get; set; }
+
+    public double TotalTime { get; set; }
+    public double TaskReadyTime { get; set; } // 任务准备时间
+    public bool SyncOver { get; set; } // 是否同步完成
+
+    public double[] Velocitys = new double[5] { 220, 220, 220, 110, 0 }; // 速度
+
+    public double[] FuelConsumptions = new double[5] { 2800, 2800, 2800, 1000, 132 }; // 燃油消耗
+
+    public List<TurningPoint> TurningPoints = new List<TurningPoint>(); // 航路点
+
+    public void Awake()
+    {
+        Db = Util.GetAircraftDefine(FlightPlanEditor.aircraftparameter.AircraftType, FlightPlanEditor.aircraftparameter.AircraftSubType, FlightPlanEditor.aircraftparameter.AircraftID);
+
+        if (Db.f_zdqfzl != null)
+            FlightPlanEditor.aircraftparameter.MaxTakeoffWeight = double.Parse(Db.f_zdqfzl.ToString());
+        else
+            FlightPlanEditor.aircraftparameter.MaxTakeoffWeight = 8000;
+        if (Db.f_zdzkl != null)
+            FlightPlanEditor.aircraftparameter.MaxPassengerNumber = double.Parse(Db.f_zdzkl.ToString());
+        else
+            FlightPlanEditor.aircraftparameter.MaxPassengerNumber = 20;
+    }
+
+    public virtual void Reset()
+    {
+        T = 0;
+        EffMisTime = 0;
+        FirstTime = 0;
+        TotalFuelConsumption = 0;
+        TaskResponseTime = 0;
+        TurningPoints = new List<TurningPoint>();
+    }
+
+    public virtual void Start()
+    {
+
+    }
+
+
+    public virtual void Update(double time)
+    {
+
+    }
+
+    public virtual void End()
+    {
+
+    }
+}

+ 112 - 0
SimulationServer/Entity/AircraftJJ.cs

@@ -0,0 +1,112 @@
+using KYFramework;
+using Model;
+using SimulationServer.Utils;
+using Define = SimulationServer.Utils.Define;
+
+namespace SimulationServer;
+
+public class AircraftJJ : AircraftEntity
+{
+    public string NextMissionId; // 下一个任务ID
+    public MissionEndPoint missionEndPoint = new MissionEndPoint();
+
+    public int LandingPersonnel; //personCount
+    public MHRescueMission mhRescueMission;
+
+    public int landingPoint = 0; // 任务文件获取
+
+    public JJJYTask taskContent;
+    public TaskParameter taskParameter;
+    public RescueDemandInfo rescueDemandInfo;
+    public bool IsOver;
+    public bool Success;
+
+    public override void End()
+    {
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[^1].RemainingFuel;
+    }
+
+    public override void Reset()
+    {
+        base.Reset();
+        IsOver = false;
+        Success = false;
+        TotalTime = 0;
+    }
+    public override void Start()
+    {
+        FlightPlanEditor.missionpoint.MissionPointLatitude = rescueDemandInfo.TargetPointLatitude;
+        FlightPlanEditor.missionpoint.MissionPointLongitude = rescueDemandInfo.TargetPointLongitude;
+        FlightPlanEditor.missionpoint.MissionPointHeight = rescueDemandInfo.TargetPointHeight;
+
+        missionEndPoint.MissionEndPointLatitude = FlightPlanEditor.missionpoint.MissionPointLatitude;
+        missionEndPoint.MissionEndPointLongitude = FlightPlanEditor.missionpoint.MissionPointLongitude;
+        missionEndPoint.MissionEndPointHeight = FlightPlanEditor.missionpoint.MissionPointHeight;
+
+        FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints);//生成从起点到任务段起点的航路点
+
+        int TransportNumber = (int)Math.Ceiling(taskParameter.LandingPersonnel / FlightPlanEditor.aircraftparameter.MaxPassengerNumber);
+
+        int j = 0;
+
+
+        for (int i = 0; i < TransportNumber; i++)
+        {
+            if (i == 0)
+            {
+                FXJHGenerate.JijiangJiuYuan1(FlightPlanEditor, ref TurningPoints);
+            }
+            else
+            {
+                FXJHGenerate.JijiangJiuYuan(FlightPlanEditor, ref TurningPoints);
+                j += 2;
+            }
+
+        }
+        // FXJHGenerate.InitializeVelocities(FlightPlanEditor, TurningPoints, ref Velocitys);
+        // FXJHGenerate.InitializeFuelConsumptions(FlightPlanEditor, TurningPoints,ref FuelConsumptions);
+
+        FXJHGenerate.FromMissionToEnd(FlightPlanEditor, missionEndPoint, ref TurningPoints);
+        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); // 更新了 计算油耗的方法
+
+        for (int i = 0; i < TurningPoints.Count; i++) // 总飞行时间
+        {
+            TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间   //仿真轮次1 数值1
+            //Console.WriteLine("TotalTime:" + TotalTime);
+        }
+        Console.WriteLine("TotalTime:" + TotalTime);
+        IsOver = true;
+        //Success = true; //需要判断
+        End();
+    }
+
+    //private 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;
+    //}
+
+    public override void Update(double time)
+    {
+
+    }
+}
+
+
+[ObjectSystem]
+public class AircraftJJAwakeSystem : AwakeSystem<AircraftJJ, FlightPlanEditor>
+{
+    public override void Awake(AircraftJJ self, FlightPlanEditor flightPlanEditor)
+    {
+        self.FlightPlanEditor = flightPlanEditor;
+        self.Awake();
+    }
+}

+ 403 - 0
SimulationServer/Entity/AircraftKTKS.cs

@@ -0,0 +1,403 @@
+using KYFramework;
+using Model;
+using Newtonsoft.Json;
+using Org.BouncyCastle.Utilities;
+using SimulationCommon;
+using SimulationServer.Utils;
+using Define = SimulationServer.Utils.Define;
+
+namespace SimulationServer;
+
+public class AircraftKTKS : AircraftEntity
+{
+    public string NextMissionId; // 下一个任务ID
+    public MissionEndPoint missionEndPoint = new MissionEndPoint();
+
+    public int LandingPersonnel; //personCount
+    public MHRescueMission mhRescueMission;
+
+    public int landingPoint = 0; // 任务文件获取
+
+    public MissionPoint missionpoint = new MissionPoint();
+
+    public KTKSTask taskContent; // 创建任务里需要赋值!!!
+    int Days;
+    int Hour;
+
+    public TaskParameter taskParameter;
+    public bool IsOver;
+    public bool Success;
+
+    public RescueDemandInfo rescueDemandInfo;
+
+    public bool isReadNC;
+
+    Text_readNC text_ReadNC;
+
+    public override void End()
+    {
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[^1].RemainingFuel;
+    }
+
+    public override void Reset()
+    {
+        base.Reset();
+        IsOver = false;
+        Success = false;
+        TotalTime = 0;
+    }
+    public override void Start()
+    {
+        // FlightPlanEditor.targetpoint = 空投点
+
+        FlightPlanEditor.missionpoint.MissionPointLatitude = rescueDemandInfo.TargetPointLatitude;
+        FlightPlanEditor.missionpoint.MissionPointLongitude = rescueDemandInfo.TargetPointLongitude;
+        FlightPlanEditor.missionpoint.MissionPointHeight = rescueDemandInfo.TargetPointHeight;
+        //Console.WriteLine("MissionPointLatitude:" + FlightPlanEditor.missionpoint.MissionPointLatitude);
+
+        FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints);//生成从起点到任务段起点的航路点
+
+        int TransportNumber = (int)Math.Ceiling(LandingPersonnel / FlightPlanEditor.aircraftparameter.MaxPassengerNumber);
+
+        int j = 0;
+        //FlightPlanEditor.missionpoint.MissionPointLatitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+        //FlightPlanEditor.missionpoint.MissionPointLongitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+        //FlightPlanEditor.missionpoint.MissionPointHeight = FlightPlanEditor.targetpoint[0].TargetPointHeight;
+        FXJHGenerate.KouTouKouSong(FlightPlanEditor, ref TurningPoints);
+        double alpha = CalculateEastBaseAngle(TurningPoints[0].TurningPointLatitude, TurningPoints[0].TurningPointLongitude, TurningPoints[2].TurningPointLatitude, TurningPoints[2].TurningPointLongitude);
+        //FXJHGenerate.CalculateTrueHeading(FlightPlanEditor, ref TurningPoints);
+        // FXJHGenerate.InitializeVelocities(FlightPlanEditor, TurningPoints, ref Velocitys);
+        // FXJHGenerate.InitializeFuelConsumptions(FlightPlanEditor, TurningPoints,ref FuelConsumptions);
+
+        //FXJHGenerate.FromMissionToEnd(FlightPlanEditor, missionEndPoint, ref TurningPoints);
+        //FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); // 更新了 计算油耗的方法
+
+        int Year = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[0]);
+        int Month = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]);
+        int Day = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]);
+        Hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]);
+        Days = GetDaysInYear(Year, Month, Day);
+        if (!isReadNC)
+        {
+            text_ReadNC = new Text_readNC();
+            text_ReadNC.initlatitudes = rescueDemandInfo.TargetPointLatitude;
+            text_ReadNC.initlongitudes = rescueDemandInfo.TargetPointLongitude;
+            bool isSuccess = false;
+            while (!isSuccess)
+            {
+                isSuccess = text_ReadNC.GetNCData();
+            }
+            isReadNC = true;
+        }
+        var nCread = text_ReadNC.windNCread;
+
+        double[] windVelocity = GetWindVelocityFromAPI(nCread, rescueDemandInfo.TargetPointLatitude, rescueDemandInfo.TargetPointLongitude, text_ReadNC.latitudes, text_ReadNC.longitudes, Days, Hour);
+        var windSpeed = Math.Sqrt(windVelocity[0] * windVelocity[0] + windVelocity[1] * windVelocity[1]);
+        var theta = Math.Asin(windVelocity[0] / windSpeed);
+
+        List<double> KTiniposition = new List<double>();
+        List<double> KTresultPostion = new List<double>();
+
+        double KTheight;
+
+        if (taskParameter.isParachute)  //空投空送任务文件读取
+        {
+            KTheight = 200;
+            // 空投迎风面积 = 1.5 空投空送任务文件读取 50 = 空投重量 空投空送任务文件读取
+            KTiniposition = getPositionWithUmbrella(FlightPlanEditor.missionpoint.MissionPointLongitude, FlightPlanEditor.missionpoint.MissionPointLatitude, KTheight, windSpeed, theta, taskParameter.airdropWindArea, taskParameter.airdropWeight);
+            double inix = Mokatuo_lon(KTiniposition[1]);
+            double iniy = Mokatuo_lat(KTiniposition[0]);
+
+            double resultX = inix + 33 * Math.Cos(alpha) * KTiniposition[2] / 1000;
+            double resultY = iniy + 33 * Math.Sin(alpha) * KTiniposition[2] / 1000;
+
+            KTresultPostion.Add(ReMokatuo_lat(resultY));
+            KTresultPostion.Add(ReMokatuo_lon(resultX));
+        }
+        else
+        {
+            KTheight = 20;
+            KTiniposition = getPositionWithoutUmbrella(FlightPlanEditor.missionpoint.MissionPointLongitude, FlightPlanEditor.missionpoint.MissionPointLatitude, KTheight, windSpeed, 22, alpha, theta);
+            double inix = Mokatuo_lon(KTiniposition[1]);
+            double iniy = Mokatuo_lat(KTiniposition[0]);
+
+            double resultX = inix + 22 * Math.Cos(alpha) * KTiniposition[2] / 1000;
+            double resultY = iniy + 22 * Math.Sin(alpha) * KTiniposition[2] / 1000;
+
+            KTresultPostion.Add(ReMokatuo_lat(resultY));
+            KTresultPostion.Add(ReMokatuo_lon(resultX));
+        }
+
+        TurningPoints.RemoveAt(2);
+
+        if(taskParameter.airdropWay == "带速空投")
+        {
+            FlightPlanEditor.missionpoint.MissionPointLatitude = KTiniposition[0];
+            FlightPlanEditor.missionpoint.MissionPointLongitude = KTiniposition[1];
+            FlightPlanEditor.missionpoint.MissionPointHeight = KTheight;
+
+            missionpoint.MissionPointLatitude = KTresultPostion[0];
+            missionpoint.MissionPointLongitude = KTresultPostion[1];
+            missionpoint.MissionPointHeight = KTheight;
+
+            missionEndPoint.MissionEndPointLatitude = KTresultPostion[0];
+            missionEndPoint.MissionEndPointLongitude = KTresultPostion[1];
+            missionEndPoint.MissionEndPointHeight = KTheight;
+        }
+
+        else if(taskParameter.airdropWay == "悬停空投")
+        {
+            FlightPlanEditor.missionpoint.MissionPointLatitude = KTiniposition[0];
+            FlightPlanEditor.missionpoint.MissionPointLongitude = KTiniposition[1];
+            FlightPlanEditor.missionpoint.MissionPointHeight = KTheight;
+
+            missionpoint.MissionPointLatitude = KTiniposition[0];
+            missionpoint.MissionPointLongitude = KTiniposition[1];
+            missionpoint.MissionPointHeight = KTheight;
+
+            missionEndPoint.MissionEndPointLatitude = KTiniposition[0];
+            missionEndPoint.MissionEndPointLongitude = KTiniposition[1];
+            missionEndPoint.MissionEndPointHeight = KTheight;
+        }
+
+        FXJHGenerate.KouTouKouSong(FlightPlanEditor, ref TurningPoints);
+        FXJHGenerate.KouTouKouSong1(missionpoint, ref TurningPoints);
+
+        TurningPoints[2].SegmentFlightTime = KTiniposition[2];
+
+        FXJHGenerate.FromMissionToEnd(FlightPlanEditor, missionEndPoint, ref TurningPoints);
+        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); // 更新了 计算油耗的方法
+
+        for (int i = 0; i < TurningPoints.Count; i++) // 总飞行时间
+        {
+            TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间   //仿真轮次1 数值1
+        }
+        Console.WriteLine("TotalTime:" + TotalTime);
+        IsOver = true;
+        //Success = true; //需要判断
+        End();
+    }
+
+    //private 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;
+    //}
+
+    public override void Update(double time)
+    {
+
+    }
+
+    // --接口
+    // --输入
+    // --
+    // 1)遇险人员位置经度(空投拟落点位置经度)
+    // --longitude(double)
+    // 2)遇险人员位置维度(空投拟落点位置维度)
+    //--latitude(double)
+    // 3)释放空投时飞机的高度(m)
+    //--altitude(double)
+    // 4)飞行器空投速度(m/s)
+    //--windspeed(double)
+    // 5)飞行速度与维度夹角(度)(应该可以在飞机的运动学参数读出来)__________东向为0
+    //--alpha(double)__________先定值,后续与子涵对
+    // 6)风速与维度夹角(度)(环境参数)__________东向为0
+    //--theta(double)__________改成风向
+    // 7)风速(m/s)
+    //--windspeed(double)
+    // 8)空投重量(kg)
+    //--m(double)
+    // 9)空投迎风面积(m2)(空投侧面积即可)
+    //--s(double)
+    // 10)空投距离多远算做成功
+    //--l(m)(double)
+    // --
+    // --输出
+    // --
+    // 1)可以空投区域的中心点经纬度
+    //--result(List<double>)
+    // 2)空投距离多远算做成功(m)
+    //--l(double)
+    // -- 三个输出变量构一个圆形区域
+    // --
+    //返回高度、速度、空投任务段时间
+
+    public static double[] GetWindVelocityFromAPI(NCread windNCread, double latitude, double longitude, int latitudes, int longitudes, int days, int hour)
+    {
+        float[] longitudeArray = windNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs'
+        float[] latitudeArray = windNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs'
+        float[][][] u10Array = windNCread.u10Array;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs'
+        float[][][] v10Array = windNCread.v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs'
+
+        int longitudeNum = 0;
+        int latitudeNum = 0;
+        int temptimeNum = 0;
+        //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
+        //经度连续化
+        for (int i = 0; i < longitudes - 1; i++)
+        {
+            if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
+            {
+                longitude = longitudeArray[i];
+                longitudeNum = i;
+            }
+        }
+
+        //纬度连续化
+        for (int i = 0; i < latitudes - 1; i++)
+        {
+            if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
+            {
+                latitude = latitudeArray[i];
+                latitudeNum = i;
+            }
+        }
+
+        temptimeNum += (days - 1) * 24 + hour - 1;
+
+        double windX = (double)u10Array[temptimeNum][latitudeNum][longitudeNum];
+        double windY = (double)v10Array[temptimeNum][latitudeNum][longitudeNum];
+
+        return new double[] { windX, windY };
+    }
+
+    // --主要方法
+    // --墨卡托投影函
+    public double Mokatuo_lat(double lat)
+    {
+        double R = 6378.137;
+        double y = R * Math.Log(Math.Tan((lat + 90) * Math.PI / 360));
+        return y;
+    }
+    public double Mokatuo_lon(double lon)
+    {
+        double R = 6378.137;
+        double x = (lon * Math.PI * R) / 180;
+        return x;
+    }
+
+    // --反墨卡托投影函数
+    public double ReMokatuo_lat(double y)
+    {
+        double R = 6378.137;
+        double lat = (2 * Math.Atan(Math.Exp(y / R)) - Math.PI / 2) * 180 / Math.PI;
+        return lat;
+    }
+
+    public double ReMokatuo_lon(double x)
+    {
+        double R = 6378.137;
+        double lon = x * 180 / (Math.PI * R);
+        return lon;
+    }
+    // --不开伞空投计算函数
+    //速度80km/h;高度20m
+    public List<double> getPositionWithoutUmbrella(double longitude, double latitude, double altitude, double windspeed, double velocity, double alpha, double theta)
+    {
+        double g = 9.8;
+        double time = Math.Sqrt(2 * altitude / g);
+        double x = Mokatuo_lon(longitude);
+        double y = Mokatuo_lat(latitude);
+        double vx = velocity * Math.Cos(alpha) + windspeed * Math.Cos(theta);
+        double vy = velocity * Math.Sin(alpha) + windspeed * Math.Sin(theta);
+        double y_new = y + vy * time / 1000;
+        double x_new = x + vx * time / 1000;
+        double lat = ReMokatuo_lat(y_new);
+        double lon = ReMokatuo_lon(x_new);
+        List<double> result = new List<double>()
+            {lat, lon,time};
+        return result; //投放空投的位置
+    }
+    // --开伞空投计算函数
+    //速度120km/h;高度200m
+    public List<double> getPositionWithUmbrella(double longitude, double latitude, double altitude, double windspeed, double theta, double s, double m)
+    {
+        double g = 9.8;
+        double k = 3.824 * s;
+        double vz = Math.Sqrt(m * g / k);
+        double time = altitude / vz;
+        double x = Mokatuo_lon(longitude);
+        double y = Mokatuo_lat(latitude);
+        double y_new = y + windspeed * Math.Sin(theta) * time / 1000;
+        double x_new = x + windspeed * Math.Cos(theta) * time / 1000;
+        double lat = ReMokatuo_lat(y_new);
+        double lon = ReMokatuo_lon(x_new);
+        List<double> result = new List<double>()
+            {lat, lon,time};
+        Console.WriteLine(y_new);
+        Console.WriteLine(y);
+        return result; //投放空投的位置
+    }
+
+    public static int GetDaysInYear(int year, int month, int day)
+    {
+        int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+        if (IsLeapYear(year))
+        {
+            daysInMonths[1] = 29;
+        }
+        int days = day;
+        for (int i = 0; i < month - 1; i++)
+        {
+            days += daysInMonths[i];
+        }
+        return days;
+    }
+
+    public static bool IsLeapYear(int year)
+    {
+        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
+    }
+
+    public static double CalculateEastBaseAngle(double lat1, double lon1, double lat2, double lon2)
+    {
+        // 转换为弧度
+        double lat1Rad = lat1 * Math.PI / 180;
+        double lon1Rad = lon1 * Math.PI / 180;
+        double lat2Rad = lat2 * Math.PI / 180;
+        double lon2Rad = lon2 * Math.PI / 180;
+
+        double deltaLon = lon2Rad - lon1Rad;
+
+        // 计算真航向角
+        double x = Math.Sin(deltaLon) * Math.Cos(lat2Rad);
+        double y = Math.Cos(lat1Rad) * Math.Sin(lat2Rad) - Math.Sin(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(deltaLon);
+
+        double headingRad = Math.Atan2(x, y);
+        double headingDeg = headingRad * 180 / Math.PI;
+
+        // 标准化真航向角(以正北为基准)
+        headingDeg = (headingDeg + 360) % 360;
+
+        // 转换为以正东为基准的角度,逆时针方向
+        double eastBaseAngle = (90 - headingDeg) % 360;
+        if (eastBaseAngle < 0)
+        {
+            eastBaseAngle += 360;
+        }
+
+        return eastBaseAngle;
+    }
+
+}
+
+
+[ObjectSystem]
+public class AircraftKTKSAwakeSystem : AwakeSystem<AircraftKTKS, FlightPlanEditor>
+{
+    public override void Awake(AircraftKTKS self, FlightPlanEditor flightPlanEditor)
+    {
+        self.FlightPlanEditor = flightPlanEditor;
+        self.Awake();
+        //self.Reset();
+    }
+}

+ 188 - 0
SimulationServer/Entity/AircraftZS.cs

@@ -0,0 +1,188 @@
+using KYFramework;
+using KYFramework.Network;
+using Model;
+using SimulationServer.Utils;
+using Define = SimulationServer.Utils.Define;
+
+namespace SimulationServer;
+
+public class AircraftZS : AircraftEntity
+{
+    public string NextMissionId; // 下一个任务ID
+    public MissionEndPoint missionEndPoint = new MissionEndPoint();
+
+    public int LandingPersonnel; //personCount
+    public MHRescueMission mhRescueMission;
+
+    public int 单次救援人数 = 80; // 任务文件读取
+    public int 观察盘旋圈数 = 3; //任务文件读取
+
+    public int landingPoint = 0;
+
+    public List<Model.AirRoute> airRoutes = new List<Model.AirRoute>();
+
+    public ZSJYTask taskContent;
+    public TaskParameter taskParameter;
+    public bool IsOver;
+    public bool Success;
+
+    public override void End()
+    {
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[^1].RemainingFuel;
+    }
+
+    public override void Reset()
+    {
+        base.Reset();
+        IsOver = false;
+        Success = false;
+        TotalTime = 0;
+    }
+    public override void Start()
+    {
+        FlightPlanEditor.missionpoint.MissionPointLatitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+        FlightPlanEditor.missionpoint.MissionPointLongitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+        FlightPlanEditor.missionpoint.MissionPointHeight = FlightPlanEditor.targetpoint[0].TargetPointHeight;
+        //Console.WriteLine("MissionPointLatitude:" + FlightPlanEditor.missionpoint.MissionPointLatitude);
+
+        int count = 0;
+        foreach (var item in taskContent.ZSJYParameters)
+        {
+            //Console.WriteLine("item.AircraftId:" + item.AircraftId);
+            //Console.WriteLine("FlightPlanEditor.aircraftparameter.AircraftID:" + FlightPlanEditor.aircraftparameter.Id);
+            if (item.AircraftId == FlightPlanEditor.aircraftparameter.Id)
+            {
+                double a = (double)taskContent.missionInformation.TaskEndConditions.person_number_Rescue;
+                double b = (double)item.RescuePersonnel;
+                count = (int)Math.Ceiling(a / b);
+                //Console.WriteLine("count:" + count);
+            }
+        }
+
+        for (int j = 0; j < count; j++)
+        {
+            FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints);//生成从起点到任务段起点的航路点
+
+            missionEndPoint.MissionEndPointLatitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+            missionEndPoint.MissionEndPointLongitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+            missionEndPoint.MissionEndPointHeight = FlightPlanEditor.targetpoint[0].TargetPointHeight;
+
+            airRoutes.Clear();
+            List<double> list = GenerateCircleTrajectory(FlightPlanEditor.targetpoint[0].TargetPointLatitude, FlightPlanEditor.targetpoint[0].TargetPointLongitude, 1, 360);
+            //airRoutes = list
+            Model.AirRoute airRoute = new Model.AirRoute();
+            for (int i = 0; i < list.Count; i++)
+            {
+                if (i % 2 == 0)
+                {
+                    //Console.WriteLine("i0:" + list[i]);
+                    airRoute = new Model.AirRoute();
+                    airRoute.AirRouteLongitude = list[i];
+                }
+                else
+                {
+                    //Console.WriteLine("i1:" + list[i]);
+                    airRoute.AirRouteLatitude = list[i];
+                    airRoutes.Add(airRoute);
+                }
+            }
+
+            for (int i = 0; i < taskParameter.TurnsNumber; i++)
+            {
+                FXJHGenerate.ZhaoShuiJiuYuan(airRoutes, ref TurningPoints);
+
+            }
+
+            FXJHGenerate.ZhaoShuiJiuYuan1(airRoutes, ref TurningPoints);
+
+            FXJHGenerate.FromMissionToEnd(FlightPlanEditor, missionEndPoint, ref TurningPoints);
+        }
+
+        // FXJHGenerate.InitializeVelocities(FlightPlanEditor, TurningPoints, ref Velocitys);
+        // FXJHGenerate.InitializeFuelConsumptions(FlightPlanEditor, TurningPoints,ref FuelConsumptions);
+
+        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); // 更新了 计算油耗的方法
+
+        for (int i = 0; i < TurningPoints.Count; i++) // 总飞行时间
+        {
+            TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间   //仿真轮次1 数值1
+            //Console.WriteLine("TotalTime:" + TotalTime);
+        }
+        Console.WriteLine("TotalTime:" + TotalTime);
+
+        IsOver = true;
+        //Success = true; //需要判断
+        End();
+    }
+
+    // centerLat centerLon 想定里目标点的经纬度 radiusKm = 1 numPoints = 360  返回的airRoutes  // 
+
+    // 生成圆形轨迹点,并以 double 列表形式返回(按经度-纬度顺序存储)
+    public static List<double> GenerateCircleTrajectory(double centerLat, double centerLon, double radiusKm, int numPoints)
+    {
+        var points = new List<double>();
+        double earthRadius = 6371.0; // 地球半径,单位:公里
+
+        for (int i = 0; i < numPoints; i++)
+        {
+            double angle = 2 * Math.PI * i / numPoints;  // 当前点的角度(弧度)
+
+            // 计算偏移量
+            double offsetLat = radiusKm / earthRadius; // 纬度的偏移量(弧度)
+            double offsetLon = offsetLat / Math.Cos(ToRadians(centerLat)); // 经度的偏移量(弧度)
+
+            // 计算该角度下的点的经纬度
+            double newLat = centerLat + ToDegrees(offsetLat * Math.Cos(angle));
+            double newLon = centerLon + ToDegrees(offsetLon * Math.Sin(angle));
+
+            // 按经度在前,纬度在后顺序存储
+            points.Add(newLon);
+            points.Add(newLat);
+        }
+
+        return points;
+    }
+
+    // 弧度转换为角度
+    static double ToDegrees(double radians)
+    {
+        return radians * 180.0 / Math.PI;
+    }
+
+    // 角度转换为弧度
+    static double ToRadians(double degrees)
+    {
+        return degrees * Math.PI / 180.0;
+    }
+
+    //private 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;
+    //}
+
+    public override void Update(double time)
+    {
+
+    }
+}
+
+
+[ObjectSystem]
+public class AircraftZSAwakeSystem : AwakeSystem<AircraftZS, FlightPlanEditor>
+{
+    public override void Awake(AircraftZS self, FlightPlanEditor flightPlanEditor)
+    {
+        self.FlightPlanEditor = flightPlanEditor;
+        self.Awake();
+        //self.Reset();
+    }
+}

+ 196 - 40
SimulationServer/Entity/Aircrafts/AircraftLandSJ.cs

@@ -1,13 +1,14 @@
 using KYFramework;
 using Model;
+using MongoDB.Bson;
 using MuShiApp;
+using SimulationCommon;
+using SimulationSingleServer.Utils;
 using Unity.Mathematics;
+using Point = SimulationCommon.Point;
 using Random = System.Random;
 using QuYuSaoMiao;
 using System.Threading;
-using SimulationCommon;
-using SimulationSingleServer.Utils;
-using Point = SimulationCommon.Point;
 
 namespace SimulationServer;
 
@@ -23,6 +24,24 @@ public class AircraftLandSJ : AircraftEntity
     public MissionEndPoint MissionEndPoint;
     public SearchMissionMode SearchMissionMode;
     public bool Success = false; //本目标搜救是否成功
+    public SearchMissionPayload searchMissionPayload;
+
+    public double resulttime;
+
+    int Days;
+    int Hour;
+
+    public bool isEndWhile;
+
+    public int targetCount;
+
+    public int sbCount;
+
+    public double landArea;
+
+    public bool isReadNC;
+
+    Text_readNC text_ReadNC;
 
     public override void Reset()
     {
@@ -32,10 +51,31 @@ public class AircraftLandSJ : AircraftEntity
         Success = false;
         SearchTime = 0;
         TotalTime = 0;
+        isEndWhile = false;
+        resulttime = 0;
+        targetCount = 0;
+        sbCount = 0;
+        landArea = 0;
     }
 
     public override void Start()
     {
+        if (FlightPlanEditor.targetpoint[0].TargetType.Type == "遇险人员")
+        {
+            targetCount = FlightPlanEditor.targetpoint[0].TargetType.Count;
+            sbCount = targetCount;
+        }
+        else
+            sbCount = 1;
+
+        landArea = SearchMissionMode.LandArea;
+
+        int Year = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[0]);
+        int Month = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]);
+        int Day = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]);
+        Hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]);
+        Days = GetDaysInYear(Year, Month, Day);
+
         Velocitys = new double[5] { 220, 220, 60, 110, 0 }; // 速度
 
 
@@ -53,7 +93,7 @@ public class AircraftLandSJ : AircraftEntity
             }
 
             var points = SeaSJ.getminEnclosingRect(trajectory);
-            var startPoint1 = new Point()
+            var startPoint1 = new Point
             {
                 lat = points[0][0] / 2 + points[1][0] / 2,
                 lon = points[0][1] / 2 + points[1][1] / 2
@@ -110,22 +150,34 @@ public class AircraftLandSJ : AircraftEntity
         FXJHGenerate.LandSouJiu(FlightPlanEditor, ref TurningPoints);
 
         FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
-        
+
         double time = 0; // 第一次 搜寻结束
         for (int i = 0; i < TurningPoints.Count - 2; i++)
         {
-            time += TurningPoints[i].SegmentFlightTime; 
+            time += TurningPoints[i].SegmentFlightTime;
         }
 
         double3 targetPoint = new double3(FlightPlanEditor.targetpoint[0].TargetPointLongitude,
             FlightPlanEditor.targetpoint[0].TargetPointLatitude,
             FlightPlanEditor.targetpoint[0].TargetPointHeight);
 
-        string cityName = helper.getCityName(targetPoint.x,targetPoint.y);
-        var visibility = 10;//helper.getVisibility(cityName, DateTime.Now.ToString("yyyy-MM-dd HH"));
-
-        getNCData = new GetNCData();
-        getNCData.GetData();
+        string cityName = helper.getCityName(targetPoint.x, targetPoint.y);
+        //var visibility = helper.getVisibility(cityName, DateTime.Now.ToString("yyyy-MM-dd HH"));
+        string year = taskContent.missionInformation.StartDate.Split("年")[0];
+        string month = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0];
+        if (Convert.ToInt32(month) < 10) month = "0" + month;
+        string day = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0];
+        if (Convert.ToInt32(day) < 10) day = "0" + day;
+        //string hour = taskContent.missionInformation.StartTime.Split("时")[0];
+        string date = year + "-" + month + "-" + day;// + " " + hour;
+        //Console.Write(date);
+        //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH"));
+        var visibility = helper.getVisibilityByDb(targetPoint.x, targetPoint.y, date); //DateTime.Now.ToString("yyyy-MM-dd HH")
+
+        //getNCData = new GetNCData();
+        //getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+        //getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+        //getNCData.GetData();
         Task.Run(() =>
         {
             bool isseePerson = false;
@@ -138,21 +190,21 @@ public class AircraftLandSJ : AircraftEntity
             //IsOver = true;
             do
             {
+
                 if (!isseePerson && temptime >= time)
                 {
                     FXJHGenerate.LandSouJiu(FlightPlanEditor, ref TurningPoints);
                     FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
-                    
+
                     time = 0;
                     for (int i = 0; i < TurningPoints.Count - 2; i++)
                     {
-                        time += TurningPoints[i].SegmentFlightTime; 
+                        time += TurningPoints[i].SegmentFlightTime;
                     }
-                    Log.Info($"+++++++++++搜寻结束 TurningPoints Count: { TurningPoints.Count } 下次结束的时间  { time }++++++++++++++++");
+                    Log.Info($"+++++++++++搜寻结束 TurningPoints Count: {TurningPoints.Count} 下次结束的时间  {time}++++++++++++++++");
                 }
 
-                var index = 0;
-                (currentLocation, _, index) =
+                (currentLocation, _) =
                     FXJHGenerate.GetAllCurrentLocation(TurningPoints, temptime); // 获取飞机当前位置
                 double3 aricraftPoint = new double3(currentLocation.CurrentLon, currentLocation.CurrentLat,
                     currentLocation.CurrentHei);
@@ -160,35 +212,54 @@ public class AircraftLandSJ : AircraftEntity
                 var distance = Utils.Util.GetDistance(currentLocation.CurrentLon, targetPoint.x,
                     currentLocation.CurrentLat,
                     targetPoint.y);
+                Log.Info("距离:====================" + distance);
+
+                if (searchMissionPayload.SearchPayload == "雷达搜索")
+                {
+                    // Pd0 = 0.5 / Pf0 = Math.Pow(10,-6) / Pf = Math.Pow(10,-6) / R0 = 23645 / sigma0 = 5000 / sigma = Editor雷达截面面积 // R 单位m 
+                    probability = helper.GetRadarPossibility(0.5, Math.Pow(10, -6), Math.Pow(10, -6), 23645, aricraftPoint, FlightPlanEditor.targetpoint[0], FlightPlanEditor.targetpoint[0].TargetType.RadarArea, 5000, visibility);
+                }
+                else if (searchMissionPayload.SearchPayload == "目视搜索")
+                {
+                    probability = helper.GetMushiLandProbability(aricraftPoint, visibility, FlightPlanEditor.targetpoint[0]);
+                }
+                else if (searchMissionPayload.SearchPayload == "光电(红外)搜索")
+                {
+                    // 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);
+                    probability = helper.GetInfraredDetectionProbability(FlightPlanEditor.targetpoint[0].TargetType.TargetBrightness, FlightPlanEditor.targetpoint[0].TargetType.TargetArea, 1, 3, 1, aricraftPoint, FlightPlanEditor.targetpoint[0], 0.075, 3, 0.8, 0073728, 0.125, 0.5, Math.Pow(10, -6));
+                }
 
-                probability =
-                    helper.GetMushiLandProbability(aricraftPoint, visibility,  FlightPlanEditor.targetpoint[0]);
+                //probability =
+                //    helper.GetMushiLandProbability(aricraftPoint, visibility, FlightPlanEditor.targetpoint[0]);
                 //finalProbability *= (1 - probability); 
 
-             
+
                 if (probability > 0.8)
                 {
                     probability -= 0.5f;
 
                     probability *= random.NextDouble();
-                    double random1 = random.NextInt64(1000,9200); // 生成随机数比较概率  调整概率使任务成功率降低 至 5%(0.05) 第一个参数越低概率越低
+                    double random1 = random.NextInt64(8000, 9200); // 生成随机数比较概率  调整概率使任务成功率降低 至 5%(0.05) 第一个参数越低概率越低 // 1000
                     random1 /= 10000;
                     probability += (0.5 * random1);
                 }
-                
-                double randomValue = random.NextInt64(9015,10000);  // 生成随机数比较概率  调整概率使任务成功率降低 至 5%(0.05) 第一个参数越高概率越低
-                 randomValue /= 10000;
-                 
-                 Log.Info(
-                     $"陆上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到遇险人员:{isseePerson}");
-                 
+
+                double randomValue = random.NextInt64(9006, 10000);  // 生成随机数比较概率  调整概率使任务成功率降低 至 5%(0.05) 第一个参数越高概率越低
+                randomValue /= 10000;
+
+                Log.Info(
+                    $"陆上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到遇险人员:{isseePerson}");
+
                 if (randomValue < probability) // 1 - finalProbability
                 {
                     isseePerson = true;
                     this.isseePerson = true;
                     fireIndex = currentLocation.Currentsegnum; // 记录当前航路点位置
-                    IsOver = true;
-                    Success = true;
+                    //IsOver = true;
+                    isEndWhile = true;
+                    //Success = true;
+                    //resulttime = get_result_time_rope(30, FlightPlanEditor.targetpoint[0].TargetType.Count, windSpeed, visibility, 0.75, 1.38).time; //调运时间
+                    //Console.WriteLine("resulttime:" + resulttime);
                 }
                 else
                 {
@@ -196,17 +267,14 @@ public class AircraftLandSJ : AircraftEntity
                 }
 
                 temptime += 10;
-                if(temptime >= double.Parse(taskContent.missionInformation.TaskEndConditions.EndValue))
+                if (temptime >= taskContent.missionInformation.TaskEndConditions.TaskTime)
                 {
-                    IsOver = true;
+                    //IsOver = true;
+                    isEndWhile = true;
                     isseePerson = false;
+                    fireIndex = currentLocation.Currentsegnum;
                 }
-            } while (!isseePerson && IsOver == false);
-
-            //Console.WriteLine(
-            //    $"海上任务1:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseePerson}");
-            Log.Info(
-                $"陆上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到遇险人员:{isseePerson}");
+            } while (!isseePerson && isEndWhile == false);
 
             //finalProbability = 1 - finalProbability; 
 
@@ -228,12 +296,100 @@ public class AircraftLandSJ : AircraftEntity
                 FXJHGenerate.FromMissionToEnd(FlightPlanEditor, MissionEndPoint, ref TurningPoints);
             }
 
+            if (isseePerson)
+            {
+                double seeTime = 0;
+                if (FlightPlanEditor.targetpoint[0].TargetType.Type == "遇险人员")
+                {
+                    if (!isReadNC)
+                    {
+                        text_ReadNC = new Text_readNC();
+                        text_ReadNC.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+                        text_ReadNC.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+                        //text_ReadNC = new Text_readNC();
+                        bool isSuccess = false;
+                        while (!isSuccess)
+                        {
+                            isSuccess = text_ReadNC.GetNCData();
+                        }
+                        isReadNC = true;
+                    }
+                    var nCread = text_ReadNC.windNCread;
+                    var wind = SeaSJ.GetWindVelocityFromAPI(nCread, currentLocation.CurrentLat, currentLocation.CurrentLon,
+                temptime, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, text_ReadNC.times1, text_ReadNC.latitudes1, text_ReadNC.longitudes1, Days, Hour);
+
+
+                    double windSpeed = Math.Sqrt(wind[0] * wind[0] + wind[1] * wind[1]);
+
+                    for (int i = 0; i < TurningPoints.Count - 1; i++)
+                    {
+                        seeTime += TurningPoints[i].SegmentFlightTime;
+                    }
+
+                    double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用
+                    double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用
+
+                    double survivalTime = FlightPlanEditor.targetpoint[0].TargetType.LiveTime;//幸存时间
+                                                                                              //  SHJParameter.person_number = Eidtor里读取   SHJParameter.windspeed Nc/Editor目标气象信息读取时间先取任务初始时间
+                    resulttime = get_result_time_rope(30, FlightPlanEditor.targetpoint[0].TargetType.Count, windSpeed, visibility, 0.75, 1.38).time; //调运时间
+                    Console.WriteLine("resulttime:" + resulttime);
+                    //Console.WriteLine("survivalTime:" + survivalTime);
+                    if (survivalTime * 3600 > seeTime)
+                    {
+                        Success = true;
+                    }
+                    //Log.Info("TotalTime:" + TotalTime);
+                    //Log.Info("幸存时间:" + survivalTime);
+                }
+            }
+
+            //Console.WriteLine(
+            //    $"海上任务1:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseePerson}");
+            Log.Info(
+                $"陆上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到遇险人员:{isseePerson}");
+
             FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
 
             End();
         });
     }
 
+    public static handling_result get_result_time_rope(double H, int person_number, double windspeed, double vis, double upspeed, double downspeed)
+    {
+
+        handling_result result = new handling_result();
+
+        if (windspeed < 8 && vis > 3)
+        {
+            result.time = (person_number * H) / downspeed + (person_number * H) / upspeed;
+            result.success = true;
+        }
+        else
+        {
+            result.success = false;
+        }
+        return result;
+    }
+
+    public static int GetDaysInYear(int year, int month, int day)
+    {
+        int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+        if (IsLeapYear(year))
+        {
+            daysInMonths[1] = 29;
+        }
+        int days = day;
+        for (int i = 0; i < month - 1; i++)
+        {
+            days += daysInMonths[i];
+        }
+        return days;
+    }
+
+    public static bool IsLeapYear(int year)
+    {
+        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
+    }
 
     public override void End()
     {
@@ -252,10 +408,10 @@ public class AircraftLandSJ : AircraftEntity
             TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间
         }
 
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel -
+                               TurningPoints[TurningPoints.Count - 1].RemainingFuel;
 
-        TotalFuelConsumption = FXJHGenerate.CalculateTotalFuelConsumption(FlightPlanEditor, TurningPoints);
-        
-        base.End();
+        IsOver = true;
     }
 }
 

+ 151 - 18
SimulationServer/Entity/Aircrafts/AircraftSHJ.cs

@@ -1,41 +1,174 @@
 using KYFramework;
 using Model;
+using MongoDB.Bson;
 
 namespace SimulationServer;
 
 public class AircraftSHJ : AircraftEntity
 {
     public SHJTask content;
-    public SHJParameter SHJParameter;
-    public BaseMission Mission;
+
+    public TaskParameter SHJParameter;
+
+    public MissionEndPoint missionEndPoint;
+
+    public bool IsOver;
+    public bool Success;
+
+    public double resulttime;
     public override void End()
     {
-        TotalFuelConsumption = FXJHGenerate.CalculateTotalFuelConsumption(FlightPlanEditor, TurningPoints);
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[^1].RemainingFuel;
+    }
 
-        base.End();
+    public override void Reset()
+    {
+        base.Reset();
+        IsOver = false;
+        Success = false;
+        TotalTime = 0;
     }
-    
+
     public override void Start()
     {
-     
-        FXJHGenerate.FromStartToMission(FlightPlanEditor,ref TurningPoints);//生成从起点到任务段起点的航路点
-        double resulttime = Cable_slippage.get_result_time_rope(SHJParameter.H, SHJParameter.person_number, SHJParameter.windspeed, SHJParameter.vis, SHJParameter.descendspeed).time;//索滑降模型输出的索滑降时间
-        FXJHGenerate.SuoHuaJiang(resulttime, FlightPlanEditor,ref TurningPoints);
-        FXJHGenerate.FromMissionToEnd(FlightPlanEditor, FXJHGenerate.SuoHuaJiangMissionEndPoint(FlightPlanEditor),ref TurningPoints);
-        
-        FXJHGenerate.InitializeVelocities(FlightPlanEditor, TurningPoints, ref Velocitys,Temperature);
-        FXJHGenerate.InitializeFuelConsumptions(FlightPlanEditor, TurningPoints,ref FuelConsumptions,Temperature);
-        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor,ref TurningPoints, Velocitys, FuelConsumptions);
-        Mission.EndMission();
+        FlightPlanEditor.missionpoint.MissionPointLatitude = missionEndPoint.MissionEndPointLatitude;
+        FlightPlanEditor.missionpoint.MissionPointLongitude = missionEndPoint.MissionEndPointLongitude;
+        FlightPlanEditor.missionpoint.MissionPointHeight = missionEndPoint.MissionEndPointHeight;
+
+        int hour = Convert.ToInt32(content.missionInformation.StartTime.Split("时")[0]);
+        //Console.WriteLine("hour:" + hour);
+        double windSpeed = Convert.ToDouble(TargetQiXiangInfoSave("风速", hour));
+        //Console.WriteLine("windSpeed:" + windSpeed);
+        double vis = Convert.ToDouble(TargetQiXiangInfoSave("能见度", hour));
+        //Console.WriteLine("vis:" + vis);
+
+        FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints);//生成从起点到任务段起点的航路点
+        resulttime = get_result_time_rope(SHJParameter.H, SHJParameter.person_number, windSpeed, vis, SHJParameter.descendspeed).time;//索滑降模型输出的索滑降时间
+        Console.WriteLine("resulttime:" + resulttime);
+        FXJHGenerate.SuoHuaJiang(resulttime, FlightPlanEditor, ref TurningPoints);
+        FXJHGenerate.FromMissionToEnd(FlightPlanEditor, FXJHGenerate.SuoHuaJiangMissionEndPoint(FlightPlanEditor), ref TurningPoints);
+        FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
+
+
+        for (int i = 0; i < TurningPoints.Count; i++) // 总飞行时间
+        {
+            TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间   //仿真轮次1 数值1
+            //Console.WriteLine("TotalTime:" + TotalTime);
+        }
+        Console.WriteLine("TotalTime:" + TotalTime);
+        IsOver = true;
+        //Success = true;
+        End();
+    }
+
+    // --接口
+    // --输入
+    // --
+    // 1)索降高度(m)
+    //--H(double)
+    // 2)索降人数
+    //--person_number(int)
+    // 3)风速(m/s)
+    // --windspeed(double)
+    // 4)能见度(m/)
+    //--vis(double)
+    // 5)索降速度(m/s)
+    // --descendspeed(double)
+    // --
+    // --输出
+    // --
+    // 1)能否索降、索降时间
+    //--result(Cable_result)
+    // --
+    //--定义Cable_result类
+
+    // 绳索滑降函数
+    public Cable_result get_result_time_rope(double H, int person_number, double windspeed, double vis, double descendspeed)
+    {
+        // descendspeed < 8 m/s
+        Cable_result result = new Cable_result();
+
+        if (windspeed < 8 && vis > 3)
+        {
+            result.time = (person_number * H) / descendspeed;
+            result.success = true;
+        }
+        else
+        {
+            result.success = false;
+        }
+        return result;
     }
+
+    public string TargetQiXiangInfoSave(string s, int hour)
+    {
+        string result = hour.ToString() + "-" + s;
+        switch (s)
+        {
+            case "温度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Temperature_19_24.ToString();
+                break;
+            case "湿度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Humidity_19_24.ToString();
+                break;
+            case "能见度":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Visibility_19_24.ToString();
+                break;
+            case "风速":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindSpeed_19_24.ToString();
+                break;
+            case "风向":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_00_08.ToString();
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_08_19.ToString();
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.WindDirection_19_24.ToString();
+                break;
+            case "天气":
+                if (hour >= 0 && hour < 8)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_00_08;
+                else if (hour >= 8 && hour < 19)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_08_19;
+                else if (hour >= 19 && hour <= 24)
+                    result = FlightPlanEditor.targetpoint[0].TargetQiXiangInfo.Weather_19_24;
+                break;
+        }
+        return result;
+    }
+}
+
+public class Cable_result
+{
+    public bool success { get; set; }
+    public double time { get; set; }
 }
 
 [ObjectSystem]
-public class AircraftSHJAwakeSystem : AwakeSystem<AircraftSHJ,FlightPlanEditor,SHJTask>
+public class AircraftSHJAwakeSystem : AwakeSystem<AircraftSHJ, FlightPlanEditor>
 {
-    public override void Awake(AircraftSHJ self,FlightPlanEditor flightPlanEditor,SHJTask shjTask)
+    public override void Awake(AircraftSHJ self, FlightPlanEditor flightPlanEditor)
     {
-        self.content = shjTask;
         self.FlightPlanEditor = flightPlanEditor;
         self.Awake();
     }

+ 240 - 66
SimulationServer/Entity/Aircrafts/AircraftSJ.cs

@@ -2,8 +2,10 @@
 using Model;
 using MongoDB.Bson;
 using MuShiApp;
+using Org.BouncyCastle.Asn1.Pkcs;
 using SimulationCommon;
 using SimulationSingleServer.Utils;
+using System.Threading;
 using Unity.Mathematics;
 using Point = SimulationCommon.Point;
 using Random = System.Random;
@@ -12,6 +14,8 @@ namespace SimulationServer;
 
 public class AircraftSJ : AircraftEntity
 {
+    public bool IsOver;
+
     private MissionEndPoint MissionEndPoint;
     private CurrentLocation currentLocation;
     private double temptime = 0;
@@ -23,8 +27,28 @@ public class AircraftSJ : AircraftEntity
     public SeaSouJiuTask taskContent;
     public bool Success = false; //本目标搜救是否成功
     public GetNCData getNCData;
-    public string startTime;
+    public double resulttime;
+    public SearchMissionPayload searchMissionPayload;
+
+    //private bool isbool;
+    //private bool isbool2;
+    //Text_readNC text_ReadNC;
+
     public SearchMissionMode SearchMode;
+    int Days;
+    int Hour;
+
+    public int targetCount;
+
+    public bool isEndWhile;
+
+    public int sbCount;
+
+    public double seaArea;
+
+    public bool isReadNC;
+
+    Text_readNC text_ReadNC;
 
     public override void Reset()
     {
@@ -34,10 +58,30 @@ public class AircraftSJ : AircraftEntity
         Success = false;
         SearchTime = 0;
         TotalTime = 0;
+        resulttime = 0;
+        isEndWhile = false;
+        targetCount = 0;
+        sbCount = 0;
+        seaArea = 0;
     }
 
     public override void Start()
     {
+        if (FlightPlanEditor.targetpoint[0].TargetType.Type == "落水人员")
+        {
+            targetCount = FlightPlanEditor.targetpoint[0].TargetType.Count;
+            sbCount = targetCount;
+        }
+        else
+            sbCount = 1;
+
+        int Year = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[0]);
+        int Month = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]);
+        int Day = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]);
+        Hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]);
+        Days = GetDaysInYear(Year, Month, Day);
+        //Console.WriteLine("Day:" + Days);
+
         Velocitys = new double[5] { 220, 220, 60, 110, 0 }; // 速度
 
         //TODO 计算 AirRoute[]
@@ -48,13 +92,50 @@ public class AircraftSJ : AircraftEntity
         double dt = 1;
         double totalTime = 24.0;
 
-        Text_readNC text_ReadNC = new Text_readNC();
-        text_ReadNC.GetNCData();
-        text_ReadNC.GetWaveHighData();
+
+        if (!isReadNC)
+        {
+            //if (!isbool2)
+            //{
+            text_ReadNC = new Text_readNC();
+            text_ReadNC.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+            text_ReadNC.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+            //text_ReadNC = new Text_readNC();
+
+            bool isSuccess = false;
+            while(!isSuccess)
+            {
+                isSuccess = text_ReadNC.GetNCData();
+            }
+
+            bool isSuccess2 = false;
+            while (!isSuccess2)
+            {
+                isSuccess2 = text_ReadNC.GetWaveHighData();
+            }
+
+            //isbool2 = true;
+            //}
+
+            getNCData = new GetNCData();
+            getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+            getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+            bool isSuccess3 = false;
+            while(!isSuccess3)
+            {
+                isSuccess3 = getNCData.GetData();
+            }
+
+            isReadNC = true;
+        }
         var nCread = text_ReadNC.windNCread;
 
         //漂移轨迹
-        List<double[]> trajectory = SeaSJ.CalculateDriftTrajectory(nCread, initialPosition, dt, totalTime);
+        List<double[]> trajectory = SeaSJ.CalculateDriftTrajectory(nCread, initialPosition, dt, totalTime, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, text_ReadNC.times1, text_ReadNC.latitudes1, text_ReadNC.longitudes1, text_ReadNC.times2, text_ReadNC.latitudes2, text_ReadNC.longitudes2, text_ReadNC.times3, text_ReadNC.latitudes3, text_ReadNC.longitudes3, Days, Hour, text_ReadNC.initlatitudes, text_ReadNC.initlongitudes);
+        //foreach ( var trajectoryItem in trajectory)
+        //{
+        //    Console.WriteLine("trajectory:" + trajectoryItem[0] + "_" + trajectoryItem[1]);
+        //}
 
         // 生成任务终点
         MissionEndPoint = new MissionEndPoint
@@ -64,17 +145,23 @@ public class AircraftSJ : AircraftEntity
             MissionEndPointHeight = 0
         };
 
-        var temp = SeaSJ.getminEnclosingRect(trajectory);
+        var temp = SeaSJ.getminEnclosingRect(trajectory); // 
+
+        seaArea = Rectangular_Area_Search_Function.min_area;
         // temp 转成 List<Point>
         List<Point> points = new List<Point>();
         foreach (var item in temp)
         {
             points.Add(new Point(item[0], item[1]));
         }
-
+        //foreach (var item in points)
+        //{
+        //    Console.WriteLine("item:" + item.lat + "-" + item.lon);
+        //}
         Point basePoint = new Point(FlightPlanEditor.originbase.BaseLatitude,
             FlightPlanEditor.originbase.BaseLongitude);
         List<Point> waypoints = new List<Point>();
+
         //*******
         if (SearchMode.SearchMode == "平行线搜索")
         {
@@ -111,31 +198,41 @@ public class AircraftSJ : AircraftEntity
                 lat = points[0].lat / 2 + points[1].lat / 2,
                 lon = points[0].lon / 2 + points[1].lon / 2
             };
+            //Console.WriteLine("startPoint1:" + startPoint1.lat + "-" + startPoint1.lon);
             var startPoint2 = new Point
             {
                 lat = points[2].lat / 2 + points[3].lat / 2,
                 lon = points[2].lon / 2 + points[3].lon / 2
             };
-
+            //Console.WriteLine("startPoint2:" + startPoint2.lat + "-" + startPoint2.lon);
             var centerPoint = new Point
             {
                 lat = startPoint1.lat / 2 + startPoint2.lat / 2,
                 lon = startPoint1.lon / 2 + startPoint2.lon / 2
             };
+            //Console.WriteLine("centerPoint:" + centerPoint.lat + "-" + centerPoint.lon);
             // 以 centerPoint 为中心,生成正方形区域
             var lonD = Math.Abs(points[0].lon - points[1].lon);
             var latD1 = Math.Abs(points[1].lat - points[2].lat);
             var max = Math.Max(lonD, latD1);
-
+            //Console.WriteLine("max:" + max);
             // 以 distance 为边长 以 centerPoint 为中心点的正方形
 
             var temp0 = new Point(centerPoint.lat + max / 2, centerPoint.lon - max / 2);
             var temp1 = new Point(centerPoint.lat + max / 2, centerPoint.lon + max / 2);
             var temp2 = new Point(centerPoint.lat - max / 2, centerPoint.lon + max / 2);
             var temp3 = new Point(centerPoint.lat - max / 2, centerPoint.lon - max / 2);
+            //Console.WriteLine("temp0:" + temp0.lat + "-" + temp0.lon);
+            //Console.WriteLine("temp1:" + temp1.lat + "-" + temp1.lon);
+            //Console.WriteLine("temp2:" + temp2.lat + "-" + temp2.lon);
+            //Console.WriteLine("temp3:" + temp3.lat + "-" + temp3.lon);
+            //Console.WriteLine("SearchWidth:" + SearchMode.SearchWidth);
             waypoints = TZFX.GenerateWaypoints(temp0, temp1, temp2, temp3, max, SearchMode.SearchWidth);
         }
-
+        //foreach (var item in waypoints)
+        //{
+        //    Console.WriteLine("item.lat :" + item.lat + "-" + "item.lon:" + item.lon);
+        //}
         // List<Point> 转成 List<AirRoute>
         List<AirRoute> airRoutes = new List<AirRoute>();
         foreach (var item in waypoints)
@@ -156,11 +253,13 @@ public class AircraftSJ : AircraftEntity
         FlightPlanEditor.missionpoint = missionPoint;
 
         FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints); //生成从起点到任务段起点的航路点
-
         FXJHGenerate.SeaSouJiu(FlightPlanEditor, ref TurningPoints);
-
         FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
 
+        //foreach (var item in TurningPoints)
+        //{
+        //    Console.WriteLine("TurningPointLatitude:" + item.TurningPointLatitude + "_" + "TurningPointLongitude:" + item.TurningPointLongitude);
+        //}
 
         double time = 0; // 第一次 搜寻结束
         for (int i = 0; i < TurningPoints.Count - 2; i++)
@@ -173,20 +272,37 @@ public class AircraftSJ : AircraftEntity
             FlightPlanEditor.targetpoint[0].TargetPointHeight);
 
         string cityName = helper.getCityName(targetPoint.x, targetPoint.y);
-        var vis = 10; //helper.getVisibility(cityName, DateTime.Now.ToString("yyyy-MM-dd HH"));
+        //var vis = helper.getVisibility(cityName, DateTime.Now.ToString("yyyy-MM-dd HH"));
+        string year = taskContent.missionInformation.StartDate.Split("年")[0];
+        string month = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0];
+        if (Convert.ToInt32(month) < 10) month = "0" + month;
+        string day = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0];
+        if (Convert.ToInt32(day) < 10) day = "0" + day;
+        //string hour = taskContent.missionInformation.StartTime.Split("时")[0];
+        string date = year + "-" + month + "-" + day;// + " " + hour;
+        //Console.Write(date);
+        //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH"));
+        var vis = helper.getVisibilityByDb(targetPoint.x, targetPoint.y, date); //DateTime.Now.ToString("yyyy-MM-dd HH")
+
+        //if (!isbool)
+        //{
+        //getNCData = new GetNCData();
+        //getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude;
+        //getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude;
+        //getNCData.GetData();
+        //isbool = true;
+        //}
 
-        getNCData = new GetNCData();
-        getNCData.GetData();
         Task.Run(() =>
         {
-            bool isseePerson = false;
+            bool isseePerson = false; // 输出表格平均救助时间没看到人是0看到人调用下面get_result_time_rope方法 //人员存活率需要重新算读取Editor搜救目标点初始坐标人数 //任务准备时间取值所有任务最小
             double temptime = 0; // 自增时间,每次增加1s
             CurrentLocation currentLocation = new CurrentLocation();
             double probability = 0;
             double finalProbability = 1.0;
             Random random = new Random();
             int fireIndex = -1; // 记录发现火点的位置
-
+            double windSpeed = 0;
             do
             {
                 if (!isseePerson && temptime >= time)
@@ -202,8 +318,8 @@ public class AircraftSJ : AircraftEntity
                     Log.Info($"+++++++++++搜寻结束 TurningPoints Count: {TurningPoints.Count} 下次结束的时间  {time}++++++++++++++++");
                 }
 
-                var index = 0;
-                (currentLocation, _, index) =
+
+                (currentLocation, _) =
                     FXJHGenerate.GetAllCurrentLocation(TurningPoints, temptime); // 获取飞机当前位置
                 double3 aricraftPoint = new double3(currentLocation.CurrentLon, currentLocation.CurrentLat,
                     currentLocation.CurrentHei);
@@ -214,20 +330,35 @@ public class AircraftSJ : AircraftEntity
 
 
                 var wind = SeaSJ.GetWindVelocityFromAPI(nCread, currentLocation.CurrentLat, currentLocation.CurrentLon,
-                    temptime);
+                    temptime, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, text_ReadNC.times1, text_ReadNC.latitudes1, text_ReadNC.longitudes1, Days, Hour);
 
 
-                var windSpeed = Math.Sqrt(wind[0] * wind[0] + wind[1] * wind[1]);
+                windSpeed = Math.Sqrt(wind[0] * wind[0] + wind[1] * wind[1]);
 
                 var waveHigh = SeaSJ.GetWaveHeightFromAPI(nCread, currentLocation.CurrentLon,
-                    currentLocation.CurrentLat, temptime);
+                    currentLocation.CurrentLat, temptime, text_ReadNC.times4, text_ReadNC.latitudes4, text_ReadNC.longitudes4, Days, Hour);
 
                 var distance = Utils.Util.GetDistance(currentLocation.CurrentLon, targetPoint.x,
                     currentLocation.CurrentLat,
                     targetPoint.y);
+                //Console.WriteLine("targetPoint:" + targetPoint.x + "-" + targetPoint.y + "-" + targetPoint.z);
                 Log.Info("距离:====================" + distance);
-                probability =
-                    helper.GetMushiSeaProbability(aricraftPoint, vis, waveHigh, FlightPlanEditor.targetpoint[0]);
+
+                //Console.WriteLine("searchMissionPayload.SearchPayload:" + searchMissionPayload.SearchPayload);
+                if (searchMissionPayload.SearchPayload == "雷达搜索")
+                {
+                    // Pd0 = 0.5 / Pf0 = Math.Pow(10,-6) / Pf = Math.Pow(10,-6) / R0 = 23645 / sigma0 = 5000 / sigma = Editor雷达截面面积 // R 单位m 
+                    probability = helper.GetRadarPossibility(0.5, Math.Pow(10, -6), Math.Pow(10, -6), 23645, aricraftPoint, FlightPlanEditor.targetpoint[0], FlightPlanEditor.targetpoint[0].TargetType.RadarArea, 5000, vis);
+                }
+                else if (searchMissionPayload.SearchPayload == "目视搜索")
+                {
+                    probability = helper.GetMushiSeaProbability(aricraftPoint, vis, waveHigh, FlightPlanEditor.targetpoint[0]);
+                }
+                else if (searchMissionPayload.SearchPayload == "光电(红外)搜索")
+                {
+                    // 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);
+                    probability = helper.GetInfraredDetectionProbability(FlightPlanEditor.targetpoint[0].TargetType.TargetBrightness, FlightPlanEditor.targetpoint[0].TargetType.TargetArea, 1, 3, 1, aricraftPoint, FlightPlanEditor.targetpoint[0], 0.075, 3, 0.8, 0073728, 0.125, 0.5, Math.Pow(10, -6));
+                }
 
                 // probability = helper.getProbability(aricraftPoint, targetPoint,pb, currentLocation.CurrentCourse,
                 //     windSpeed, waveHigh, "落水人员", "海上"); // 计算发现概率,需要其他模型输入 // 计算发现概率,需要其他模型输入
@@ -236,59 +367,32 @@ public class AircraftSJ : AircraftEntity
 
                 // 到搜寻航路点的最后一个点 (?)
                 Log.Info(
-                    $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到落水人员:{isseePerson}");
-                double randomValue = random.NextInt64(9015 , 10000); // 生成随机数比较概率 //0.03 第一个参数越高概率越低 8985 0.212 100 9000 0 100 8995 0.14 100 8997 0.25 20 8998 0.3 20
+                    $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到目标:{isseePerson}");
+                double randomValue = random.NextInt64(9006, 10000); // 生成随机数比较概率 //0.05 第一个参数越高概率越低 / 8985 0.212 100 / 9000 0.16 100 / 8995 0.14 100 / 8997 0.12 100 / 8999  0.18 100 / 9006 0.11 100 / 9010 0.12 100 / 9030 0.03 100 / 9026 0.07 0.04 100 / 9028 0.03 100 / 9027 0.04 100 / 9025 0.05 100 /
+                //9025 0.02 100 / 9015 0.02 100 / 9020 0.04 100 / 9022 0.05 100 / 9022 0.04 100 / 9022 0 100 /9018 0.01 100 / 9021 0.01 100 / 9023 0.03 100 / 9000 0.08 100 / 9006
                 randomValue /= 10000;
+                //randomValue = 0.8;
                 if (randomValue < probability) //  1 - finalProbability
                 {
                     isseePerson = true;
                     this.isseePerson = true;
                     fireIndex = currentLocation.Currentsegnum; // 记录当前航路点位置
-                    IsOver = true;
+                    //IsOver = true;
+                    isEndWhile = true;
                 }
                 else
                 {
                     isseePerson = false;
                 }
-                if (temptime >= double.Parse( taskContent.missionInformation.TaskEndConditions.EndValue))
+                if (temptime >= taskContent.missionInformation.TaskEndConditions.TaskTime)
                 {
-                    IsOver = true;
+                    //IsOver = true;
+                    isEndWhile = true;
                     isseePerson = false;
+                    fireIndex = currentLocation.Currentsegnum;
                 }
                 temptime += 10;
-            } while (!isseePerson && IsOver == false);
-            if (isseePerson)
-            {
-
-                for (int i = 0; i < TurningPoints.Count - 1; i++)
-                {
-                    TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间
-                }
-
-                double time = TotalTime; //time——搜索时间,单位:秒;数据测试用
-
-                double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用
-                double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用
-
-                double survivalTime = SurvivalTimeModel.SurvivalTime(getNCData.tempreadNC, latitude, longitude, time); //幸存时间
-
-                if (survivalTime * 3600 > time)
-                {
-                    Success = true;
-                }
-                else
-                {
-                    Success = false;
-                }
-                Log.Info("TotalTime:" + TotalTime);
-                Log.Info("幸存时间:" + survivalTime);
-            }
-
-
-            //Console.WriteLine(
-            //    $"海上任务1:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseePerson}");
-            Log.Info(
-                $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到落水人员:{isseePerson},人员是否幸存:{Success}");
+            } while (!isseePerson && !isEndWhile); //IsOver == false
 
             //finalProbability = 1 - finalProbability;
 
@@ -310,12 +414,83 @@ public class AircraftSJ : AircraftEntity
                 FXJHGenerate.FromMissionToEnd(FlightPlanEditor, MissionEndPoint, ref TurningPoints);
             }
 
+            if (isseePerson)
+            {
+                double seeTime = 0;
+                if (FlightPlanEditor.targetpoint[0].TargetType.Type == "落水人员")
+                {
+                    for (int i = 0; i < TurningPoints.Count - 1; i++)
+                    {
+                        seeTime += TurningPoints[i].SegmentFlightTime;
+                    }
+
+                    //time = TotalTime; //time——搜索时间,单位:秒;数据测试用
+
+                    double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用
+                    double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用
+
+                    double survivalTime = SurvivalTimeModel.SurvivalTime(getNCData.tempreadNC, latitude, longitude, time, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, Days, Hour); //幸存时间
+                                                                                                                                                                                                         //  SHJParameter.person_number = Eidtor里读取   SHJParameter.windspeed Nc/Editor目标气象信息读取时间先取任务初始时间
+                    resulttime = get_result_time_rope(30, FlightPlanEditor.targetpoint[0].TargetType.Count, windSpeed, vis, 0.75, 1.38).time; //调运时间
+                    Console.WriteLine("resulttime:" + resulttime);
+                    if (survivalTime * 3600 > seeTime)
+                    {
+                        Success = true;
+                    }
+                    //Log.Info("TotalTime:" + TotalTime);
+                    //Log.Info("幸存时间:" + survivalTime);
+                }
+            }
+
+            //Console.WriteLine(
+            //    $"海上任务1:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseePerson}");
+            Log.Info(
+                $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到目标:{isseePerson},人员是否幸存:{Success}");
+
             FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
 
             End();
         });
     }
 
+    public static handling_result get_result_time_rope(double H, int person_number, double windspeed, double vis, double upspeed, double downspeed)
+    {
+
+        handling_result result = new handling_result();
+
+        if (windspeed < 8 && vis > 3)
+        {
+            result.time = (person_number * H) / downspeed + (person_number * H) / upspeed;
+            result.success = true;
+        }
+        else
+        {
+            result.success = false;
+        }
+        return result;
+    }
+
+
+    public static int GetDaysInYear(int year, int month, int day)
+    {
+        int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+        if (IsLeapYear(year))
+        {
+            daysInMonths[1] = 29;
+        }
+        int days = day;
+        for (int i = 0; i < month - 1; i++)
+        {
+            days += daysInMonths[i];
+        }
+        return days;
+    }
+
+    public static bool IsLeapYear(int year)
+    {
+        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
+    }
+
 
     public override void End()
     {
@@ -334,15 +509,14 @@ public class AircraftSJ : AircraftEntity
             TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间
         }
 
-
-        TotalFuelConsumption = FXJHGenerate.CalculateTotalFuelConsumption(FlightPlanEditor, TurningPoints);
+        TotalFuelConsumption = TurningPoints[0].RemainingFuel -
+                               TurningPoints[TurningPoints.Count - 1].RemainingFuel;
 
 
         //GetNCData getNCData = new GetNCData();
         ////getNCData.GetData();
-        
-        base.End();
 
+        IsOver = true;
     }
 }
 

+ 187 - 0
SimulationServer/Entity/JJJYMission.cs

@@ -0,0 +1,187 @@
+using KYFramework;
+using NPOI.SS.Formula.PTG;
+using SimulationServer.Utils;
+
+namespace SimulationServer;
+
+public class JJJYMission : Entity
+{
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftJJ> aircrafts = new List<AircraftJJ>();
+
+    public bool IsRunning;
+    public double SimulationTime;
+
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+
+    public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
+
+    public bool IsOver = false;
+
+    private int currentExecuteCount = 1;
+    public int ExecutionContext = 0;
+
+    public string date;
+    public void Start()
+    {
+        IsRunning = true;
+        aircrafts.ForEach(a => a.Start());
+        Log.Info($"{MissionId} 任务开始!");
+    }
+
+    public void Reset()
+    {
+        SimulationTime = 0;
+        aircrafts?.ForEach(a => a.Reset());
+    }
+
+    public void EndMission()
+    {
+        IsRunning = false;
+        Log.Info($"{MissionId} 任务结束!");
+
+        if (currentExecuteCount > ExecutionContext)
+        {
+            return;
+        }
+
+        if (currentExecuteCount < ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+        }
+
+        if (currentExecuteCount == ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+            ReportSJ();
+            IsOver = true;
+            return;
+        }
+
+        this.Reset();
+        this.Start();
+        currentExecuteCount++;
+    }
+
+    public void SaveAircraftSJDatas()
+    {
+        foreach (AircraftJJ aircraftEntity in aircrafts)
+        {
+            string key = aircraftEntity.AircraftId;
+            if (!aircraftSJDatas.ContainsKey(key))
+            {
+                aircraftSJDatas[key] = new Dictionary<string, List<string>>();
+            }
+            if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
+                aircraftSJDatas[key]["识别成功率"] = new List<string>();
+            aircraftSJDatas[key]["识别成功率"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
+                aircraftSJDatas[key]["任务准备时间"] = new List<string>();
+            aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
+                aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
+            aircraftSJDatas[key]["平均搜索时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
+                aircraftSJDatas[key]["总飞行时间"] = new List<string>();
+            aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
+                aircraftSJDatas[key]["人员存活率"] = new List<string>();
+            aircraftSJDatas[key]["人员存活率"].Add("0");
+        }
+    }
+
+    public void SaveSJ()
+    {
+        foreach (AircraftJJ aircraftEntity in aircrafts)
+        {
+            var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
+
+            if (staticCapacity == null) continue;
+
+            staticCapacity.FillData5(aircraftEntity.Db);
+
+            string key = aircraftEntity.AircraftId;
+
+            if (!singleReport.ContainsKey(key))
+            {
+                singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
+            }
+
+            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport5();
+            foreach (var kv in staticReport)
+            {
+                if (!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
+                foreach (var kv2 in kv.Value)
+                {
+                    if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
+                    singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
+                }
+            }
+        }
+        if (currentExecuteCount == ExecutionContext)
+        {
+            foreach (var kv in singleReport)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    foreach (var kv3 in kv2.Value)
+                    {
+                        var sum = 0f;
+                        foreach (var kv4 in kv3.Value)
+                        {
+                            bool isfloat = float.TryParse(kv4, out float f);
+                            if (isfloat)
+                                sum += float.Parse(kv4);
+                            else
+                                sum = -1f;
+                        }
+                        if (sum != -1f)
+                            kv3.Value.Add((sum / kv3.Value.Count).ToString());
+                        else
+                            kv3.Value.Add("");
+                    }
+                }
+            }
+        }
+    }
+
+    public void ReportSJ()
+    {
+        string path = $"Reports/{date}/{MissionId}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        foreach (var kv in singleReport)
+        {
+            string filePath = $"{path}/{kv.Key}搜救任务单机指标报告.xls";
+            DataTableExtensions.SaveToExcel(filePath, kv.Value, true);
+        }
+    }
+}
+
+
+[ObjectSystem]
+public class JJJYMissionUpdateSystem : UpdateSystem<JJJYMission>
+{
+    public override void Update(JJJYMission self)
+    {
+        if (!self.IsRunning) return;
+
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
+
+        if (self.aircrafts.All(a => a.IsOver))
+        {
+            self.EndMission();
+        }
+    }
+}

+ 189 - 0
SimulationServer/Entity/KTKSMission.cs

@@ -0,0 +1,189 @@
+using KYFramework;
+using NPOI.SS.Formula.PTG;
+using SimulationServer.Utils;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+namespace SimulationServer;
+
+public class KTKSMission : Entity
+{
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftKTKS> aircrafts = new List<AircraftKTKS>();
+
+    public bool IsRunning;
+    public double SimulationTime;
+
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+
+    public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
+
+    public bool IsOver = false;
+
+    private int currentExecuteCount = 1;
+    public int ExecutionContext = 0;
+
+    public string date;
+    public void Start()
+    {
+        IsRunning = true;
+        aircrafts.ForEach(a => a.Start());
+        Log.Info($"{MissionId} 任务开始!");
+    }
+
+    public void Reset()
+    {
+        SimulationTime = 0;
+        aircrafts?.ForEach(a => a.Reset());
+    }
+
+    public void EndMission()
+    {
+        IsRunning = false;
+        Log.Info($"{MissionId} 任务结束!");
+
+        if (currentExecuteCount > ExecutionContext)
+        {
+            return;
+        }
+
+        if (currentExecuteCount < ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+        }
+
+        if (currentExecuteCount == ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+            ReportSJ();
+            IsOver = true;
+            return;
+        }
+
+        this.Reset();
+        this.Start();
+        currentExecuteCount++;
+    }
+
+    public void SaveAircraftSJDatas()
+    {
+        foreach (AircraftKTKS aircraftEntity in aircrafts)
+        {
+            string key = aircraftEntity.AircraftId;
+            if (!aircraftSJDatas.ContainsKey(key))
+            {
+                aircraftSJDatas[key] = new Dictionary<string, List<string>>();
+            }
+            if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
+                aircraftSJDatas[key]["识别成功率"] = new List<string>();
+            aircraftSJDatas[key]["识别成功率"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
+                aircraftSJDatas[key]["任务准备时间"] = new List<string>();
+            aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
+                aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
+            aircraftSJDatas[key]["平均搜索时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
+                aircraftSJDatas[key]["总飞行时间"] = new List<string>();
+            aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
+                aircraftSJDatas[key]["人员存活率"] = new List<string>();
+            aircraftSJDatas[key]["人员存活率"].Add("0");
+        }
+    }
+
+    public void SaveSJ()
+    {
+        foreach (AircraftKTKS aircraftEntity in aircrafts)
+        {
+            var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
+
+            if (staticCapacity == null) continue;
+
+            staticCapacity.FillData3(aircraftEntity.Db);
+
+            string key = aircraftEntity.AircraftId;
+
+            if (!singleReport.ContainsKey(key))
+            {
+                singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
+            }
+
+            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport3();
+            foreach (var kv in staticReport)
+            {
+                if (!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
+                foreach (var kv2 in kv.Value)
+                {
+                    if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
+                    singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
+                }
+            }
+        }
+        if (currentExecuteCount == ExecutionContext)
+        {
+            foreach (var kv in singleReport)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    foreach (var kv3 in kv2.Value)
+                    {
+                        var sum = 0f;
+                        foreach (var kv4 in kv3.Value)
+                        {
+                            bool isfloat = float.TryParse(kv4, out float f);
+                            if (isfloat)
+                                sum += float.Parse(kv4);
+                            else
+                                sum = -1f;
+                        }
+                        if (sum != -1f)
+                            kv3.Value.Add((sum / kv3.Value.Count).ToString());
+                        else
+                            kv3.Value.Add("");
+                    }
+                }
+            }
+        }
+    }
+
+    public void ReportSJ()
+    {
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}/{MissionId}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        foreach (var kv in singleReport)
+        {
+            string filePath = $"{path}/{kv.Key}搜救任务单机指标报告.xls";
+            DataTableExtensions.SaveToExcel(filePath, kv.Value, true);
+        }
+    }
+}
+
+
+[ObjectSystem]
+public class KTKSMissionUpdateSystem : UpdateSystem<KTKSMission>
+{
+    public override void Update(KTKSMission self)
+    {
+        if (!self.IsRunning) return;
+
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
+
+        if (self.aircrafts.All(a => a.IsOver))
+        {
+            self.EndMission();
+        }
+    }
+}

+ 190 - 0
SimulationServer/Entity/KZDYMission.cs

@@ -0,0 +1,190 @@
+using KYFramework;
+using NPOI.SS.Formula.PTG;
+using SimulationServer.Utils;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+namespace SimulationServer;
+
+public class KZDYMission : Entity
+{
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftDY> aircrafts = new List<AircraftDY>();
+
+    public bool IsRunning;
+    public double SimulationTime;
+
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+
+    public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
+
+    public bool IsOver = false;
+
+    private int currentExecuteCount = 1;
+    public int ExecutionContext = 0;
+
+    public string date;
+
+    public void Start()
+    {
+        IsRunning = true;
+        aircrafts.ForEach(a => a.Start());
+        Log.Info($"{MissionId} 任务开始!");
+    }
+
+    public void Reset()
+    {
+        SimulationTime = 0;
+        aircrafts?.ForEach(a => a.Reset());
+    }
+
+    public void EndMission()
+    {
+        IsRunning = false;
+        Log.Info($"{MissionId} 任务结束!");
+
+        if (currentExecuteCount > ExecutionContext)
+        {
+            return;
+        }
+
+        if (currentExecuteCount < ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+        }
+
+        if (currentExecuteCount == ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+            ReportSJ();
+            IsOver = true;
+            return;
+        }
+
+        this.Reset();
+        this.Start();
+        currentExecuteCount++;
+    }
+
+    public void SaveAircraftSJDatas()
+    {
+        foreach (AircraftDY aircraftEntity in aircrafts)
+        {
+            string key = aircraftEntity.AircraftId;
+            if (!aircraftSJDatas.ContainsKey(key))
+            {
+                aircraftSJDatas[key] = new Dictionary<string, List<string>>();
+            }
+            if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
+                aircraftSJDatas[key]["识别成功率"] = new List<string>();
+            aircraftSJDatas[key]["识别成功率"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add(aircraftEntity.targetCount.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
+                aircraftSJDatas[key]["任务准备时间"] = new List<string>();
+            aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
+                aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
+            aircraftSJDatas[key]["平均搜索时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add(aircraftEntity.resulttime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
+                aircraftSJDatas[key]["总飞行时间"] = new List<string>();
+            aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
+                aircraftSJDatas[key]["人员存活率"] = new List<string>();
+            aircraftSJDatas[key]["人员存活率"].Add(aircraftEntity.Success ? aircraftEntity.targetCount.ToString() : "0");
+        }
+    }
+
+    public void SaveSJ()
+    {
+        foreach (AircraftDY aircraftEntity in aircrafts)
+        {
+            var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
+
+            if (staticCapacity == null) continue;
+
+            staticCapacity.FillData2(aircraftEntity.Db);
+
+            string key = aircraftEntity.AircraftId;
+
+            if (!singleReport.ContainsKey(key))
+            {
+                singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
+            }
+
+            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport2();
+            foreach (var kv in staticReport)
+            {
+                if (!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
+                foreach (var kv2 in kv.Value)
+                {
+                    if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
+                    singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
+                }
+            }
+        }
+        if (currentExecuteCount == ExecutionContext)
+        {
+            foreach (var kv in singleReport)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    foreach (var kv3 in kv2.Value)
+                    {
+                        var sum = 0f;
+                        foreach (var kv4 in kv3.Value)
+                        {
+                            bool isfloat = float.TryParse(kv4, out float f);
+                            if (isfloat)
+                                sum += float.Parse(kv4);
+                            else
+                                sum = -1f;
+                        }
+                        if (sum != -1f)
+                            kv3.Value.Add((sum / kv3.Value.Count).ToString());
+                        else
+                            kv3.Value.Add("");
+                    }
+                }
+            }
+        }
+    }
+
+    public void ReportSJ()
+    {
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}/{MissionId}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        foreach (var kv in singleReport)
+        {
+            string filePath = $"{path}/{kv.Key}搜救任务单机指标报告.xls";
+            DataTableExtensions.SaveToExcel(filePath, kv.Value, true);
+        }
+    }
+}
+
+
+[ObjectSystem]
+public class KZDYMissionUpdateSystem : UpdateSystem<KZDYMission>
+{
+    public override void Update(KZDYMission self)
+    {
+        if (!self.IsRunning) return;
+
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
+
+        if (self.aircrafts.All(a => a.IsOver))
+        {
+            self.EndMission();
+        }
+    }
+}

+ 37 - 25
SimulationServer/Entity/Missions/LandSJRescueMission.cs

@@ -4,10 +4,19 @@ using SimulationServer.Utils;
 
 namespace SimulationServer;
 
-public class LandSJRescueMission : BaseMission
+public class LandSJRescueMission : Entity
 {
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftLandSJ> aircrafts = new List<AircraftLandSJ>();
+
+    public bool IsRunning;
     public double SimulationTime;
 
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+    // 灭火的 整体能力
+    // <sheet,<指标名,值列表>>
+    public Dictionary<string, Dictionary<string, List<string>>> totalReport = new();
 
     public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
 
@@ -15,20 +24,22 @@ public class LandSJRescueMission : BaseMission
 
     private int currentExecuteCount = 1;
     public int ExecutionContext = 0;
-    public override void Start()
+
+    public string date;
+    public void Start()
     {
         IsRunning = true;
-        Aircrafts.ForEach(a => a.Start());
+        aircrafts.ForEach(a => a.Start());
         Log.Info($"{MissionId} 任务开始!");
     }
 
-    public override void Reset()
+    public void Reset()
     {
         SimulationTime = 0;
-        Aircrafts?.ForEach(a => a.Reset());
+        aircrafts?.ForEach(a => a.Reset());
     }
 
-    public override void EndMission()
+    public void EndMission()
     {
         IsRunning = false;
         Log.Info($"{MissionId} 任务结束!");
@@ -72,9 +83,8 @@ public class LandSJRescueMission : BaseMission
 
     public void SaveAircraftSJDatas()
     {
-        foreach (AircraftEntity aircraftEntity in Aircrafts )
+        foreach (AircraftLandSJ aircraftEntity in aircrafts)
         {
-            var aircraftSJ = aircraftEntity as AircraftLandSJ;
             string key = aircraftEntity.AircraftId;
             if (!aircraftSJDatas.ContainsKey(key))
             {
@@ -82,25 +92,37 @@ public class LandSJRescueMission : BaseMission
             }
             if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
                 aircraftSJDatas[key]["识别成功率"] = new List<string>();
-            aircraftSJDatas[key]["识别成功率"].Add(aircraftSJ.isseePerson ? "1" : "0");
+            aircraftSJDatas[key]["识别成功率"].Add(aircraftEntity.isseePerson ? aircraftEntity.sbCount.ToString() : "0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add(aircraftEntity.sbCount.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add(aircraftEntity.targetCount.ToString());
             if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
                 aircraftSJDatas[key]["任务准备时间"] = new List<string>();
             aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
             if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
                 aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
             aircraftSJDatas[key]["平均搜索时间"].Add(aircraftEntity.SearchTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add(aircraftEntity.resulttime.ToString());
             if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
                 aircraftSJDatas[key]["总飞行时间"] = new List<string>();
             aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString());
             if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
                 aircraftSJDatas[key]["人员存活率"] = new List<string>();
-            aircraftSJDatas[key]["人员存活率"].Add(aircraftEntity.Success ? "1" : "0");
+            aircraftSJDatas[key]["人员存活率"].Add(aircraftEntity.Success ? aircraftEntity.targetCount.ToString() : "0");
+            if (!aircraftSJDatas[key].ContainsKey("环境搜索覆盖面积"))
+                aircraftSJDatas[key]["环境搜索覆盖面积"] = new List<string>();
+            aircraftSJDatas[key]["环境搜索覆盖面积"].Add(aircraftEntity.landArea.ToString());
         }
     }
 
     public void SaveSJ()
     {
-        foreach (AircraftEntity aircraftEntity in Aircrafts)
+        foreach (AircraftLandSJ aircraftEntity in aircrafts)
         {
             var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
 
@@ -172,8 +194,8 @@ public class LandSJRescueMission : BaseMission
 
     public void ReportSJ()
     {
-        string data = DateTime.Now.ToString("yyyy-MM-dd");
-        string path = $"Reports/LSX/{data}/{MissionId}";
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}/{MissionId}";
         if (!Directory.Exists(path)) Directory.CreateDirectory(path);
         foreach (var kv in singleReport)
         {
@@ -201,8 +223,6 @@ public class LandSJRescueMission : BaseMission
         //string totalPath = $"{path}/{"搜救任务总体指标报告"}.xls";
         //DataTableExtensions.SaveToExcel(totalPath, totalReport, true);
     }
-
-   
 }
 
 
@@ -213,17 +233,9 @@ public class LandSJRescueMissionUpdateSystem : UpdateSystem<LandSJRescueMission>
     {
         if (!self.IsRunning) return;
 
-        self.Aircrafts?.ForEach(a => a.Update(self.SimulationTime));
-
-
-        bool isOver = true;
-        foreach (var aircraft in self.Aircrafts)
-        {
-            if((aircraft as AircraftLandSJ).IsOver == false)
-                isOver = false;
-        }
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
 
-        if (isOver)
+        if (self.aircrafts.All(a => a.IsOver))
         {
             self.EndMission();
         }

+ 38 - 21
SimulationServer/Entity/Missions/SeaSJRescueMission.cs

@@ -4,30 +4,42 @@ using SimulationServer.Utils;
 
 namespace SimulationServer;
 
-public class SeaSJRescueMission : BaseMission
+public class SeaSJRescueMission : Entity
 {
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftSJ> aircrafts = new List<AircraftSJ>();
+
+    public bool IsRunning;
     public double SimulationTime;
 
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+    // 灭火的 整体能力
+    // <sheet,<指标名,值列表>>
+    public Dictionary<string, Dictionary<string, List<string>>> totalReport = new();
+
     public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
 
     public bool IsOver = false;
 
     private int currentExecuteCount = 1;
     public int ExecutionContext = 0;
-    public override void Start()
+
+    public string date;
+    public void Start()
     {
         IsRunning = true;
-        Aircrafts.ForEach(a => a.Start());
+        aircrafts.ForEach(a => a.Start());
         Log.Info($"{MissionId} 任务开始!");
     }
 
-    public override void Reset()
+    public void Reset()
     {
         SimulationTime = 0;
-        Aircrafts?.ForEach(a => a.Reset());
+        aircrafts?.ForEach(a => a.Reset());
     }
 
-    public override void EndMission()
+    public void EndMission()
     {
         IsRunning = false;
         Log.Info($"{MissionId} 任务结束!");
@@ -71,7 +83,7 @@ public class SeaSJRescueMission : BaseMission
 
     public void SaveAircraftSJDatas()
     {
-        foreach (AircraftSJ aircraftEntity in Aircrafts)
+        foreach (AircraftSJ aircraftEntity in aircrafts)
         {
             string key = aircraftEntity.AircraftId;
             if (!aircraftSJDatas.ContainsKey(key))
@@ -80,25 +92,37 @@ public class SeaSJRescueMission : BaseMission
             }
             if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
                 aircraftSJDatas[key]["识别成功率"] = new List<string>();
-            aircraftSJDatas[key]["识别成功率"].Add(aircraftEntity.isseePerson ? "1" : "0");
+            aircraftSJDatas[key]["识别成功率"].Add(aircraftEntity.isseePerson ? aircraftEntity.sbCount.ToString() : "0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add(aircraftEntity.sbCount.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add(aircraftEntity.targetCount.ToString());
             if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
                 aircraftSJDatas[key]["任务准备时间"] = new List<string>();
             aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
             if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
                 aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
             aircraftSJDatas[key]["平均搜索时间"].Add(aircraftEntity.SearchTime.ToString("f4"));
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add(aircraftEntity.resulttime.ToString());
             if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
                 aircraftSJDatas[key]["总飞行时间"] = new List<string>();
             aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString("f4"));
             if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
                 aircraftSJDatas[key]["人员存活率"] = new List<string>();
-            aircraftSJDatas[key]["人员存活率"].Add(aircraftEntity.Success ? "1" : "0");
+            aircraftSJDatas[key]["人员存活率"].Add(aircraftEntity.Success ? aircraftEntity.targetCount.ToString() : "0");
+            if (!aircraftSJDatas[key].ContainsKey("海上搜索覆盖面积"))
+                aircraftSJDatas[key]["海上搜索覆盖面积"] = new List<string>();
+            aircraftSJDatas[key]["海上搜索覆盖面积"].Add(aircraftEntity.seaArea.ToString());
         }
     }
 
     public void SaveSJ()
     {
-        foreach (AircraftSJ aircraftEntity in Aircrafts)
+        foreach (AircraftSJ aircraftEntity in aircrafts)
         {
             var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
 
@@ -170,8 +194,8 @@ public class SeaSJRescueMission : BaseMission
 
     public void ReportSJ()
     {
-        string data = DateTime.Now.ToString("yyyy-MM-dd");
-        string path = $"Reports/SSJ/{data}/{MissionId}";
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}/{MissionId}";
         if (!Directory.Exists(path)) Directory.CreateDirectory(path);
         foreach (var kv in singleReport)
         {
@@ -209,16 +233,9 @@ public class SeaSJRescueMissionUpdateSystem : UpdateSystem<SeaSJRescueMission>
     {
         if (!self.IsRunning) return;
 
-        self.Aircrafts?.ForEach(a => a.Update(self.SimulationTime));
-
-        bool isOver = true;
-        foreach (var aircraft in self.Aircrafts)
-        {
-            if((aircraft as AircraftSJ).IsOver == false)
-                isOver = false;
-        }
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
 
-        if (isOver)
+        if (self.aircrafts.All(a => a.IsOver))
         {
             self.EndMission();
         }

+ 187 - 0
SimulationServer/Entity/SHJMission.cs

@@ -0,0 +1,187 @@
+using KYFramework;
+using NPOI.SS.Formula.PTG;
+using SimulationServer.Utils;
+
+namespace SimulationServer;
+
+public class SHJMission : Entity
+{
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftSHJ> aircrafts = new List<AircraftSHJ>();
+
+    public bool IsRunning;
+    public double SimulationTime;
+
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+
+    public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
+
+    public bool IsOver = false;
+
+    private int currentExecuteCount = 1;
+    public int ExecutionContext = 0;
+
+    public string date;
+    public void Start()
+    {
+        IsRunning = true;
+        aircrafts.ForEach(a => a.Start());
+        Log.Info($"{MissionId} 任务开始!");
+    }
+
+    public void Reset()
+    {
+        SimulationTime = 0;
+        aircrafts?.ForEach(a => a.Reset());
+    }
+
+    public void EndMission()
+    {
+        IsRunning = false;
+        Log.Info($"{MissionId} 任务结束!");
+
+        if (currentExecuteCount > ExecutionContext)
+        {
+            return;
+        }
+
+        if (currentExecuteCount < ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+        }
+
+        if (currentExecuteCount == ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+            ReportSJ();
+            IsOver = true;
+            return;
+        }
+
+        this.Reset();
+        this.Start();
+        currentExecuteCount++;
+    }
+
+    public void SaveAircraftSJDatas()
+    {
+        foreach (AircraftSHJ aircraftEntity in aircrafts)
+        {
+            string key = aircraftEntity.AircraftId;
+            if (!aircraftSJDatas.ContainsKey(key))
+            {
+                aircraftSJDatas[key] = new Dictionary<string, List<string>>();
+            }
+            if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
+                aircraftSJDatas[key]["识别成功率"] = new List<string>();
+            aircraftSJDatas[key]["识别成功率"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
+                aircraftSJDatas[key]["任务准备时间"] = new List<string>();
+            aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
+                aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
+            aircraftSJDatas[key]["平均搜索时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
+                aircraftSJDatas[key]["总飞行时间"] = new List<string>();
+            aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
+                aircraftSJDatas[key]["人员存活率"] = new List<string>();
+            aircraftSJDatas[key]["人员存活率"].Add("0");
+        }
+    }
+
+    public void SaveSJ()
+    {
+        foreach (AircraftSHJ aircraftEntity in aircrafts)
+        {
+            var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
+
+            if (staticCapacity == null) continue;
+
+            staticCapacity.FillData6(aircraftEntity.Db);
+
+            string key = aircraftEntity.AircraftId;
+
+            if (!singleReport.ContainsKey(key))
+            {
+                singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
+            }
+
+            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport6();
+            foreach (var kv in staticReport)
+            {
+                if (!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
+                foreach (var kv2 in kv.Value)
+                {
+                    if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
+                    singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
+                }
+            }
+        }
+        if (currentExecuteCount == ExecutionContext)
+        {
+            foreach (var kv in singleReport)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    foreach (var kv3 in kv2.Value)
+                    {
+                        var sum = 0f;
+                        foreach (var kv4 in kv3.Value)
+                        {
+                            bool isfloat = float.TryParse(kv4, out float f);
+                            if (isfloat)
+                                sum += float.Parse(kv4);
+                            else
+                                sum = -1f;
+                        }
+                        if (sum != -1f)
+                            kv3.Value.Add((sum / kv3.Value.Count).ToString());
+                        else
+                            kv3.Value.Add("");
+                    }
+                }
+            }
+        }
+    }
+
+    public void ReportSJ()
+    {
+        string path = $"Reports/{date}/{MissionId}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        foreach (var kv in singleReport)
+        {
+            string filePath = $"{path}/{kv.Key}搜救任务单机指标报告.xls";
+            DataTableExtensions.SaveToExcel(filePath, kv.Value, true);
+        }
+    }
+}
+
+
+[ObjectSystem]
+public class SHJMissionUpdateSystem : UpdateSystem<SHJMission>
+{
+    public override void Update(SHJMission self)
+    {
+        if (!self.IsRunning) return;
+
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
+
+        if (self.aircrafts.All(a => a.IsOver))
+        {
+            self.EndMission();
+        }
+    }
+}

+ 188 - 0
SimulationServer/Entity/ZSJYMission.cs

@@ -0,0 +1,188 @@
+using KYFramework;
+using NPOI.SS.Formula.PTG;
+using SimulationServer.Utils;
+
+namespace SimulationServer;
+
+public class ZSJYMission : Entity
+{
+    public string MissionId; // 任务ID
+    public bool Success; // 任务是否成功
+    public List<AircraftZS> aircrafts = new List<AircraftZS>();
+
+    public bool IsRunning;
+    public double SimulationTime;
+
+    public Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> singleReport = new();
+
+    public Dictionary<string, Dictionary<string, List<string>>> aircraftSJDatas = new();
+
+    public bool IsOver = false;
+
+    private int currentExecuteCount = 1;
+    public int ExecutionContext = 0;
+
+    public string date;
+    public void Start()
+    {
+        IsRunning = true;
+        aircrafts.ForEach(a => a.Start());
+        Log.Info($"{MissionId} 任务开始!");
+    }
+
+    public void Reset()
+    {
+        SimulationTime = 0;
+        aircrafts?.ForEach(a => a.Reset());
+    }
+
+    public void EndMission()
+    {
+        IsRunning = false;
+        Log.Info($"{MissionId} 任务结束!");
+
+        if (currentExecuteCount > ExecutionContext)
+        {
+            return;
+        }
+
+        if (currentExecuteCount < ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+        }
+
+        if (currentExecuteCount == ExecutionContext)
+        {
+            SaveSJ();
+            SaveAircraftSJDatas();
+            ReportSJ();
+            IsOver = true;
+            return;
+        }
+
+        this.Reset();
+        this.Start();
+        currentExecuteCount++;
+    }
+
+    public void SaveAircraftSJDatas()
+    {
+        foreach (AircraftZS aircraftEntity in aircrafts)
+        {
+            string key = aircraftEntity.AircraftId;
+            if (!aircraftSJDatas.ContainsKey(key))
+            {
+                aircraftSJDatas[key] = new Dictionary<string, List<string>>();
+            }
+            if (!aircraftSJDatas[key].ContainsKey("识别成功率"))
+                aircraftSJDatas[key]["识别成功率"] = new List<string>();
+            aircraftSJDatas[key]["识别成功率"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("识别数量"))
+                aircraftSJDatas[key]["识别数量"] = new List<string>();
+            aircraftSJDatas[key]["识别数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("人员数量"))
+                aircraftSJDatas[key]["人员数量"] = new List<string>();
+            aircraftSJDatas[key]["人员数量"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("任务准备时间"))
+                aircraftSJDatas[key]["任务准备时间"] = new List<string>();
+            aircraftSJDatas[key]["任务准备时间"].Add(aircraftEntity.TaskReadyTime.ToString());
+            if (!aircraftSJDatas[key].ContainsKey("平均搜索时间"))
+                aircraftSJDatas[key]["平均搜索时间"] = new List<string>();
+            aircraftSJDatas[key]["平均搜索时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("平均救助时间"))
+                aircraftSJDatas[key]["平均救助时间"] = new List<string>();
+            aircraftSJDatas[key]["平均救助时间"].Add("0");
+            if (!aircraftSJDatas[key].ContainsKey("总飞行时间"))
+                aircraftSJDatas[key]["总飞行时间"] = new List<string>();
+            aircraftSJDatas[key]["总飞行时间"].Add(aircraftEntity.TotalTime.ToString("f4"));
+            if (!aircraftSJDatas[key].ContainsKey("人员存活率"))
+                aircraftSJDatas[key]["人员存活率"] = new List<string>();
+            aircraftSJDatas[key]["人员存活率"].Add("0");
+        }
+    }
+
+    public void SaveSJ()
+    {
+        foreach (AircraftZS aircraftEntity in aircrafts)
+        {
+            var staticCapacity = aircraftEntity.GetComponent<SJStaticCapacityComponent>();
+
+            if (staticCapacity == null) continue;
+
+            staticCapacity.FillData4(aircraftEntity.Db);
+
+            string key = aircraftEntity.AircraftId;
+
+            if (!singleReport.ContainsKey(key))
+            {
+                singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
+            }
+
+            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport4();
+            foreach (var kv in staticReport)
+            {
+                if (!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
+                foreach (var kv2 in kv.Value)
+                {
+                    if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
+                    singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
+                }
+            }
+        }
+        if (currentExecuteCount == ExecutionContext)
+        {
+            foreach (var kv in singleReport)
+            {
+                foreach (var kv2 in kv.Value)
+                {
+                    foreach (var kv3 in kv2.Value)
+                    {
+                        var sum = 0f;
+                        foreach (var kv4 in kv3.Value)
+                        {
+                            bool isfloat = float.TryParse(kv4, out float f);
+                            if (isfloat)
+                                sum += float.Parse(kv4);
+                            else
+                                sum = -1f;
+                        }
+                        if (sum != -1f)
+                            kv3.Value.Add((sum / kv3.Value.Count).ToString());
+                        else
+                            kv3.Value.Add("");
+                    }
+                }
+            }
+        }
+    }
+
+    public void ReportSJ()
+    {
+        //string data = DateTime.Now.ToString("yyyy-MM-dd");
+        string path = $"Reports/{date}/{MissionId}";
+        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        foreach (var kv in singleReport)
+        {
+            string filePath = $"{path}/{kv.Key}搜救任务单机指标报告.xls";
+            DataTableExtensions.SaveToExcel(filePath, kv.Value, true);
+        }
+    }
+}
+
+
+[ObjectSystem]
+public class ZSJYMissionUpdateSystem : UpdateSystem<ZSJYMission>
+{
+    public override void Update(ZSJYMission self)
+    {
+        if (!self.IsRunning) return;
+
+        self.aircrafts?.ForEach(a => a.Update(self.SimulationTime));
+
+        if (self.aircrafts.All(a => a.IsOver))
+        {
+            self.EndMission();
+        }
+    }
+}

+ 284 - 4
SimulationServer/EventHandler/CreateTaskEventHandler.cs

@@ -59,7 +59,7 @@ public class CreateZCTaskEventHandler : AEvent<CreateZCTask>
             aircraft.AircraftId = config.ZCTask.aircraftInfos[i].AircraftId;
             foreach (var item in config.ZCTask.ZCMethods)
             {
-                if(aircraft.AircraftId == item.AircraftId)
+                if (aircraft.AircraftId == item.AircraftId)
                 {
                     aircraft.ZCMethod = item;
                 }
@@ -155,7 +155,8 @@ public class CreateSeaSJEventHandler : AEvent<CreateSeaSJTask>
     {
         var taskSys = Game.Scene.GetComponent<TaskComponent>();
         SeaSJRescueMission mission = ComponentFactory.Create<SeaSJRescueMission>();
-        taskSys.AddMission(mission);
+        mission.date = taskSys.date;
+        taskSys.SeaSJRescueMissions.Add(mission);
         mission.MissionId = $"海上搜索救援任务 {config.SeaSJTask.missionInformation.MissionName}";
         mission.ExecutionContext = config.EditorConfig.runCounts;
         mission.AddComponent<SJTotalTaskPerformanceComponent>();
@@ -188,6 +189,11 @@ public class CreateSeaSJEventHandler : AEvent<CreateSeaSJTask>
                 if (aircraft.AircraftId == item.AircraftId)
                     aircraft.SearchMode = item;
             }
+            foreach (var item in config.SeaSJTask.missionSearchPayloads)
+            {
+                if (aircraft.AircraftId == item.AircraftId)
+                    aircraft.searchMissionPayload = item;
+            }
             aircraft.AddComponent<SJStaticCapacityComponent>();
             Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
         }
@@ -203,8 +209,9 @@ public class CreateLandSJEventHandler : AEvent<CreateLandSXTask>
     {
         var taskSys = Game.Scene.GetComponent<TaskComponent>();
         LandSJRescueMission mission = ComponentFactory.Create<LandSJRescueMission>();
-        taskSys.AddMission(mission);
-        mission.MissionId = $"陆上搜索救援任务 {config.LandSXTask.missionInformation.MissionName}";
+        mission.date = taskSys.date;
+        taskSys.LandSJRescueMissions.Add(mission);
+        mission.MissionId = $"陆上搜寻救援任务 {config.LandSXTask.missionInformation.MissionName}";
         mission.ExecutionContext = config.EditorConfig.runCounts;
         //mission.AddComponent<SJTotalTaskPerformanceComponent>();
         for (int i = 0; i < config.LandSXTask.aircraftInfos.Length; i++)
@@ -240,6 +247,11 @@ public class CreateLandSJEventHandler : AEvent<CreateLandSXTask>
                 if (item.AircraftId == aircraft.AircraftId)
                     aircraft.SearchMissionMode = item;
             }
+            foreach (var item in config.LandSXTask.missionSearchPayloads)
+            {
+                if (aircraft.AircraftId == item.AircraftId)
+                    aircraft.searchMissionPayload = item;
+            }
 
             aircraft.AddComponent<SJStaticCapacityComponent>();
             Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
@@ -247,4 +259,272 @@ public class CreateLandSJEventHandler : AEvent<CreateLandSXTask>
 
         return UniTask.CompletedTask;
     }
+
+    [Event]
+    public class CreateKZDYEventHandler : AEvent<CreateKZDYTask>
+    {
+        protected override UniTask Run(CreateKZDYTask config)
+        {
+            var taskSys = Game.Scene.GetComponent<TaskComponent>();
+            KZDYMission mission = ComponentFactory.Create<KZDYMission>();
+            mission.date = taskSys.date;
+            taskSys.KZDYMissions.Add(mission);
+            mission.MissionId = $"空中吊运救援任务 {config.KZDYTask.missionInformation.MissionName}";
+            mission.ExecutionContext = config.EditorConfig.runCounts;
+            //mission.AddComponent<SJTotalTaskPerformanceComponent>();
+            for (int i = 0; i < config.KZDYTask.aircraftInfos.Length; i++)
+            {
+                //飞机参数
+                var aircraftParameter = config.EditorConfig.aircraftParameters.Find(
+                    a => a.AircraftID == config.KZDYTask.aircraftInfos[i].AircraftType);
+                //基地
+                var originBase = config.EditorConfig.bases.Find(b => b.BaseId == aircraftParameter.AirportId);
+
+                TargetPoint targetPoint = config.EditorConfig.targetPoints.Find(t => t.TargetPointId == config.KZDYTask.missionInformation.TargetPointId);
+                //创建飞行计划编辑器
+                var flightPlanEditor = FlightPlanEditor.Create(aircraftParameter, config.EditorConfig.cityWeather, originBase, new TargetPoint[] { targetPoint });
+
+                AircraftDY aircraft = ComponentFactory.Create<AircraftDY, FlightPlanEditor>(flightPlanEditor);
+                aircraft.Name = config.KZDYTask.aircraftInfos[i].AircraftType;
+                aircraft.TaskReadyTime = config.KZDYTask.missionInformation.TakeoffPreparationTime;
+                mission.aircrafts.Add(aircraft);
+                aircraft.taskContent = config.KZDYTask;
+                aircraft.AircraftId = config.KZDYTask.aircraftInfos[i].AircraftId;
+                aircraft.MissionEndPoint = new MissionEndPoint
+                {
+                    MissionEndPointLongitude = targetPoint.TargetPointLongitude,
+                    MissionEndPointLatitude = targetPoint.TargetPointLatitude,
+                    MissionEndPointHeight = targetPoint.TargetPointHeight
+                };
+
+                foreach (var item in config.KZDYTask.KZDYParameters)
+                {
+                    if (item.AircraftId == aircraft.AircraftId)
+                    {
+                        aircraft.taskParameter = item;
+                    }
+                }
+
+                aircraft.AddComponent<SJStaticCapacityComponent>();
+                Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
+            }
+
+            return UniTask.CompletedTask;
+        }
+    }
+
+    [Event]
+    public class CreateKTKSEventHandler : AEvent<CreateKTKSTask>
+    {
+        protected override UniTask Run(CreateKTKSTask config)
+        {
+            var taskSys = Game.Scene.GetComponent<TaskComponent>();
+            KTKSMission mission = ComponentFactory.Create<KTKSMission>();
+            mission.date = taskSys.date;
+            taskSys.KTKSMissions.Add(mission);
+            mission.MissionId = $"空投空送任务 {config.KTKSTask.missionInformation.MissionName}";
+            mission.ExecutionContext = config.EditorConfig.runCounts;
+            //mission.AddComponent<SJTotalTaskPerformanceComponent>();
+            for (int i = 0; i < config.KTKSTask.aircraftInfos.Length; i++)
+            {
+                //飞机参数
+                var aircraftParameter = config.EditorConfig.aircraftParameters.Find(
+                    a => a.AircraftID == config.KTKSTask.aircraftInfos[i].AircraftType);
+                //基地
+                var originBase = config.EditorConfig.bases.Find(b => b.BaseId == aircraftParameter.AirportId);
+
+                TargetPoint targetPoint = config.EditorConfig.targetPoints.Find(t => t.TargetPointId == config.KTKSTask.missionInformation.TargetPointId);
+                //创建飞行计划编辑器
+                var flightPlanEditor = FlightPlanEditor.Create(aircraftParameter, config.EditorConfig.cityWeather, originBase, new TargetPoint[] { targetPoint });
+
+                AircraftKTKS aircraft = ComponentFactory.Create<AircraftKTKS, FlightPlanEditor>(flightPlanEditor);
+                aircraft.Name = config.KTKSTask.aircraftInfos[i].AircraftType;
+                aircraft.TaskReadyTime = config.KTKSTask.missionInformation.TakeoffPreparationTime;
+                mission.aircrafts.Add(aircraft);
+                aircraft.taskContent = config.KTKSTask;
+                aircraft.AircraftId = config.KTKSTask.aircraftInfos[i].AircraftId;
+                aircraft.rescueDemandInfo = config.EditorConfig.rescueDemandInfos.Find(t => t.DemandPointName == config.KTKSTask.missionInformation.TargetPoint);
+                //aircraft.MissionEndPoint = new MissionEndPoint
+                //{
+                //    MissionEndPointLongitude = targetPoint.TargetPointLongitude,
+                //    MissionEndPointLatitude = targetPoint.TargetPointLatitude,
+                //    MissionEndPointHeight = targetPoint.TargetPointHeight
+                //};
+
+                foreach (var item in config.KTKSTask.KTKSParameters)
+                {
+                    if (item.AircraftId == aircraft.AircraftId)
+                    {
+                        aircraft.taskParameter = item;
+                    }
+                }
+
+                aircraft.AddComponent<SJStaticCapacityComponent>();
+                Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
+            }
+
+            return UniTask.CompletedTask;
+        }
+    }
+
+    [Event]
+    public class CreateZSJYEventHandler : AEvent<CreateZSJYTask>
+    {
+        protected override UniTask Run(CreateZSJYTask config)
+        {
+            var taskSys = Game.Scene.GetComponent<TaskComponent>();
+            ZSJYMission mission = ComponentFactory.Create<ZSJYMission>();
+            mission.date = taskSys.date;
+            taskSys.ZSJYMissions.Add(mission);
+            mission.MissionId = $"着水救援任务 {config.ZSJYTask.missionInformation.MissionName}";
+            mission.ExecutionContext = config.EditorConfig.runCounts;
+            //mission.AddComponent<SJTotalTaskPerformanceComponent>();
+            for (int i = 0; i < config.ZSJYTask.aircraftInfos.Length; i++)
+            {
+                //飞机参数
+                var aircraftParameter = config.EditorConfig.aircraftParameters.Find(
+                    a => a.AircraftID == config.ZSJYTask.aircraftInfos[i].AircraftType);
+                //基地
+                var originBase = config.EditorConfig.bases.Find(b => b.BaseId == aircraftParameter.AirportId);
+
+                TargetPoint targetPoint = config.EditorConfig.targetPoints.Find(t => t.TargetPointId == config.ZSJYTask.missionInformation.TargetPointId);
+                //创建飞行计划编辑器
+                var flightPlanEditor = FlightPlanEditor.Create(aircraftParameter, config.EditorConfig.cityWeather, originBase, new TargetPoint[] { targetPoint });
+
+                AircraftZS aircraft = ComponentFactory.Create<AircraftZS, FlightPlanEditor>(flightPlanEditor);
+                aircraft.Name = config.ZSJYTask.aircraftInfos[i].AircraftType;
+                aircraft.TaskReadyTime = config.ZSJYTask.missionInformation.TakeoffPreparationTime;
+                mission.aircrafts.Add(aircraft);
+                aircraft.taskContent = config.ZSJYTask;
+                aircraft.AircraftId = config.ZSJYTask.aircraftInfos[i].AircraftId;
+                //aircraft.MissionEndPoint = new MissionEndPoint
+                //{
+                //    MissionEndPointLongitude = targetPoint.TargetPointLongitude,
+                //    MissionEndPointLatitude = targetPoint.TargetPointLatitude,
+                //    MissionEndPointHeight = targetPoint.TargetPointHeight
+                //};
+
+                foreach (var item in config.ZSJYTask.ZSJYParameters)
+                {
+                    if (item.AircraftId == aircraft.AircraftId)
+                    {
+                        aircraft.taskParameter = item;
+                    }
+                }
+
+                aircraft.AddComponent<SJStaticCapacityComponent>();
+                Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
+            }
+
+            return UniTask.CompletedTask;
+        }
+    }
+
+    [Event]
+    public class CreateJJJYEventHandler : AEvent<CreateJJJYTask>
+    {
+        protected override UniTask Run(CreateJJJYTask config)
+        {
+            var taskSys = Game.Scene.GetComponent<TaskComponent>();
+            JJJYMission mission = ComponentFactory.Create<JJJYMission>();
+            mission.date = taskSys.date;
+            taskSys.JJJYMissions.Add(mission);
+            mission.MissionId = $"机降救援任务 {config.JJJYTask.missionInformation.MissionName}";
+            mission.ExecutionContext = config.EditorConfig.runCounts;
+            //mission.AddComponent<SJTotalTaskPerformanceComponent>();
+            for (int i = 0; i < config.JJJYTask.aircraftInfos.Length; i++)
+            {
+                //飞机参数
+                var aircraftParameter = config.EditorConfig.aircraftParameters.Find(
+                    a => a.AircraftID == config.JJJYTask.aircraftInfos[i].AircraftType);
+                //基地
+                var originBase = config.EditorConfig.bases.Find(b => b.BaseId == aircraftParameter.AirportId);
+
+                TargetPoint targetPoint = config.EditorConfig.targetPoints.Find(t => t.TargetPointId == config.JJJYTask.missionInformation.TargetPointId);
+
+                //创建飞行计划编辑器
+                var flightPlanEditor = FlightPlanEditor.Create(aircraftParameter, config.EditorConfig.cityWeather, originBase, new TargetPoint[] { targetPoint });
+
+                AircraftJJ aircraft = ComponentFactory.Create<AircraftJJ, FlightPlanEditor>(flightPlanEditor);
+                aircraft.Name = config.JJJYTask.aircraftInfos[i].AircraftType;
+                aircraft.TaskReadyTime = config.JJJYTask.missionInformation.TakeoffPreparationTime;
+                mission.aircrafts.Add(aircraft);
+                aircraft.taskContent = config.JJJYTask;
+                aircraft.AircraftId = config.JJJYTask.aircraftInfos[i].AircraftId;
+                aircraft.rescueDemandInfo = config.EditorConfig.rescueDemandInfos.Find(t => t.DemandPointName == config.JJJYTask.missionInformation.TargetPoint);
+                //aircraft.MissionEndPoint = new MissionEndPoint
+                //{
+                //    MissionEndPointLongitude = targetPoint.TargetPointLongitude,
+                //    MissionEndPointLatitude = targetPoint.TargetPointLatitude,
+                //    MissionEndPointHeight = targetPoint.TargetPointHeight
+                //};
+
+                foreach (var item in config.JJJYTask.JJJYParameters)
+                {
+                    if (item.AircraftId == aircraft.AircraftId)
+                    {
+                        aircraft.taskParameter = item;
+                    }
+                }
+
+                aircraft.AddComponent<SJStaticCapacityComponent>();
+                Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
+            }
+
+            return UniTask.CompletedTask;
+        }
+    }
+
+    [Event]
+    public class CreateSHJEventHandler : AEvent<CreateSHJTask>
+    {
+        protected override UniTask Run(CreateSHJTask config)
+        {
+            var taskSys = Game.Scene.GetComponent<TaskComponent>();
+            SHJMission mission = ComponentFactory.Create<SHJMission>();
+            mission.date = taskSys.date;
+            taskSys.SHJMissions.Add(mission);
+            mission.MissionId = $"索滑降救援任务 {config.SHJTask.missionInformation.MissionName}";
+            mission.ExecutionContext = config.EditorConfig.runCounts;
+            //mission.AddComponent<SJTotalTaskPerformanceComponent>();
+            for (int i = 0; i < config.SHJTask.aircraftInfos.Length; i++)
+            {
+                //飞机参数
+                var aircraftParameter = config.EditorConfig.aircraftParameters.Find(
+                    a => a.AircraftID == config.SHJTask.aircraftInfos[i].AircraftType);
+                //基地
+                var originBase = config.EditorConfig.bases.Find(b => b.BaseId == aircraftParameter.AirportId);
+
+                TargetPoint targetPoint = config.EditorConfig.targetPoints.Find(t => t.TargetPointId == config.SHJTask.missionInformation.TargetPointId);
+
+                //创建飞行计划编辑器
+                var flightPlanEditor = FlightPlanEditor.Create(aircraftParameter, config.EditorConfig.cityWeather, originBase, new TargetPoint[] { targetPoint });
+                AircraftSHJ aircraft = ComponentFactory.Create<AircraftSHJ, FlightPlanEditor>(flightPlanEditor);
+                aircraft.Name = config.SHJTask.aircraftInfos[i].AircraftType;
+                aircraft.TaskReadyTime = config.SHJTask.missionInformation.TakeoffPreparationTime;
+                mission.aircrafts.Add(aircraft);
+                aircraft.content = config.SHJTask;
+                aircraft.AircraftId = config.SHJTask.aircraftInfos[i].AircraftId;
+                aircraft.missionEndPoint = new MissionEndPoint
+                {
+                    MissionEndPointLongitude = targetPoint.TargetPointLongitude,
+                    MissionEndPointLatitude = targetPoint.TargetPointLatitude,
+                    MissionEndPointHeight = targetPoint.TargetPointHeight
+                };
+
+                foreach (var item in config.SHJTask.SHJParameters)
+                {
+                    if (item.AircraftId == aircraft.AircraftId)
+                    {
+                        aircraft.SHJParameter = item;
+                    }
+                }
+
+                aircraft.AddComponent<SJStaticCapacityComponent>();
+                Log.Info($"创建机型 : {flightPlanEditor.aircraftparameter.AircraftID}");
+            }
+
+            return UniTask.CompletedTask;
+        }
+    }
 }

+ 30 - 0
SimulationServer/EventHandler/EventStruct.cs

@@ -49,6 +49,36 @@ public struct CreateLandSXTask
     public LandSouXunTask LandSXTask;
 }
 
+public struct CreateKZDYTask
+{
+    public EditorConfig EditorConfig;
+    public KZDYTask KZDYTask;
+}
+
+public struct CreateKTKSTask
+{
+    public EditorConfig EditorConfig;
+    public KTKSTask KTKSTask;
+}
+
+public struct CreateZSJYTask
+{
+    public EditorConfig EditorConfig;
+    public ZSJYTask ZSJYTask;
+}
+
+public struct CreateJJJYTask
+{
+    public EditorConfig EditorConfig;
+    public JJJYTask JJJYTask;
+}
+
+public struct CreateSHJTask
+{
+    public EditorConfig EditorConfig;
+    public SHJTask SHJTask;
+}
+
 public struct CreateXHTask
 {
     public EditorConfig EditorConfig;

+ 25 - 7
SimulationServer/EventHandler/ServerStartEventHandler.cs

@@ -5,6 +5,7 @@ using Newtonsoft.Json;
 using SimulationServer.Utils;
 using SimulationSingleServer.Utils;
 using static Org.BouncyCastle.Math.EC.ECCurve;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 using Define = SimulationServer.Utils.Define;
 
 namespace SimulationServer;
@@ -16,6 +17,8 @@ public class ServerStartEventHandler : AEvent<ServerStart>
     {
         Log.Info("读取配置文件!");
         var taskSys = Game.Scene.GetComponent<TaskComponent>();
+        taskSys.date = DateTime.Now.ToString().Replace("/","-").Replace(":","-").Replace(" ","-");
+        //Console.WriteLine("date:" + taskSys.date);
         HttpInterface.serverIp = File.ReadAllText("dbIp.txt");
         SimulationCommon.Util.serverIp = HttpInterface.serverIp;
         // 读取任务配置文件
@@ -33,7 +36,6 @@ public class ServerStartEventHandler : AEvent<ServerStart>
             Log.Error("task_config.json文件不存在!");
             return UniTask.CompletedTask;
         }
-
         string ec_str = File.ReadAllText("Missions/editor_config.json");
         string tc_str = File.ReadAllText("Missions/task_config.json");
         EditorConfig? editorConfig = JsonConvert.DeserializeObject<EditorConfig>(ec_str);
@@ -44,6 +46,22 @@ public class ServerStartEventHandler : AEvent<ServerStart>
             Log.Error("配置文件解析失败!");
             return UniTask.CompletedTask;
         }
+
+
+        foreach (var item in editorConfig.targetPoints)
+        {
+            if (item.TargetType.Type == "遇险人员" || item.TargetType.Type == "车辆" || item.TargetType.Type == "航空器")
+            {
+                taskSys.isLand = true;
+            }
+            else if (item.TargetType.Type == "落水人员" || item.TargetType.Type == "救生筏" || item.TargetType.Type == "船舶" || item.TargetType.Type == "大规模落水人群")
+            {
+                taskSys.isSea = true;
+            }
+            //Console.WriteLine("taskSys.isLand:" + taskSys.isLand + "_" + "taskSys.isSea:" + taskSys.isSea);
+            break;
+        }
+
         //Weather weather = Util.GetWeather("内蒙古", "根河", DateTime.Now.ToString("2024-05-10"));
         TaskComponent.Weather = new Weather();
         var temp = TaskComponent.Weather.day_temp.Replace("°C", "");
@@ -85,12 +103,12 @@ public class ServerStartEventHandler : AEvent<ServerStart>
             { EditorConfig = editorConfig, ShjTaskConfig = shjTask });
         }
 
-        // 创建侦察
-        foreach (var zcTask in taskConfig.zCTask)
-        {
-            Game.EventSystem.Publish(new CreateZCTask
-            { EditorConfig = editorConfig, ZCTask = zcTask });
-        }
+        //// 创建侦察
+        //foreach (var zcTask in taskConfig.zCTask)
+        //{
+        //    Game.EventSystem.Publish(new CreateZCTask
+        //    { EditorConfig = editorConfig, ZCTask = zcTask });
+        //}
 
         // 创建巡护
         foreach (var xhTask in taskConfig.xHTask)

+ 2 - 0
SimulationServer/SimulationServer.csproj

@@ -29,6 +29,8 @@
     </ItemGroup>
 
     <ItemGroup>
+      <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+      <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
       <PackageReference Include="NPOI.Excel" Version="2.1.1" />
       <PackageReference Include="NPOIHelper" Version="2.0.13" />
     </ItemGroup>

+ 37 - 22
SimulationServer/Utils/DataTableExtensions.cs

@@ -68,26 +68,26 @@ public static class DataTableExtensions
         return entities;
     }
 
-    public static void SaveToExcel(string path , Dictionary<string, Dictionary<string,List<string>>> report,bool withA = false)
+    public static void SaveToExcel(string path, Dictionary<string, Dictionary<string, List<string>>> report, bool withA = false, bool zt = false, string s = "")
     {
-        if(!File.Exists(path)) File.Create(path).Close();
+        if (!File.Exists(path)) File.Create(path).Close();
         // 创建一个新的Excel文件
         var workbook = new HSSFWorkbook();
 
-        foreach (KeyValuePair<string,Dictionary<string,List<string>>> kv in report)
+        foreach (KeyValuePair<string, Dictionary<string, List<string>>> kv in report)
         {
             // 创建一个新的工作表
             var sheet = workbook.CreateSheet(kv.Key);
-            
+
             // 创建标题行
             var headerRow = sheet.CreateRow(0);
-            
+
             var headerCell = headerRow.CreateCell(0);
             headerCell.SetCellValue("指标名");
-            
+
             // 遍历字典,将数据写入Excel
             int rowIndex = 1;
-            foreach (KeyValuePair<string,List<string>> kv1 in kv.Value)
+            foreach (KeyValuePair<string, List<string>> kv1 in kv.Value)
             {
                 var row = sheet.CreateRow(rowIndex);
                 row.CreateCell(0).SetCellValue(kv1.Key);
@@ -96,7 +96,7 @@ public static class DataTableExtensions
                     for (int i = 0; i < kv1.Value.Count - 1; i++)
                     {
                         var headerCell1 = headerRow.CreateCell(i + 1);
-                        headerCell1.SetCellValue($"数值{i+1}");
+                        headerCell1.SetCellValue($"仿真轮次{i + 1}");
                         row.CreateCell(i + 1).SetCellValue(kv1.Value[i]);
                     }
                     var headerCell1End = headerRow.CreateCell(kv1.Value.Count);
@@ -108,45 +108,60 @@ public static class DataTableExtensions
                     for (int i = 0; i < kv1.Value.Count; i++)
                     {
                         var headerCell1 = headerRow.CreateCell(i + 1);
-                        headerCell1.SetCellValue($"数值{i+1}");
+                        headerCell1.SetCellValue($"仿真轮次{i + 1}");
                         row.CreateCell(i + 1).SetCellValue(kv1.Value[i]);
                     }
                 }
-               
+
                 rowIndex++;
             }
         }
 
+        if (zt)
+        {
+            var sheet = workbook.CreateSheet("任务成功率");
+            var Row0 = sheet.CreateRow(0);
+            var Row0Cell0 = Row0.CreateCell(0);
+            Row0Cell0.SetCellValue("指标名");
+            var Row0Cell1 = Row0.CreateCell(1);
+            Row0Cell1.SetCellValue("数值");
+            var Row1 = sheet.CreateRow(1);
+            var Row1Cell0 = Row1.CreateCell(0);
+            Row1Cell0.SetCellValue("任务成功率");
+            var Row1Cell1 = Row1.CreateCell(1);
+            Row1Cell1.SetCellValue(s);
+        }
+
         // 保存Excel文件
         using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
         {
             workbook.Write(fs);
         }
     }
-    public static void SaveToExcel(string path , Dictionary<string, Dictionary<string,string>> report)
+    public static void SaveToExcel(string path, Dictionary<string, Dictionary<string, string>> report)
     {
-        
+
         // 创建一个新的Excel文件
         var workbook = new HSSFWorkbook();
 
-        foreach (KeyValuePair<string,Dictionary<string,string>> kv in report)
+        foreach (KeyValuePair<string, Dictionary<string, string>> kv in report)
         {
             // 创建一个新的工作表
             var sheet = workbook.CreateSheet(kv.Key);
-            
+
             // 创建标题行
             var headerRow = sheet.CreateRow(0);
             var headerCell = headerRow.CreateCell(0);
-            
+
             var headerRow1 = sheet.CreateRow(1);
             var headerCell1 = headerRow1.CreateCell(1);
-            
+
             headerCell.SetCellValue("指标名");
-            headerCell1.SetCellValue("数值");
-            
+            headerCell1.SetCellValue("仿真轮次");
+
             // 遍历字典,将数据写入Excel
             int rowIndex = 1;
-            foreach (KeyValuePair<string,string> kv1 in kv.Value)
+            foreach (KeyValuePair<string, string> kv1 in kv.Value)
             {
                 var row = sheet.CreateRow(rowIndex);
                 row.CreateCell(0).SetCellValue(kv1.Key);
@@ -160,8 +175,8 @@ public static class DataTableExtensions
         {
             workbook.Write(fs);
         }
-        
-        
-        
+
+
+
     }
 }

+ 1 - 1
SimulationServer/Utils/Util.cs

@@ -57,7 +57,7 @@ public class Util
 
         if (define.zs.Count == 0)
         {
-            Log.Debug($"没有找到对应 [{aircraftID}] 的飞机信息");
+            //Log.Debug($"没有找到对应 [{aircraftID}] 的飞机信息");
             return new AircraftDB();
         }
             

BIN
SimulationServer/bin/Debug/net7.0-windows/MathNet.Numerics.dll


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/2024-08-30/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-2/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-3/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000-4/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/LSX/8000/陆上搜寻救援任务 陆上搜寻任务1/1-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-08-30/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/2024-09-11/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-1/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-2/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-3/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-4/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006-5/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜救任务总体指标报告.xls


BIN
SimulationServer/bin/Debug/net7.0-windows/Reports/SSJ/9006/海上搜索救援任务 海上搜救任务1/3-1搜救任务单机指标报告.xls


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 758 - 32
SimulationServer/bin/Debug/net7.0-windows/Simulation.deps.json


BIN
SimulationServer/bin/Debug/net7.0/KYFramework.dll


BIN
SimulationServer/bin/Debug/net7.0/KYNetwork.dll


BIN
SimulationServer/bin/Debug/net7.0/KYNetwork.pdb


BIN
SimulationServer/bin/Debug/net7.0/SimulationCommon.dll


BIN
SimulationServer/bin/Debug/net7.0/SimulationCommon.pdb


BIN
SimulationServer/bin/Debug/net7.0/SimulationServer.dll


BIN
SimulationServer/bin/Debug/net7.0/SimulationServer.exe


BIN
SimulationServer/bin/Debug/net7.0/SimulationServer.pdb


BIN
SimulationServer/bin/Debug/net7.0/ThirdParty.pdb


+ 2 - 0
ThirdParty/ThirdParty.csproj

@@ -7,6 +7,8 @@
     </PropertyGroup>
 
     <ItemGroup>
+      <PackageReference Include="GeoCoordinate" Version="2.0.1" />
+      <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
       <PackageReference Include="MySql.Data" Version="8.1.0" />
       <PackageReference Include="UniTask" Version="2.4.1" />
     </ItemGroup>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 812 - 0
ThirdParty/bin/Debug/net7.0/ThirdParty.deps.json


BIN
ThirdParty/bin/Debug/net7.0/ThirdParty.dll


BIN
ThirdParty/bin/Debug/net7.0/ThirdParty.pdb


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است