diff --git a/Plane.FormationCreator.sln b/Plane.FormationCreator.sln
index ce338a0..5366b41 100644
--- a/Plane.FormationCreator.sln
+++ b/Plane.FormationCreator.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34202.233
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.FormationCreator", "Plane.FormationCreator\Plane.FormationCreator.csproj", "{61E2F31E-220A-4E3F-A64D-F7CDC2135008}"
ProjectSection(ProjectDependencies) = postProject
@@ -28,15 +28,9 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRoute", "..\FlyTest\FlightRoute\FlightRoute.csproj", "{705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlyBase", "..\FlyCube\FlyBase\FlyBase.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRouteV2", "..\FlyCube\FlightRouteV2\FlightRouteV2.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}"
EndProject
Global
- GlobalSection(SharedMSBuildProjectFiles) = preSolution
- ..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
- ..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
- ..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
- ..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
- EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
@@ -128,4 +122,10 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
+ ..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
+ ..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
+ ..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
+ EndGlobalSection
EndGlobal
diff --git a/Plane.FormationCreator/App.config b/Plane.FormationCreator/App.config
index f138028..e7bb9a6 100644
--- a/Plane.FormationCreator/App.config
+++ b/Plane.FormationCreator/App.config
@@ -1,53 +1,53 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 192.168.1.50
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 192.168.1.50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plane.FormationCreator/App.xaml.cs b/Plane.FormationCreator/App.xaml.cs
index ec0aab8..f89c7b6 100644
--- a/Plane.FormationCreator/App.xaml.cs
+++ b/Plane.FormationCreator/App.xaml.cs
@@ -1,312 +1,313 @@
-using Plane.Communication;
-using Plane.Copters;
-using Plane.FormationCreator.Formation;
-using Plane.Logging;
-using Plane.Windows;
-using Plane.Windows.Messages;
-using GalaSoft.MvvmLight.Ioc;
-using Microsoft.Practices.ServiceLocation;
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows;
-using Plane.CommunicationManagement;
-using Plane.FormationCreator.Util;
-
-namespace Plane.FormationCreator
-{
- ///
- /// Interaction logic for App.xaml
- ///
- public partial class App : Application
- {
- public App()
- {
- VersionControl.GetSettingFromIni();
- Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
-
- ServiceLocatorConfigurer.Instance.Configure();
- _logger = ServiceLocator.Current.GetInstance();
- _copterManager = ServiceLocator.Current.GetInstance();
- _formationController = ServiceLocator.Current.GetInstance();
- _mapManager = ServiceLocator.Current.GetInstance();
-
- AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
- {
- var simpleName = new AssemblyName(e.Name).Name;
- if (simpleName.EndsWith(".resources"))
- {
- return null;
- }
- return LoadAssembly(simpleName);
- };
- this.DispatcherUnhandledException += (s, e) =>
- {
- _logger.Log(e.Exception);
- // await _formationController.AllStop();
- TcpServerConnectionManager.Instance.StopListening();
- UdpServerConnectionManager.Instance.StopReceiving();
- };
- this.Exit += (s, e) =>
- {
- try
- {
- // TcpServerConnectionManager.Instance.StopListening();
- UdpServerConnectionManager.Instance.StopReceiving();
- }
- catch (Exception ex)
- {
- // RaiseExceptionThrown(ex);
- }
-
- };
- //new Test().Prepare().Run();
-
-
- }
-
- private ILogger _logger;
- private CopterManager _copterManager;
- private FormationController _formationController;
- private MapManager _mapManager;
-
- private Assembly LoadAssembly(string simpleName)
- {
- String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll";
- using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
- {
- Byte[] assemblyData = new Byte[stream.Length];
- stream.Read(assemblyData, 0, assemblyData.Length);
- return Assembly.Load(assemblyData);
- }
- }
-
- protected override void OnStartup(StartupEventArgs e)
- {
- base.OnStartup(e);
-
- var md = Resources.MergedDictionaries;
- // md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") });
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") });
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") });
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") });
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") });
-
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") });
-
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") });
- md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") });
- /*
- new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger)
- .CheckAsync(ver =>
- {
- var currentVersion = this.GetType().Assembly.GetName().Version;
- if (currentVersion < ver
- && Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
- {
- Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe");
- this.Shutdown();
- }
- });
- */
- System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
-
- MainWindow = new MainWindow();
- MainWindow.Show();
-
-
- try
- {
- /* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好
- TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
- if (!TcpServerConnectionManager.Instance.StartListening())
- {
- Alert.Show("网络连接不正常,无法连接飞机。");
- return;
- }
- */
-
- if (VersionControl.ConType == 1)
- {
- CommModuleManager.Instance.UseTransModule = false;
- UdpServerConnectionManager.Instance.ExceptionThrown += (sender, e1) =>
- {
- _logger.Log(e1.Exception);
- };
- UdpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
- UdpServerConnectionManager.Instance.StartReceiving();
- }
- else
- {
- CommModuleManager.Instance.UseTransModule = true;
- //初始化地面站连接
- CommModuleManager.Instance.CommunicationReceived += CommtionReceivedCopterInfo;
- CommModuleManager.Instance.CommunicationCopterDisconnect += CommCopterDisconnect;
- CommModuleManager.Instance.CommunicationConnected += CommCopterconnected;
- CommModuleManager.Instance.Connect();
- }
-
- }
- catch (Exception ex)
- {
- Alert.Show("网络连接不正常,无法连接飞机。");
- return;
- }
- }
-
- protected override void OnExit(ExitEventArgs e)
- {
- CommModuleManager.Instance.CloseConnection();
- base.OnExit(e);
- }
-
-
- private void Copter_TextReceived(object sender, MessageCreatedEventArgs e)
- {
- _logger.Log(e.Message );
- }
- //wifi模式添加飞机
- private async Task AddOrUpdateCopter(string ip, IConnection Connection)
- {
- var copters = _copterManager.Copters;
- var copterStatus = _copterManager.CopterStatus;
-
- string[] iparr = ip.Split('.');
- string vIPID = String.Format("{0:D3}", int.Parse(iparr[2])) + String.Format("{0:D3}", int.Parse(iparr[3]));
-
- var copter = copters.FirstOrDefault(c => c.Id == vIPID);
- if (copter == null)
- {
- if (!_copterManager.EnAddCopter_Real())
- {
- UdpServerConnectionManager.Instance.DeleteConnections(ip);
- }
- else
- {
- await Dispatcher.BeginInvoke(new Action(() =>
- {
-
-
- copter = new Copter(Connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
- {
- Id = vIPID,
- Name = vIPID // ip.Substring(ip.LastIndexOf('.') + 1)
- };
- int _index;
- _index = copters.AddCopter(copter, _copterManager.SortType);
- copterStatus.Insert(_index, false);
- copter.TextReceived += Copter_TextReceived;
-
- }));
- }
- }
- else
- {
- copter.Connection = Connection;
- }
- if (copter!=null)
- await copter.ConnectAsync().ConfigureAwait(false);
- }
-
- private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e)
- {
- await AddOrUpdateCopter(e.RemoteAddress, e.Connection);
- }
-
- private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e)
- {
- await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion);
- //await TaskUtils.CompletedTask;
- }
-
- private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e)
- {
- await DisconnectCopter(e.Id);
- }
-
- private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e)
- {
- await AddCommCopter(e.Id);
- }
-
- private async Task DisconnectCopter(int id)
- {
- var copters = _copterManager.Copters;
- var copter = copters.FirstOrDefault(c => c.Id == id.ToString());
- if (copter != null)
- {
- if (copter is PLCopter)
- {
- PLCopter plcopter = (PLCopter)copter;
- plcopter.CommModuleConnected = false;
- }
- }
- await TaskUtils.CompletedTask;
- }
-
-
- private static readonly object locker = new object();
- private async Task AddCommCopter(int id)
- {
- await Dispatcher.BeginInvoke(new Action(() =>
- {
- lock(locker)
- {
- var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
- if ((copter != null)&&(copter is FakeCopter))
- {
- _copterManager.Copters.Remove(copter);
- copter = null;
- }
-
-
- if (copter == null)
- {
- if (_copterManager.EnAddCopter_Real())
- {
-
- var copterStatus = _copterManager.CopterStatus;
- var connection = new CommConnection();
- copter = new Copter(connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
- {
- Id = id.ToString(),
- Name = id.ToString(),
- };
- copter.VirtualId = 0;
- int _index;
- _index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType);
- copterStatus.Insert(_index, false);
- copter.TextReceived += Copter_TextReceived;
- }
- }
- }
- }));
- }
-
- private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion)
- {
- await AddCommCopter(id);
- lock (locker)
- {
- var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
- if (copter!= null && copter is PLCopter)
- {
- PLCopter plcopter = (PLCopter)copter;
- if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true;
- plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion);
- plcopter.CommModuleConnected = true;
- }
- }
-
-
- }
- }
-}
+using Plane.Communication;
+using Plane.Copters;
+using Plane.FormationCreator.Formation;
+using Plane.Logging;
+using Plane.Windows;
+using Plane.Windows.Messages;
+using GalaSoft.MvvmLight.Ioc;
+using Microsoft.Practices.ServiceLocation;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+
+using Plane.FormationCreator.Util;
+using Plane.CommunicationManagement;
+
+namespace Plane.FormationCreator
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ public App()
+ {
+ VersionControl.GetSettingFromIni();
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
+
+ ServiceLocatorConfigurer.Instance.Configure();
+ _logger = ServiceLocator.Current.GetInstance();
+ _copterManager = ServiceLocator.Current.GetInstance();
+ _formationController = ServiceLocator.Current.GetInstance();
+ _mapManager = ServiceLocator.Current.GetInstance();
+
+ AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
+ {
+ var simpleName = new AssemblyName(e.Name).Name;
+ if (simpleName.EndsWith(".resources"))
+ {
+ return null;
+ }
+ return LoadAssembly(simpleName);
+ };
+ this.DispatcherUnhandledException += (s, e) =>
+ {
+ _logger.Log(e.Exception);
+ // await _formationController.AllStop();
+ TcpServerConnectionManager.Instance.StopListening();
+ UdpServerConnectionManager.Instance.StopReceiving();
+ };
+ this.Exit += (s, e) =>
+ {
+ try
+ {
+ // TcpServerConnectionManager.Instance.StopListening();
+ UdpServerConnectionManager.Instance.StopReceiving();
+ }
+ catch (Exception ex)
+ {
+ // RaiseExceptionThrown(ex);
+ }
+
+ };
+ //new Test().Prepare().Run();
+
+
+ }
+
+ private ILogger _logger;
+ private CopterManager _copterManager;
+ private FormationController _formationController;
+ private MapManager _mapManager;
+
+ private Assembly LoadAssembly(string simpleName)
+ {
+ String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll";
+ using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
+ {
+ Byte[] assemblyData = new Byte[stream.Length];
+ stream.Read(assemblyData, 0, assemblyData.Length);
+ return Assembly.Load(assemblyData);
+ }
+ }
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ var md = Resources.MergedDictionaries;
+ // md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") });
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") });
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") });
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") });
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") });
+
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") });
+
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") });
+ md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") });
+ /*
+ new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger)
+ .CheckAsync(ver =>
+ {
+ var currentVersion = this.GetType().Assembly.GetName().Version;
+ if (currentVersion < ver
+ && Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe");
+ this.Shutdown();
+ }
+ });
+ */
+ System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
+
+ MainWindow = new MainWindow();
+ MainWindow.Show();
+
+
+ try
+ {
+ /* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好
+ TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
+ if (!TcpServerConnectionManager.Instance.StartListening())
+ {
+ Alert.Show("网络连接不正常,无法连接飞机。");
+ return;
+ }
+ */
+
+ if (VersionControl.ConType == 1)
+ {
+ CommModuleManager.Instance.UseTransModule = false;
+ UdpServerConnectionManager.Instance.ExceptionThrown += (sender, e1) =>
+ {
+ _logger.Log(e1.Exception);
+ };
+ UdpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
+ UdpServerConnectionManager.Instance.StartReceiving();
+ }
+ else
+ {
+ CommModuleManager.Instance.UseTransModule = true;
+ //初始化地面站连接
+ CommModuleManager.Instance.CommunicationReceived += CommtionReceivedCopterInfo;
+ CommModuleManager.Instance.CommunicationCopterDisconnect += CommCopterDisconnect;
+ CommModuleManager.Instance.CommunicationConnected += CommCopterconnected;
+ CommModuleManager.Instance.Connect();
+ }
+
+ }
+ catch (Exception ex)
+ {
+ Alert.Show("网络连接不正常,无法连接飞机。");
+ return;
+ }
+ }
+
+ protected override void OnExit(ExitEventArgs e)
+ {
+ CommModuleManager.Instance.CloseConnection();
+ base.OnExit(e);
+ }
+
+
+ private void Copter_TextReceived(object sender, MessageCreatedEventArgs e)
+ {
+ _logger.Log(e.Message );
+ }
+ //wifi模式添加飞机
+ private async Task AddOrUpdateCopter(string ip, IConnection Connection)
+ {
+ var copters = _copterManager.Copters;
+ var copterStatus = _copterManager.CopterStatus;
+
+ string[] iparr = ip.Split('.');
+ string vIPID = String.Format("{0:D3}", int.Parse(iparr[2])) + String.Format("{0:D3}", int.Parse(iparr[3]));
+
+ var copter = copters.FirstOrDefault(c => c.Id == vIPID);
+ if (copter == null)
+ {
+ if (!_copterManager.EnAddCopter_Real())
+ {
+ UdpServerConnectionManager.Instance.DeleteConnections(ip);
+ }
+ else
+ {
+ await Dispatcher.BeginInvoke(new Action(() =>
+ {
+
+
+ copter = new Copter(Connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
+ {
+ Id = vIPID,
+ Name = vIPID // ip.Substring(ip.LastIndexOf('.') + 1)
+ };
+ int _index;
+ _index = copters.AddCopter(copter, _copterManager.SortType);
+ copterStatus.Insert(_index, false);
+ copter.TextReceived += Copter_TextReceived;
+
+ }));
+ }
+ }
+ else
+ {
+ copter.Connection = Connection;
+ }
+ if (copter!=null)
+ await copter.ConnectAsync().ConfigureAwait(false);
+ }
+
+ private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e)
+ {
+ await AddOrUpdateCopter(e.RemoteAddress, e.Connection);
+ }
+
+ private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e)
+ {
+ await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion);
+ //await TaskUtils.CompletedTask;
+ }
+
+ private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e)
+ {
+ await DisconnectCopter(e.Id);
+ }
+
+ private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e)
+ {
+ await AddCommCopter(e.Id);
+ }
+
+ private async Task DisconnectCopter(int id)
+ {
+ var copters = _copterManager.Copters;
+ var copter = copters.FirstOrDefault(c => c.Id == id.ToString());
+ if (copter != null)
+ {
+ if (copter is PLCopter)
+ {
+ PLCopter plcopter = (PLCopter)copter;
+ plcopter.CommModuleConnected = false;
+ }
+ }
+ await TaskUtils.CompletedTask;
+ }
+
+
+ private static readonly object locker = new object();
+ private async Task AddCommCopter(int id)
+ {
+ await Dispatcher.BeginInvoke(new Action(() =>
+ {
+ lock(locker)
+ {
+ var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
+ if ((copter != null)&&(copter is FakeCopter))
+ {
+ _copterManager.Copters.Remove(copter);
+ copter = null;
+ }
+
+
+ if (copter == null)
+ {
+ if (_copterManager.EnAddCopter_Real())
+ {
+
+ var copterStatus = _copterManager.CopterStatus;
+ var connection = new CommConnection();
+ copter = new Copter(connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
+ {
+ Id = id.ToString(),
+ Name = id.ToString(),
+ };
+ copter.VirtualId = 0;
+ int _index;
+ _index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType);
+ copterStatus.Insert(_index, false);
+ copter.TextReceived += Copter_TextReceived;
+ }
+ }
+ }
+ }));
+ }
+
+ private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion)
+ {
+ await AddCommCopter(id);
+ lock (locker)
+ {
+ var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
+ if (copter!= null && copter is PLCopter)
+ {
+ PLCopter plcopter = (PLCopter)copter;
+ if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true;
+ plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion);
+ plcopter.CommModuleConnected = true;
+ }
+ }
+
+
+ }
+ }
+}
diff --git a/Plane.FormationCreator/Formation/CopterManager.cs b/Plane.FormationCreator/Formation/CopterManager.cs
index 13a7818..8d05899 100644
--- a/Plane.FormationCreator/Formation/CopterManager.cs
+++ b/Plane.FormationCreator/Formation/CopterManager.cs
@@ -1,870 +1,870 @@
-using Plane.Copters;
-using GalaSoft.MvvmLight;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Plane.FormationCreator.Util;
-using Microsoft.Practices.ServiceLocation;
-using Plane.FormationCreator.ViewModels;
-using System.Threading;
-using Plane.Communication;
-using Plane.Util;
-using System.Windows;
-using Plane.Windows.Messages;
-using System.Reflection;
-using System.IO;
-
-namespace Plane.FormationCreator.Formation
-{
-
-
- public class CopterCollection : ObservableCollection
- {
- //软件过期时间---过期将无法添加飞机,并自动退出
- public static DateTime Expire_App = DateTime.Parse("2023-12-31");
- //超级用户过期时间--过期将无法使用内置超级用户登录
- public static DateTime Expire_SuperUser = Expire_App;
- //允许飞行的飞机数量
- public int EnCopterNumber = 0;
- //允许模拟的飞机数量
- public int EnVCopterNumber = 0;
-
-
-
- ///
- /// 实现排序插入
- ///
- ///
- public int AddCopter(ICopter entityObject, CopterManager.CopterSortType vSortType)
- {
-
- //新增飞机区域限制:内蒙
-// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756
-// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856)
-// return 0;
-
- if (DateTime.UtcNow > Expire_App)
- {
- throw new NotImplementedException();
- }
-
-/*
- if (this.Count >= VersionControl.CopterUpperLimit)
- {
- return 0;
- }
-
-
- //网络登录限制
- // if (!VersionControl.IsFullVersion)
- {
- if (entityObject is FakeCopter)
- {
- if (this.Count >= EnVCopterNumber)
- {
- return 0;
- }
-
- }
- else
- {
- if (this.Count >= EnCopterNumber)
- {
- return 0;
- }
-
- }
- }
-
- */
-
-
-
-
- int _index = 0;
- if (this.Count == 0)
- {
- Add(entityObject);
- _index = 0;
- }
- else
- {
- //删除重复
- // if (entityObject is PLCopter)
- // {
- for (int i = 0; i < this.Count; i++)
- {
- if (vSortType == CopterManager.CopterSortType.ByID)
- {
- if (int.Parse(this[i].Id) == int.Parse(entityObject.Id))
- {
- if (this[i] is FakeCopter)
- Remove(this[i]);
- else
- {
- Message.Show($"无法加入飞机,已有重复的真实飞机ID[{this[i].Id}]!");
- return -1;
- }
-
- }
- }else
- {
-
- if ((entityObject.VirtualId!=0) &&(this[i].VirtualId == entityObject.VirtualId))
- {
- if (this[i] is FakeCopter)
- Remove(this[i]);
- else
- {
- Message.Show($"无法加入飞机,已有重复的真实飞机ID[{this[i].VirtualId}]!");
- return -1;
- }
-
- }
-
- }
-
- }
- // }
-
-
- bool isInsret = false;
- for (int i = 0; i < this.Count; i++)
- {
- //按ID排序插入
- if (vSortType == CopterManager.CopterSortType.ByID)
- {
- if (int.Parse(this[i].Id) > int.Parse(entityObject.Id))
- {
- InsertItem(i, entityObject);
- isInsret = true;
- _index = i;
- break;
- }
- }
- else
- //按VID排序插入
- {
- if (this[i].VirtualId > entityObject.VirtualId)
- {
-
- InsertItem(i, entityObject);
- isInsret = true;
- _index = i;
- break;
-
- }
- }
- }
- if (!isInsret)
- {
- Add(entityObject);
- _index = this.Count()-1 ;
- }
-
-
- }
-
- entityObject.DisplayID = ((vSortType == CopterManager.CopterSortType.ByID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
- entityObject.DisplayVirtualId = ((vSortType == CopterManager.CopterSortType.ByVID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
-
- return _index;
- }
- }
-
-
- public class CopterManager : ObservableObject
- {
-
- const string LoginPage = "checkforapp.php";
- // const string supername = "admin";
- // const string superpass = "admin0622";
- const string supername = "user";
- const string superpass = "123456";
-
- const string TEMP_MISSIONFILE = @".\gcs.dat";
- //飞控版本控制
- public int FC_VER_NO = 1;//"4.1.2" 这个版本以前版本灯光比较少no=1 //"4.5"以后no=2;
- //飞控版本控制
- public string FC_VER_STRING = "4.1.2以前"; //
-
-
-
-
-
- //用户级别
- const int LEVEL_NORMAL = 1;
- const int LEVEL_ADMIN = 0;
-
- //飞机默认颜色
- public const string CopterDefaultColor= "1E90FF";
- //开始起飞颜色//解锁起飞用暗紫色
- public const string CopterTakeoffColor = "FF00FF";
- //飞行中颜色
- public const string CopterFlyingColor = "32CD32";
-
-
- private string superDispname = "超级用户";
- public CopterManager()
- {
- AppEx.Current.AppModeChanged += (sender, e) =>
- {
- RaisePropertyChanged(nameof(Copters));
- };
- App.Current.Exit += (sender, e) =>
- {
- Task.WhenAll(Copters.Select(c => c.DisconnectAsync()));
- };
-
-
- Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles();
- string readvalue = "";
- int intTemp;
- readvalue = inifilse.IniReadvalue("Default", "FC_VER_NO");
- if (readvalue != "" && int.TryParse(readvalue, out intTemp))
- FC_VER_NO = int.Parse(readvalue);
-
-
- readvalue = inifilse.IniReadvalue("Default", "FC_VER_STRING");
- if (readvalue != "" )
- FC_VER_STRING =readvalue;
- }
-
- public List ShowCopter = new List();
-
-
- //3维视图显示比例,有些大的图案显示不出来可以缩小
- private float _scale3d = 1.0f;
- public float scale3d
- {
- get { return _scale3d; }
- set { Set(nameof(scale3d), ref _scale3d, value); }
- }
-
- public delegate void NetStatusChanged(bool Logined, string status);
- public event NetStatusChanged netStatusChanged;
-
- public CopterCollection Copters { get;} = new CopterCollection();
-
- //标记某飞机是否需要跳过
- public ArrayList CopterStatus = new ArrayList();
- //public ObservableCollection Copters
- //{
- // get
- // {
- // switch (AppEx.Instance.CurrentMode)
- // {
- // case AppMode.ControllingCopters:
- // default:
- // return CoptersForControlling;
- // case AppMode.PreparedForRunningTasks:
- // case AppMode.ModifyingTask:
- // return CoptersForModifyingTask;
- // case AppMode.RunningTasks:
- // throw new NotImplementedException();
- // }
- // }
- //}
-
-
-
- private string _Loginstate = "未登录";
- public string Loginstate
- {
- get { return _Loginstate; }
- set
- {
- Set(nameof(Loginstate), ref _Loginstate, value);
- netStatusChanged(Logined,Loginstate);
- }
- }
- public enum CopterSortType { ByID, ByVID, ByVIDShowAll };
- //排序类型
- private CopterSortType _SortType =0;
- public CopterSortType SortType
- {
- get { return _SortType; }
- set
- {
- Set(nameof(SortType), ref _SortType, value);
- switch (value)
- {
- case CopterSortType.ByID:
- sortbyid();
- break;
- case CopterSortType.ByVID:
- sortbyvid();
- break;
- case CopterSortType.ByVIDShowAll:
- sortbyvid(true);
- break;
- default:
- sortbyid();
- break;
- }
-
-
- }
- }
-
- public void ReSort()
- {
- SortType = _SortType;
-
-
- }
-
-
-
- private int _EnCopterNumber = 0;
- public int EnCopterNumber
- {
- get { return _EnCopterNumber; }
- set
- {
- Set(nameof(EnCopterNumber), ref _EnCopterNumber, value);
- Copters.EnCopterNumber = EnCopterNumber;
- }
- }
-
- private int _EnVCopterNumber = 0;
- public int EnVCopterNumber
- {
- get { return _EnVCopterNumber; }
- set
- {
- Set(nameof(EnVCopterNumber), ref _EnVCopterNumber, value);
- Copters.EnVCopterNumber = EnVCopterNumber;
- }
- }
-
- private bool _Logined = false;
- public bool Logined
- {
- get { return _Logined; }
- set
- {
- Set(nameof(Logined), ref _Logined, value);
- netStatusChanged(Logined, Loginstate);
- }
- }
-
- private string _UserName = "";
- private string _UserDisplayName = "";
- public string RTK_URL = "";
-
- public void NetLogined(string UserName,string UserDisplayName,int vEnCopterNumber,int vEnVCopterNumber,int userlever=1)
- {
- _UserName = UserName;
- EnCopterNumber = vEnCopterNumber;
- EnVCopterNumber = vEnVCopterNumber;
- _UserDisplayName = UserDisplayName;
- string dis_EnCopterNumber ="<"+ EnCopterNumber.ToString()+">";
- string dis_EnVCopterNumber = "<" + EnVCopterNumber.ToString() + ">";
- if (EnCopterNumber == -1) dis_EnCopterNumber = "<无限>";
- if (EnVCopterNumber == -1) dis_EnVCopterNumber = "<无限>";
- Loginstate ="["+ UserDisplayName + "]已登录,模拟飞机:"+ dis_EnVCopterNumber + "架,真实飞机:"+ dis_EnCopterNumber + "架";
- Logined = true;
- VersionControl.SetUserLever(userlever);
- if (UserName != supername)
- {
- Task.Run(async () =>
- {
- while (Logined)
- {
- NetActivePost();
- //30秒一次保持活跃
- await Task.Delay(30 * 1000).ConfigureAwait(false);
- }
- }).ConfigureAwait(false);
- }
- }
- public void GetRTKURL()
- {
- if (_UserName == "") return;
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=GetRTK");
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, ResultCallBack_rtk, out errorstr);
- }
-
- public void ReleaseRTKURL()
- {
- if (_UserName == "") return;
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=RelRTK");
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
-
- }
-
-
- private void NetActivePost()
- {
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL+ LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&type=Active");
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, null,out errorstr);
- }
-
- private void NetLogoutPost()
- {
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=Logout");
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
- }
- public void NetLogout()
- {
- if (Logined)
- NetLogoutPost();
-
-
- Logined = false;
- EnCopterNumber = 0;
- EnVCopterNumber = 0;
- _UserDisplayName = "";
- _UserName = "";
- VersionControl.SetUserLever(LEVEL_NORMAL);
- Loginstate = "未登录";
- }
-
- //本地飞行任务日志 提交到服务器
- public void Net_PostTempMission()
- {
- string filePath = TEMP_MISSIONFILE;
- string[] Missionstrs = { };
- try
- {
- if (File.Exists(filePath))
- {
- Missionstrs = File.ReadAllLines(filePath);
- List Mlist = new List(Missionstrs);
- string upstr = "";
- foreach (var mstr in Mlist)
- upstr = upstr + mstr + "|";
- Net_PostTempMission(upstr);
- Mlist.Clear();
- File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
- }
-
- }
- catch (Exception ex)
- {
-
- }
-
- }
-
- //保存飞行任务日志临时到本地
- public void Net_WriteTempMission(DateTime MissionTime, double OriginLng, double OriginLat)
- {
- string filePath = TEMP_MISSIONFILE;
- string[] Missionstrs = { };
- try
- {
- if (File.Exists(filePath))
- Missionstrs = File.ReadAllLines(filePath);
- List Mlist = new List(Missionstrs);
- Mlist.Add(MissionTime.ToString() + ";" + OriginLng.ToString() + ";" + OriginLat.ToString() + ";" + Copters.Count().ToString()
- + ";" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
-
- File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
-
- }
- catch (Exception ex)
- {
-
- }
- }
-
- //提交飞行记录
- public void Net_LogStartMission(DateTime MissionTime,double OriginLng, double OriginLat)
- {
- Net_WriteTempMission(MissionTime, OriginLng, OriginLat);
- Net_PostStartMission(MissionTime, OriginLng, OriginLat);
- }
-
-
- //提交飞行记录
- public void Net_PostStartMission(DateTime MissionTime, double OriginLng, double OriginLat)
- {
-
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=StartMission");
- sbUrl.Append("&mtime=" + MissionTime.ToString());
- sbUrl.Append("&orgLng=" + OriginLng.ToString());
- sbUrl.Append("&orgLat=" + OriginLat.ToString());
- sbUrl.Append("&coptercount=" + Copters.Count().ToString());
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
- }
-
- //提交本地飞行记录
- public void Net_PostTempMission(string missstr)
- {
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + _UserName);
- sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=TempMission");
- sbUrl.Append("&Mission=" + missstr);
- String strUrl = sbUrl.ToString();
- string errorstr;
- new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
- }
-
-
-
-
-
-
-
-
-
-
-
- private string tempuser;
- private string tempPassword;
- private bool tempSavePassword;
-
- //在这个方法里面接收回调的返回信息
- private void DataResultCallBack(string data,bool haveerror)
- {
- if (haveerror)
- {
- Loginstate = "登录失败,"+ data;
- return;
- }
- if (data == "")
- {
- Loginstate = "登录失败,请检查网络连接";
- return;
- }
- string[] arr = data.Split(';');
- string loginret = arr[0];
- if (loginret == "Login ok")
- {
- if (arr.Length!= 5)
- {
- Alert.Show("系统版本不正确!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
- return;
- }
-
-
- string UserDisplayName = arr[1];
- int vEnCopterNumber = int.Parse(arr[2]);
- int vEnVCopterNumber = int.Parse(arr[3]);
- int userlevel = int.Parse(arr[4]);
- NetLogined(tempuser, UserDisplayName, vEnCopterNumber, vEnVCopterNumber, userlevel);
- VersionControl.SaveLogininfoToIni(tempuser, tempPassword, tempSavePassword);
- Net_PostTempMission();
- //MessageBox.Show(UserDisplayName + " 登录成功!", "登录提示");
- }
- else
- if (loginret == "username error")
- {
- NetLogout();
- Alert.Show("账号错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- else
- if (loginret == "password error")
- {
- NetLogout();
- Alert.Show("密码错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- else
- if (loginret == "replogin error")
- {
- NetLogout();
- Alert.Show("该账号已在其他地方登录!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
- }else
- {
- NetLogout();
- Alert.Show("登录失败:"+ data, "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- public void NetLogoin(string username,string password,bool savepassword)
- {
- Logined = false;
- //超级用户,无限制
-
- if ((username== supername) && (password== superpass) &&(DateTime.UtcNow < CopterCollection.Expire_SuperUser) )
- {
- // NetLogined(supername, superDispname, -1, -1, LEVEL_ADMIN);
- NetLogined(supername, superDispname,6, 300, LEVEL_NORMAL);
- VersionControl.SaveLogininfoToIni(supername, superpass, savepassword); //超级密码是否保存---不要就不保存
- return;
- }
-
- tempuser = username;
- tempPassword = password;
- tempSavePassword = savepassword;
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + username);
- sbUrl.Append("&" + "password=" + password);
- sbUrl.Append("&type=Login");
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
- String strUrl = sbUrl.ToString();
- string errorstr;
- if (new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack, out errorstr))
- Loginstate = "登录中...";
- else Loginstate = "登录失败,"+ errorstr;
- }
-
- private void ResultCallBack_rtk(string data, bool haveerror)
- {
- if (haveerror)
- {
- MessageBox.Show("获取RTK账号失败," + data, "错误");
- return;
- }
- if (data == "")
- {
- MessageBox.Show("获取RTK账号失败,请检查网络", "错误");
- return;
- }
-
- string[] arr = data.Split(';');
- string loginret = arr[0];
- if (loginret == "ok")
- {
- RTK_URL = arr[1];
- }
- else
- MessageBox.Show(loginret, "错误");
-
- }
-
- //在这个方法里面接收回调的返回信息
- private void DataResultCallBack_changepassword(string data, bool haveerror)
- {
- if (haveerror)
- {
- MessageBox.Show("更改失败," + data, "提示");
- return;
- }
- if (data == "")
- {
- MessageBox.Show("更改失败,请检查网络", "提示");
- return;
- }
- string[] arr = data.Split(';');
- string loginret = arr[0];
- if (loginret == "chpassword ok")
- {
- MessageBox.Show( "密码更改成功!", "提示");
- }
- else
- if (loginret == "username error")
- {
-
- MessageBox.Show("账号错误!", "提示");
- }
- else
- if (loginret == "password error")
- {
- MessageBox.Show("原密码错误!", "提示");
- }
-
- }
-
- public void NetChangePassword(string username, string oldpassword, string newpassword)
- {
- tempuser = username;
- tempPassword = oldpassword;
- // 发送请求
- StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
- sbUrl.Append(VersionControl.ServerURL + LoginPage);
- sbUrl.Append("?");
- sbUrl.Append("username=" + username);
- sbUrl.Append("&password=" + oldpassword);
- sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
- sbUrl.Append("&type=Chpassword");
- sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
- sbUrl.Append("&newpassword=" + newpassword);
- String strUrl = sbUrl.ToString();
- string errorstr;
- if (!new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack_changepassword, out errorstr))
- MessageBox.Show("更改失败," + errorstr, "提示");
- }
-
- public bool shiftkeydown;
- public IEnumerable SelectedCopters { get { return _selectedCoptersGetter().Cast(); } }
-
- ///
- /// 注意:为避免多线程操作出问题,每次使用此属性时都会新建一个 List!
- ///
- public IEnumerable AcceptingControlCopters { get { return SelectedCopters.ToList(); } }
- private int _SeletedCopterCount;
- public int SeletedCopterCount
- {
- get { return _SeletedCopterCount; }
- set { Set(nameof(SeletedCopterCount), ref _SeletedCopterCount, value); }
- }
-
- private Func _selectedCoptersGetter;
-
- private Action _selectCopterAction;
-
- public void SetSelectionDelegates(Func selectedCoptersGetter, Action selectCopterAction)
- {
- _selectedCoptersGetter = selectedCoptersGetter;
- _selectCopterAction = selectCopterAction;
- }
-
- public event EventHandler SelectedCoptersChanged;
-
- public void RaiseSelectedCoptersChanged(IEnumerable addedCopters, IEnumerable removedCopters)
- {
- SelectedCoptersChanged?.Invoke(this, new SelectedCoptersChangedEventArgs { AddedCopters = addedCopters, RemovedCopters = removedCopters });
- SeletedCopterCount = SelectedCopters.Count();
- }
-
-
-
- public async Task ClearCopters()
- {
- foreach (var copter in Copters)
- {
- await copter.DisconnectAsync();
- }
- await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
- Copters.Clear();
- CopterStatus.Clear();
- //wifi
- if (VersionControl.ConType==1)
- UdpServerConnectionManager.Instance.ClearConnections();
- }
-
-
-
- public async Task DelSelCopters()
- {
- if (AcceptingControlCopters == null || AcceptingControlCopters.Count() ==0)
- {
- return;
- }
-
- foreach (var copter in AcceptingControlCopters)
- {
- await copter.DisconnectAsync();
-
- if(Copters.Contains(copter))
- {
- Copters.Remove(copter);
- }
-
- //标记是否跳过,这个已经没用了,随便删除第一个
- CopterStatus.RemoveAt(0);
-
-
- }
- await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
-
- //wifi
- // if (VersionControl.ConType == 1)
- // UdpServerConnectionManager.Instance.ClearConnections();
- }
-
-
-
-
- public bool EnAddCopter_Real()
- {
- if (EnCopterNumber == -1) return true;
- else
- return Copters.Count < EnCopterNumber;
- }
-
- public bool EnAddCopter_Fake()
- {
- if (EnVCopterNumber == -1) return true;
- else
- return Copters.Count < EnVCopterNumber;
- }
-
-
- ///
- /// 选择飞机
- ///
- /// Null表示清除所有选择
- public void Select(ICopter copter)
- {
- _selectCopterAction(copter);
- }
- ///
- /// 按VID重新排序飞机
- ///
- public void sortbyvid(bool displayid=false)
- {
- List tempCopters = new List();
- tempCopters.AddRange(Copters);
- Copters.Clear();
- foreach (var copter in tempCopters)
- Copters.AddCopter(copter,SortType);
- }
- ///
- /// 按原始ID重新排序飞机
- ///
- public void sortbyid()
- {
- List tempCopters = new List();
- tempCopters.AddRange(Copters);
- Copters.Clear();
- foreach (var copter in tempCopters)
- Copters.AddCopter(copter,SortType);
-
- }
-
- }
-
- public class SelectedCoptersChangedEventArgs : EventArgs
- {
- public IEnumerable AddedCopters { get; set; }
- public IEnumerable RemovedCopters { get; set; }
- }
-}
+using Plane.Copters;
+using GalaSoft.MvvmLight;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Plane.FormationCreator.Util;
+using Microsoft.Practices.ServiceLocation;
+using Plane.FormationCreator.ViewModels;
+using System.Threading;
+using Plane.Communication;
+using Plane.Util;
+using System.Windows;
+using Plane.Windows.Messages;
+using System.Reflection;
+using System.IO;
+
+namespace Plane.FormationCreator.Formation
+{
+
+
+ public class CopterCollection : ObservableCollection
+ {
+ //软件过期时间---过期将无法添加飞机,并自动退出
+ public static DateTime Expire_App = DateTime.Parse("2024-12-31");
+ //超级用户过期时间--过期将无法使用内置超级用户登录
+ public static DateTime Expire_SuperUser = Expire_App;
+ //允许飞行的飞机数量
+ public int EnCopterNumber = 0;
+ //允许模拟的飞机数量
+ public int EnVCopterNumber = 0;
+
+
+
+ ///
+ /// 实现排序插入
+ ///
+ ///
+ public int AddCopter(ICopter entityObject, CopterManager.CopterSortType vSortType)
+ {
+
+ //新增飞机区域限制:内蒙
+// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756
+// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856)
+// return 0;
+
+ if (DateTime.UtcNow > Expire_App)
+ {
+ throw new NotImplementedException();
+ }
+
+/*
+ if (this.Count >= VersionControl.CopterUpperLimit)
+ {
+ return 0;
+ }
+
+
+ //网络登录限制
+ // if (!VersionControl.IsFullVersion)
+ {
+ if (entityObject is FakeCopter)
+ {
+ if (this.Count >= EnVCopterNumber)
+ {
+ return 0;
+ }
+
+ }
+ else
+ {
+ if (this.Count >= EnCopterNumber)
+ {
+ return 0;
+ }
+
+ }
+ }
+
+ */
+
+
+
+
+ int _index = 0;
+ if (this.Count == 0)
+ {
+ Add(entityObject);
+ _index = 0;
+ }
+ else
+ {
+ //删除重复
+ // if (entityObject is PLCopter)
+ // {
+ for (int i = 0; i < this.Count; i++)
+ {
+ if (vSortType == CopterManager.CopterSortType.ByID)
+ {
+ if (int.Parse(this[i].Id) == int.Parse(entityObject.Id))
+ {
+ if (this[i] is FakeCopter)
+ Remove(this[i]);
+ else
+ {
+ Message.Show($"无法加入飞机,已有重复的真实飞机ID[{this[i].Id}]!");
+ return -1;
+ }
+
+ }
+ }else
+ {
+
+ if ((entityObject.VirtualId!=0) &&(this[i].VirtualId == entityObject.VirtualId))
+ {
+ if (this[i] is FakeCopter)
+ Remove(this[i]);
+ else
+ {
+ Message.Show($"无法加入飞机,已有重复的真实飞机ID[{this[i].VirtualId}]!");
+ return -1;
+ }
+
+ }
+
+ }
+
+ }
+ // }
+
+
+ bool isInsret = false;
+ for (int i = 0; i < this.Count; i++)
+ {
+ //按ID排序插入
+ if (vSortType == CopterManager.CopterSortType.ByID)
+ {
+ if (int.Parse(this[i].Id) > int.Parse(entityObject.Id))
+ {
+ InsertItem(i, entityObject);
+ isInsret = true;
+ _index = i;
+ break;
+ }
+ }
+ else
+ //按VID排序插入
+ {
+ if (this[i].VirtualId > entityObject.VirtualId)
+ {
+
+ InsertItem(i, entityObject);
+ isInsret = true;
+ _index = i;
+ break;
+
+ }
+ }
+ }
+ if (!isInsret)
+ {
+ Add(entityObject);
+ _index = this.Count()-1 ;
+ }
+
+
+ }
+
+ entityObject.DisplayID = ((vSortType == CopterManager.CopterSortType.ByID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
+ entityObject.DisplayVirtualId = ((vSortType == CopterManager.CopterSortType.ByVID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
+
+ return _index;
+ }
+ }
+
+
+ public class CopterManager : ObservableObject
+ {
+
+ const string LoginPage = "checkforapp.php";
+ // const string supername = "admin";
+ // const string superpass = "admin0622";
+ const string supername = "user";
+ const string superpass = "123456";
+
+ const string TEMP_MISSIONFILE = @".\gcs.dat";
+ //飞控版本控制
+ public int FC_VER_NO = 1;//"4.1.2" 这个版本以前版本灯光比较少no=1 //"4.5"以后no=2;
+ //飞控版本控制
+ public string FC_VER_STRING = "4.1.2以前"; //
+
+
+
+
+
+ //用户级别
+ const int LEVEL_NORMAL = 1;
+ const int LEVEL_ADMIN = 0;
+
+ //飞机默认颜色
+ public const string CopterDefaultColor= "1E90FF";
+ //开始起飞颜色//解锁起飞用暗紫色
+ public const string CopterTakeoffColor = "FF00FF";
+ //飞行中颜色
+ public const string CopterFlyingColor = "32CD32";
+
+
+ private string superDispname = "超级用户";
+ public CopterManager()
+ {
+ AppEx.Current.AppModeChanged += (sender, e) =>
+ {
+ RaisePropertyChanged(nameof(Copters));
+ };
+ App.Current.Exit += (sender, e) =>
+ {
+ Task.WhenAll(Copters.Select(c => c.DisconnectAsync()));
+ };
+
+
+ Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles();
+ string readvalue = "";
+ int intTemp;
+ readvalue = inifilse.IniReadvalue("Default", "FC_VER_NO");
+ if (readvalue != "" && int.TryParse(readvalue, out intTemp))
+ FC_VER_NO = int.Parse(readvalue);
+
+
+ readvalue = inifilse.IniReadvalue("Default", "FC_VER_STRING");
+ if (readvalue != "" )
+ FC_VER_STRING =readvalue;
+ }
+
+ public List ShowCopter = new List();
+
+
+ //3维视图显示比例,有些大的图案显示不出来可以缩小
+ private float _scale3d = 1.0f;
+ public float scale3d
+ {
+ get { return _scale3d; }
+ set { Set(nameof(scale3d), ref _scale3d, value); }
+ }
+
+ public delegate void NetStatusChanged(bool Logined, string status);
+ public event NetStatusChanged netStatusChanged;
+
+ public CopterCollection Copters { get;} = new CopterCollection();
+
+ //标记某飞机是否需要跳过
+ public ArrayList CopterStatus = new ArrayList();
+ //public ObservableCollection Copters
+ //{
+ // get
+ // {
+ // switch (AppEx.Instance.CurrentMode)
+ // {
+ // case AppMode.ControllingCopters:
+ // default:
+ // return CoptersForControlling;
+ // case AppMode.PreparedForRunningTasks:
+ // case AppMode.ModifyingTask:
+ // return CoptersForModifyingTask;
+ // case AppMode.RunningTasks:
+ // throw new NotImplementedException();
+ // }
+ // }
+ //}
+
+
+
+ private string _Loginstate = "未登录";
+ public string Loginstate
+ {
+ get { return _Loginstate; }
+ set
+ {
+ Set(nameof(Loginstate), ref _Loginstate, value);
+ netStatusChanged(Logined,Loginstate);
+ }
+ }
+ public enum CopterSortType { ByID, ByVID, ByVIDShowAll };
+ //排序类型
+ private CopterSortType _SortType =0;
+ public CopterSortType SortType
+ {
+ get { return _SortType; }
+ set
+ {
+ Set(nameof(SortType), ref _SortType, value);
+ switch (value)
+ {
+ case CopterSortType.ByID:
+ sortbyid();
+ break;
+ case CopterSortType.ByVID:
+ sortbyvid();
+ break;
+ case CopterSortType.ByVIDShowAll:
+ sortbyvid(true);
+ break;
+ default:
+ sortbyid();
+ break;
+ }
+
+
+ }
+ }
+
+ public void ReSort()
+ {
+ SortType = _SortType;
+
+
+ }
+
+
+
+ private int _EnCopterNumber = 0;
+ public int EnCopterNumber
+ {
+ get { return _EnCopterNumber; }
+ set
+ {
+ Set(nameof(EnCopterNumber), ref _EnCopterNumber, value);
+ Copters.EnCopterNumber = EnCopterNumber;
+ }
+ }
+
+ private int _EnVCopterNumber = 0;
+ public int EnVCopterNumber
+ {
+ get { return _EnVCopterNumber; }
+ set
+ {
+ Set(nameof(EnVCopterNumber), ref _EnVCopterNumber, value);
+ Copters.EnVCopterNumber = EnVCopterNumber;
+ }
+ }
+
+ private bool _Logined = false;
+ public bool Logined
+ {
+ get { return _Logined; }
+ set
+ {
+ Set(nameof(Logined), ref _Logined, value);
+ netStatusChanged(Logined, Loginstate);
+ }
+ }
+
+ private string _UserName = "";
+ private string _UserDisplayName = "";
+ public string RTK_URL = "";
+
+ public void NetLogined(string UserName,string UserDisplayName,int vEnCopterNumber,int vEnVCopterNumber,int userlever=1)
+ {
+ _UserName = UserName;
+ EnCopterNumber = vEnCopterNumber;
+ EnVCopterNumber = vEnVCopterNumber;
+ _UserDisplayName = UserDisplayName;
+ string dis_EnCopterNumber ="<"+ EnCopterNumber.ToString()+">";
+ string dis_EnVCopterNumber = "<" + EnVCopterNumber.ToString() + ">";
+ if (EnCopterNumber == -1) dis_EnCopterNumber = "<无限>";
+ if (EnVCopterNumber == -1) dis_EnVCopterNumber = "<无限>";
+ Loginstate ="["+ UserDisplayName + "]已登录,模拟飞机:"+ dis_EnVCopterNumber + "架,真实飞机:"+ dis_EnCopterNumber + "架";
+ Logined = true;
+ VersionControl.SetUserLever(userlever);
+ if (UserName != supername)
+ {
+ Task.Run(async () =>
+ {
+ while (Logined)
+ {
+ NetActivePost();
+ //30秒一次保持活跃
+ await Task.Delay(30 * 1000).ConfigureAwait(false);
+ }
+ }).ConfigureAwait(false);
+ }
+ }
+ public void GetRTKURL()
+ {
+ if (_UserName == "") return;
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=GetRTK");
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, ResultCallBack_rtk, out errorstr);
+ }
+
+ public void ReleaseRTKURL()
+ {
+ if (_UserName == "") return;
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=RelRTK");
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
+
+ }
+
+
+ private void NetActivePost()
+ {
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL+ LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&type=Active");
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, null,out errorstr);
+ }
+
+ private void NetLogoutPost()
+ {
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=Logout");
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
+ }
+ public void NetLogout()
+ {
+ if (Logined)
+ NetLogoutPost();
+
+
+ Logined = false;
+ EnCopterNumber = 0;
+ EnVCopterNumber = 0;
+ _UserDisplayName = "";
+ _UserName = "";
+ VersionControl.SetUserLever(LEVEL_NORMAL);
+ Loginstate = "未登录";
+ }
+
+ //本地飞行任务日志 提交到服务器
+ public void Net_PostTempMission()
+ {
+ string filePath = TEMP_MISSIONFILE;
+ string[] Missionstrs = { };
+ try
+ {
+ if (File.Exists(filePath))
+ {
+ Missionstrs = File.ReadAllLines(filePath);
+ List Mlist = new List(Missionstrs);
+ string upstr = "";
+ foreach (var mstr in Mlist)
+ upstr = upstr + mstr + "|";
+ Net_PostTempMission(upstr);
+ Mlist.Clear();
+ File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
+ }
+
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ }
+
+ //保存飞行任务日志临时到本地
+ public void Net_WriteTempMission(DateTime MissionTime, double OriginLng, double OriginLat)
+ {
+ string filePath = TEMP_MISSIONFILE;
+ string[] Missionstrs = { };
+ try
+ {
+ if (File.Exists(filePath))
+ Missionstrs = File.ReadAllLines(filePath);
+ List Mlist = new List(Missionstrs);
+ Mlist.Add(MissionTime.ToString() + ";" + OriginLng.ToString() + ";" + OriginLat.ToString() + ";" + Copters.Count().ToString()
+ + ";" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+
+ File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
+
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ //提交飞行记录
+ public void Net_LogStartMission(DateTime MissionTime,double OriginLng, double OriginLat)
+ {
+ Net_WriteTempMission(MissionTime, OriginLng, OriginLat);
+ Net_PostStartMission(MissionTime, OriginLng, OriginLat);
+ }
+
+
+ //提交飞行记录
+ public void Net_PostStartMission(DateTime MissionTime, double OriginLng, double OriginLat)
+ {
+
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=StartMission");
+ sbUrl.Append("&mtime=" + MissionTime.ToString());
+ sbUrl.Append("&orgLng=" + OriginLng.ToString());
+ sbUrl.Append("&orgLat=" + OriginLat.ToString());
+ sbUrl.Append("&coptercount=" + Copters.Count().ToString());
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
+ }
+
+ //提交本地飞行记录
+ public void Net_PostTempMission(string missstr)
+ {
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + _UserName);
+ sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=TempMission");
+ sbUrl.Append("&Mission=" + missstr);
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
+ }
+
+
+
+
+
+
+
+
+
+
+
+ private string tempuser;
+ private string tempPassword;
+ private bool tempSavePassword;
+
+ //在这个方法里面接收回调的返回信息
+ private void DataResultCallBack(string data,bool haveerror)
+ {
+ if (haveerror)
+ {
+ Loginstate = "登录失败,"+ data;
+ return;
+ }
+ if (data == "")
+ {
+ Loginstate = "登录失败,请检查网络连接";
+ return;
+ }
+ string[] arr = data.Split(';');
+ string loginret = arr[0];
+ if (loginret == "Login ok")
+ {
+ if (arr.Length!= 5)
+ {
+ Alert.Show("系统版本不正确!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+
+ string UserDisplayName = arr[1];
+ int vEnCopterNumber = int.Parse(arr[2]);
+ int vEnVCopterNumber = int.Parse(arr[3]);
+ int userlevel = int.Parse(arr[4]);
+ NetLogined(tempuser, UserDisplayName, vEnCopterNumber, vEnVCopterNumber, userlevel);
+ VersionControl.SaveLogininfoToIni(tempuser, tempPassword, tempSavePassword);
+ Net_PostTempMission();
+ //MessageBox.Show(UserDisplayName + " 登录成功!", "登录提示");
+ }
+ else
+ if (loginret == "username error")
+ {
+ NetLogout();
+ Alert.Show("账号错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ else
+ if (loginret == "password error")
+ {
+ NetLogout();
+ Alert.Show("密码错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ else
+ if (loginret == "replogin error")
+ {
+ NetLogout();
+ Alert.Show("该账号已在其他地方登录!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }else
+ {
+ NetLogout();
+ Alert.Show("登录失败:"+ data, "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+ public void NetLogoin(string username,string password,bool savepassword)
+ {
+ Logined = false;
+ //超级用户,无限制
+
+ if ((username== supername) && (password== superpass) &&(DateTime.UtcNow < CopterCollection.Expire_SuperUser) )
+ {
+ // NetLogined(supername, superDispname, -1, -1, LEVEL_ADMIN);
+ NetLogined(supername, superDispname,6, 300, LEVEL_NORMAL);
+ VersionControl.SaveLogininfoToIni(supername, superpass, savepassword); //超级密码是否保存---不要就不保存
+ return;
+ }
+
+ tempuser = username;
+ tempPassword = password;
+ tempSavePassword = savepassword;
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + username);
+ sbUrl.Append("&" + "password=" + password);
+ sbUrl.Append("&type=Login");
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ if (new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack, out errorstr))
+ Loginstate = "登录中...";
+ else Loginstate = "登录失败,"+ errorstr;
+ }
+
+ private void ResultCallBack_rtk(string data, bool haveerror)
+ {
+ if (haveerror)
+ {
+ MessageBox.Show("获取RTK账号失败," + data, "错误");
+ return;
+ }
+ if (data == "")
+ {
+ MessageBox.Show("获取RTK账号失败,请检查网络", "错误");
+ return;
+ }
+
+ string[] arr = data.Split(';');
+ string loginret = arr[0];
+ if (loginret == "ok")
+ {
+ RTK_URL = arr[1];
+ }
+ else
+ MessageBox.Show(loginret, "错误");
+
+ }
+
+ //在这个方法里面接收回调的返回信息
+ private void DataResultCallBack_changepassword(string data, bool haveerror)
+ {
+ if (haveerror)
+ {
+ MessageBox.Show("更改失败," + data, "提示");
+ return;
+ }
+ if (data == "")
+ {
+ MessageBox.Show("更改失败,请检查网络", "提示");
+ return;
+ }
+ string[] arr = data.Split(';');
+ string loginret = arr[0];
+ if (loginret == "chpassword ok")
+ {
+ MessageBox.Show( "密码更改成功!", "提示");
+ }
+ else
+ if (loginret == "username error")
+ {
+
+ MessageBox.Show("账号错误!", "提示");
+ }
+ else
+ if (loginret == "password error")
+ {
+ MessageBox.Show("原密码错误!", "提示");
+ }
+
+ }
+
+ public void NetChangePassword(string username, string oldpassword, string newpassword)
+ {
+ tempuser = username;
+ tempPassword = oldpassword;
+ // 发送请求
+ StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
+ sbUrl.Append(VersionControl.ServerURL + LoginPage);
+ sbUrl.Append("?");
+ sbUrl.Append("username=" + username);
+ sbUrl.Append("&password=" + oldpassword);
+ sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
+ sbUrl.Append("&type=Chpassword");
+ sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ sbUrl.Append("&newpassword=" + newpassword);
+ String strUrl = sbUrl.ToString();
+ string errorstr;
+ if (!new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack_changepassword, out errorstr))
+ MessageBox.Show("更改失败," + errorstr, "提示");
+ }
+
+ public bool shiftkeydown;
+ public IEnumerable SelectedCopters { get { return _selectedCoptersGetter().Cast(); } }
+
+ ///
+ /// 注意:为避免多线程操作出问题,每次使用此属性时都会新建一个 List!
+ ///
+ public IEnumerable AcceptingControlCopters { get { return SelectedCopters.ToList(); } }
+ private int _SeletedCopterCount;
+ public int SeletedCopterCount
+ {
+ get { return _SeletedCopterCount; }
+ set { Set(nameof(SeletedCopterCount), ref _SeletedCopterCount, value); }
+ }
+
+ private Func _selectedCoptersGetter;
+
+ private Action _selectCopterAction;
+
+ public void SetSelectionDelegates(Func selectedCoptersGetter, Action selectCopterAction)
+ {
+ _selectedCoptersGetter = selectedCoptersGetter;
+ _selectCopterAction = selectCopterAction;
+ }
+
+ public event EventHandler SelectedCoptersChanged;
+
+ public void RaiseSelectedCoptersChanged(IEnumerable addedCopters, IEnumerable removedCopters)
+ {
+ SelectedCoptersChanged?.Invoke(this, new SelectedCoptersChangedEventArgs { AddedCopters = addedCopters, RemovedCopters = removedCopters });
+ SeletedCopterCount = SelectedCopters.Count();
+ }
+
+
+
+ public async Task ClearCopters()
+ {
+ foreach (var copter in Copters)
+ {
+ await copter.DisconnectAsync();
+ }
+ await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
+ Copters.Clear();
+ CopterStatus.Clear();
+ //wifi
+ if (VersionControl.ConType==1)
+ UdpServerConnectionManager.Instance.ClearConnections();
+ }
+
+
+
+ public async Task DelSelCopters()
+ {
+ if (AcceptingControlCopters == null || AcceptingControlCopters.Count() ==0)
+ {
+ return;
+ }
+
+ foreach (var copter in AcceptingControlCopters)
+ {
+ await copter.DisconnectAsync();
+
+ if(Copters.Contains(copter))
+ {
+ Copters.Remove(copter);
+ }
+
+ //标记是否跳过,这个已经没用了,随便删除第一个
+ CopterStatus.RemoveAt(0);
+
+
+ }
+ await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
+
+ //wifi
+ // if (VersionControl.ConType == 1)
+ // UdpServerConnectionManager.Instance.ClearConnections();
+ }
+
+
+
+
+ public bool EnAddCopter_Real()
+ {
+ if (EnCopterNumber == -1) return true;
+ else
+ return Copters.Count < EnCopterNumber;
+ }
+
+ public bool EnAddCopter_Fake()
+ {
+ if (EnVCopterNumber == -1) return true;
+ else
+ return Copters.Count < EnVCopterNumber;
+ }
+
+
+ ///
+ /// 选择飞机
+ ///
+ /// Null表示清除所有选择
+ public void Select(ICopter copter)
+ {
+ _selectCopterAction(copter);
+ }
+ ///
+ /// 按VID重新排序飞机
+ ///
+ public void sortbyvid(bool displayid=false)
+ {
+ List tempCopters = new List();
+ tempCopters.AddRange(Copters);
+ Copters.Clear();
+ foreach (var copter in tempCopters)
+ Copters.AddCopter(copter,SortType);
+ }
+ ///
+ /// 按原始ID重新排序飞机
+ ///
+ public void sortbyid()
+ {
+ List tempCopters = new List();
+ tempCopters.AddRange(Copters);
+ Copters.Clear();
+ foreach (var copter in tempCopters)
+ Copters.AddCopter(copter,SortType);
+
+ }
+
+ }
+
+ public class SelectedCoptersChangedEventArgs : EventArgs
+ {
+ public IEnumerable AddedCopters { get; set; }
+ public IEnumerable RemovedCopters { get; set; }
+ }
+}
diff --git a/Plane.FormationCreator/Formation/FlightTaskManager.cs b/Plane.FormationCreator/Formation/FlightTaskManager.cs
index 89fb93f..b1082f4 100644
--- a/Plane.FormationCreator/Formation/FlightTaskManager.cs
+++ b/Plane.FormationCreator/Formation/FlightTaskManager.cs
@@ -1,5 +1,4 @@
-using Plane.Collections;
-using Plane.Copters;
+using Plane.Copters;
using Plane.Geography;
using Plane.Windows.Messages;
using GalaSoft.MvvmLight;
@@ -10,14 +9,19 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Plane.CommunicationManagement;
+
using FlightRoute;
+using FlightRouteV2;
using System.IO;
using System.Windows.Media.Media3D;
using System.Diagnostics;
-using Plane.FormationCreator.Util;
using System.Collections;
using System.Windows;
+using System.Threading;
+using Plane.CommunicationManagement;
+using Microsoft.Practices.ServiceLocation;
+using Plane.FormationCreator.ViewModels;
+using MahApps.Metro.Controls;
namespace Plane.FormationCreator.Formation
{
@@ -27,7 +31,7 @@ namespace Plane.FormationCreator.Formation
{
LoadIni();
_copterManager = copterManager;
-
+
//AddTakeOffTask(_copterManager.Copters);
_copterManager.Copters.CollectionChanged += (sender, e) =>
@@ -66,11 +70,11 @@ namespace Plane.FormationCreator.Formation
}
}
}
- if (selectedCopter!=null)
- selectedCopter.SetShowLEDFlashAsync(1, 100);
+ if (selectedCopter != null)
+ selectedCopter.SetShowLEDFlashAsync(1, 100);
//if (selectedCopter != null)
- //selectedCopter.LEDAsync();
+ //selectedCopter.LEDAsync();
};
TaskAdded += (sender, e) =>
@@ -98,7 +102,7 @@ namespace Plane.FormationCreator.Formation
- private string _MessageText="test";
+ private string _MessageText = "test";
public string MessageText
{
get { return _MessageText; }
@@ -106,7 +110,7 @@ namespace Plane.FormationCreator.Formation
{
if (Set(nameof(MessageText), ref _MessageText, value))
{
- // _lastUpdateStatusTextTime = DateTime.Now;
+ // _lastUpdateStatusTextTime = DateTime.Now;
}
}
}
@@ -120,7 +124,7 @@ namespace Plane.FormationCreator.Formation
{
if (Set(nameof(TaskRun_2D), ref _TaskRun_2D, value))
{
-
+
}
}
}
@@ -155,7 +159,7 @@ namespace Plane.FormationCreator.Formation
public int GetTaskTime(int TaskIndex)
{
int tasktime = 0;
- if ((Tasks==null)|| TaskIndex> Tasks.Count-1) return tasktime;
+ if ((Tasks == null) || TaskIndex > Tasks.Count - 1) return tasktime;
FlightTask value = Tasks[TaskIndex];
switch (value.TaskType)
@@ -165,12 +169,12 @@ namespace Plane.FormationCreator.Formation
//降落时间计算前一个任务目标高度最高的飞机的降落时间按1.5米/秒下降
case FlightTaskType.Land:
float maxalt = 0.0f;
- for (int i = 0; i < Tasks[TaskIndex-1].SingleCopterInfos.Count; i++)
+ for (int i = 0; i < Tasks[TaskIndex - 1].SingleCopterInfos.Count; i++)
{
var copterInfo = Tasks[TaskIndex - 1].SingleCopterInfos[i];
if (maxalt < copterInfo.TargetAlt) maxalt = copterInfo.TargetAlt;
}
- tasktime =(int) Math.Round(maxalt / 1.5,0);
+ tasktime = (int)Math.Round(maxalt / 1.5, 0);
break;
}
return tasktime;
@@ -188,7 +192,7 @@ namespace Plane.FormationCreator.Formation
{
if (_SelectedTask != value)
{
- int starttime=0;
+ int starttime = 0;
if (_SelectedTask != null)
{
@@ -203,7 +207,7 @@ namespace Plane.FormationCreator.Formation
value.IsSelected = true;
value.IsRightSelected = true;
RightSelect(value);
- if (TaskState== TasksStatus.Stop)
+ if (TaskState == TasksStatus.Stop)
value.Status = FlightTaskStatus.Selected;
for (int i = 0; i < value.TaskIndex; i++)
@@ -240,7 +244,7 @@ namespace Plane.FormationCreator.Formation
}
- Message.ShowStatus($"选中 [{value.TaskIndex+1} {value.TaskCnName }] 从{str}开始执行,需{ GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务");
+ Message.ShowStatus($"选中 [{value.TaskIndex + 1} {value.TaskCnName}] 从{str}开始执行,需{GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务");
}
else Message.ShowStatus($"无任务选中");
@@ -254,18 +258,18 @@ namespace Plane.FormationCreator.Formation
{
get { return _SelectedTaskIndex; }
set { Set(nameof(SelectedTaskIndex), ref _SelectedTaskIndex, value);
- // this.SelectedTask = Tasks[value];
+ // this.SelectedTask = Tasks[value];
}
}
- // 右键单击任务,用于隐藏任务图标, added by ZJF
+ // 右键单击任务,用于隐藏任务图标, added by ZJF
private int _RightSelectedTaskIndex;
public int RightSelectedTaskIndex
{
get { return _RightSelectedTaskIndex; }
set { Set(nameof(RightSelectedTaskIndex), ref _RightSelectedTaskIndex, value); }
}
-
+
private FlightTask _CurrentRunningTask;
public FlightTask CurrentRunningTask
{
@@ -385,11 +389,11 @@ namespace Plane.FormationCreator.Formation
public event EventHandler TaskAdded;
public event EventHandler TaskDeled;
- public void RaiseTaskDeled(FlightTask vDeledTask,int vTaskIndex)
+ public void RaiseTaskDeled(FlightTask vDeledTask, int vTaskIndex)
{
try
{
- TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex= vTaskIndex });
+ TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex = vTaskIndex });
}
catch (Exception ex)
{
@@ -398,7 +402,7 @@ namespace Plane.FormationCreator.Formation
}
- public void RaiseTaskAdded(FlightTask lastTask ,FlightTask newTask)
+ public void RaiseTaskAdded(FlightTask lastTask, FlightTask newTask)
{
try
{
@@ -451,7 +455,7 @@ namespace Plane.FormationCreator.Formation
if (Tasks.Count == 0)
AddTakeOffTask(copters);
var lastTask = Tasks.LastOrDefault();
- if (SelectedTask !=null)
+ if (SelectedTask != null)
lastTask = SelectedTask;
var nullableCenter = copters.GetCenter();
if (nullableCenter == null) return;
@@ -501,8 +505,8 @@ namespace Plane.FormationCreator.Formation
newTask.SingleCopterInfos.Add(newSingleCopterInfo);
}
- int selindex = SelectedTaskIndex+1;
- Tasks.Insert(SelectedTaskIndex+1, newTask);
+ int selindex = SelectedTaskIndex + 1;
+ Tasks.Insert(SelectedTaskIndex + 1, newTask);
RaiseTaskAdded(lastTask, newTask);
SelectTask(selindex);
@@ -511,7 +515,7 @@ namespace Plane.FormationCreator.Formation
{
SelectedTask.FlytoTime = 2;
SelectedTask.LoiterTime = 2;
- foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos)
+ foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos)
{
info.TargetLat = info.Copter.Latitude;
info.TargetLng = info.Copter.Longitude;
@@ -600,10 +604,10 @@ namespace Plane.FormationCreator.Formation
}
*/
- TasksCleared?.Invoke(this, EventArgs.Empty);
- // AddTakeOffTask(_copterManager.Copters);
+ TasksCleared?.Invoke(this, EventArgs.Empty);
+ // AddTakeOffTask(_copterManager.Copters);
}
- //删除选中的任务
+ //删除选中的任务
public void DelSelectedTask()
{
if (SelectedTask == null) return;
@@ -613,12 +617,12 @@ namespace Plane.FormationCreator.Formation
// ResetTasks();
SelectedTask.SingleCopterInfos.Clear();
Tasks.RemoveAt(SelectedTaskIndex);
- RaiseTaskDeled(SelectedTask,SelectedTaskIndex);
-
+ RaiseTaskDeled(SelectedTask, SelectedTaskIndex);
+
SelectTask(selindex - 1);
-
- // SelectedTaskIndex = 0;
+
+ // SelectedTaskIndex = 0;
}
@@ -631,7 +635,7 @@ namespace Plane.FormationCreator.Formation
Pause();
int i = 0;
//等待暂停或2s超时(80*25ms)
- while ((TaskState != TasksStatus.Paused)||(i>80))
+ while ((TaskState != TasksStatus.Paused) || (i > 80))
{
await Task.Delay(25).ConfigureAwait(false);
i++;
@@ -643,8 +647,8 @@ namespace Plane.FormationCreator.Formation
CurrentRunningTask = null;
//起飞任务需要跳过
-// if (CurrentRunningTaskIndex == 0)
-// CurrentRunningTaskIndex++;
+ // if (CurrentRunningTaskIndex == 0)
+ // CurrentRunningTaskIndex++;
CurrentRunningTaskIndex++;
await RunTaskAsync();
}
@@ -654,10 +658,10 @@ namespace Plane.FormationCreator.Formation
public async Task FlyToTasks()
{
var copters = _copterManager.Copters;
- if ((SelectedTaskIndex==-1) ||(TaskState == TasksStatus.Stop))
+ if ((SelectedTaskIndex == -1) || (TaskState == TasksStatus.Stop))
return;
- int vSelectedTaskIndex= SelectedTaskIndex;
+ int vSelectedTaskIndex = SelectedTaskIndex;
Pause();
int i = 0;
@@ -676,7 +680,7 @@ namespace Plane.FormationCreator.Formation
CurrentRunningTask = null;
CurrentRunningTaskIndex = SelectedTaskIndex;
-
+
//设置所有模拟飞机的位置
for (int j = 0; j < copters.Count; j++)
@@ -705,7 +709,7 @@ namespace Plane.FormationCreator.Formation
lng = Tasks[0].SingleCopterInfos[j].TargetLng;
}
else
- {
+ {
//用前一个任务目标位置
lat = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLat;
@@ -729,10 +733,10 @@ namespace Plane.FormationCreator.Formation
- //起飞任务需要跳过
- // if (CurrentRunningTaskIndex == 0)
- // CurrentRunningTaskIndex++;
-
+ //起飞任务需要跳过
+ // if (CurrentRunningTaskIndex == 0)
+ // CurrentRunningTaskIndex++;
+
await RunTaskAsync();
}
}
@@ -765,7 +769,7 @@ namespace Plane.FormationCreator.Formation
CurrentRunningTask.Status = FlightTaskStatus.Stop;
CurrentRunningTask = null;
}
-
+
for (int i = 0; i < Tasks.Count; i++)
{
// 将起飞的阶段标志位都置位0
@@ -779,7 +783,7 @@ namespace Plane.FormationCreator.Formation
}
}
-
+
}
@@ -793,7 +797,7 @@ namespace Plane.FormationCreator.Formation
fc.SetProperties(
latitude: Tasks[0].SingleCopterInfos[j].TargetLat,
longitude: Tasks[0].SingleCopterInfos[j].TargetLng,
- altitude: 0 );
+ altitude: 0);
//设置灯光为默认颜色
fc.LEDColor = CopterManager.CopterDefaultColor;// "000000";
fc.LEDMode = 0;
@@ -822,7 +826,7 @@ namespace Plane.FormationCreator.Formation
sb.AppendLine($"{i + 1} 0 {x} {y} {z}");
//lines[i] = $"{i+1} {x} {y} {z}";
}
-
+
return sb.ToString().Trim();
}
@@ -900,15 +904,15 @@ namespace Plane.FormationCreator.Formation
Tasks.Add(newTask);
RaiseTaskAdded(lastTask, newTask);
}
-
+
}
public void ImportDlltoVCopter(string filename)
{
- Vector3[] vc;
+ FlightRoute.Vector3[] vc;
+
-
string extname = Path.GetExtension(filename);
@@ -927,8 +931,8 @@ namespace Plane.FormationCreator.Formation
Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}");
return;
}
- int id = 0;
- foreach (Vector3 item in vc)
+ int id = 0;
+ foreach (FlightRoute.Vector3 item in vc)
{
Tuple observationLatLng = null;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
@@ -954,15 +958,15 @@ namespace Plane.FormationCreator.Formation
longitude: vlongitude,
altitude: (float)item.y / 100);
id++;
-
+
}
- }
+ }
//导入外部航点
public void ImportDlltoTask(string filename)
{
- Vector3[] vc;
+ FlightRoute.Vector3[] vc;
string extname = Path.GetExtension(filename);
@@ -976,18 +980,18 @@ namespace Plane.FormationCreator.Formation
}
else return;
- if (vc.Count()!= _copterManager.Copters.Count)
+ if (vc.Count() != _copterManager.Copters.Count)
{
Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}");
return;
}
var lastTask = Tasks.LastOrDefault();
var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 1 };
- string vname=Path.GetFileNameWithoutExtension(filename);
- if (vname.Length>6) vname= vname.Substring(0, 6);
+ string vname = Path.GetFileNameWithoutExtension(filename);
+ if (vname.Length > 6) vname = vname.Substring(0, 6);
newTask.TaskCnName = vname;
- int id =0;
- foreach (Vector3 item in vc)
+ int id = 0;
+ foreach (FlightRoute.Vector3 item in vc)
{
Tuple observationLatLng = null;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
@@ -1035,10 +1039,10 @@ namespace Plane.FormationCreator.Formation
{
//去掉前后的"[]"
string taskName_temp = taskName.Substring(1);
- taskName_temp= taskName_temp.Remove(taskName_temp.Length - 1);
+ taskName_temp = taskName_temp.Remove(taskName_temp.Length - 1);
//新版用":"分割时间
string[] words = taskName_temp.Split(':');
- if (words.Count()==2)
+ if (words.Count() == 2)
{
taskName = words[0];
flytime = int.Parse(words[1]);
@@ -1095,7 +1099,7 @@ namespace Plane.FormationCreator.Formation
Tasks.Add(newTask);
RaiseTaskAdded(lastTask, newTask);
}
- // Alert.Show("导入完成!");
+ // Alert.Show("导入完成!");
/*
Dictionary PointDic = new Dictionary();
foreach (string line in lines)
@@ -1148,7 +1152,7 @@ namespace Plane.FormationCreator.Formation
public void ImportBlenderFlyToTask(string blenderVectors)
{
- string[] lineVectors = blenderVectors.Replace("\r\n","\n").Split('\n');
+ string[] lineVectors = blenderVectors.Replace("\r\n", "\n").Split('\n');
var lastTask = Tasks.LastOrDefault();
float alt = lastTask.SingleCopterInfos[0].TargetAlt;
@@ -1203,7 +1207,7 @@ namespace Plane.FormationCreator.Formation
if (nullableCenter == null) return;
var center = nullableCenter.Value;
var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = staggerRoutes, FlytoTime = flytoTime, LoiterTime = loiterTime };
- if(taskName != null) newTask.TaskCnName = taskName;
+ if (taskName != null) newTask.TaskCnName = taskName;
// TODO: 王海, 20150801, 处理实际飞行器数目与记录中数目不一致的情况。
for (int i = 0; i < copters.Count; i++)
{
@@ -1216,9 +1220,9 @@ namespace Plane.FormationCreator.Formation
if (isMeter)
newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask(
copter,
- (double)singleCopterInfoObj.x,
+ (double)singleCopterInfoObj.x,
(double)singleCopterInfoObj.y,
- (float)singleCopterInfoObj.targetAlt - copter.GroundAlt,
+ (float)singleCopterInfoObj.targetAlt - copter.GroundAlt,
(bool)singleCopterInfoObj.isLandWaypoint);
else
newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask(
@@ -1228,7 +1232,7 @@ namespace Plane.FormationCreator.Formation
var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray;
ObservableCollection ledList = jsonArray.ToObject>();
- foreach(LEDInfo info in ledList)
+ foreach (LEDInfo info in ledList)
{
newSingleCopterInfo.AddLEDInfo(info);
}
@@ -1257,7 +1261,7 @@ namespace Plane.FormationCreator.Formation
RaiseTaskAdded(lastTask, newTask);
}
-
+
private void RestoreTakeOffTask(byte takeOffTime, dynamic singleCopterInfos)
{
var copters = _copterManager.Copters;
@@ -1270,7 +1274,7 @@ namespace Plane.FormationCreator.Formation
{
var singleCopterInfoObj = singleCopterInfos[i];
takeOffTask.SingleCopterInfos[i].TakeOffWaitTime = (ushort)singleCopterInfoObj.waitTime;
- if (singleCopterInfoObj.ledInfos!= null)
+ if (singleCopterInfoObj.ledInfos != null)
{
var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray;
ObservableCollection ledList = jsonArray.ToObject>();
@@ -1279,7 +1283,7 @@ namespace Plane.FormationCreator.Formation
takeOffTask.SingleCopterInfos[i].AddLEDInfo(info);
}
}
-
+
//Message.Show(((ushort)singleCopterInfoObj.waitTime).ToString());
}
}
@@ -1305,7 +1309,7 @@ namespace Plane.FormationCreator.Formation
}
-
+
//导出任务 (单位:米)
public IEnumerable