605 lines
23 KiB
C#
605 lines
23 KiB
C#
using Plane.Copters;
|
||
using Plane;
|
||
using Plane.FormationCreator.Formation;
|
||
using GalaSoft.MvvmLight;
|
||
using GalaSoft.MvvmLight.CommandWpf;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using System.Windows.Input;
|
||
using System.Threading;
|
||
using Plane.Communication;
|
||
using Plane.Geography;
|
||
using Microsoft.Practices.ServiceLocation;
|
||
using Plane.FormationCreator.Util;
|
||
using Newtonsoft.Json;
|
||
using System.IO;
|
||
using Newtonsoft.Json.Linq;
|
||
using Plane.Windows.Messages;
|
||
using Plane.Collections;
|
||
|
||
namespace Plane.FormationCreator.ViewModels
|
||
{
|
||
public class CopterListViewModel : ViewModelBase
|
||
{
|
||
public CopterListViewModel(CopterManager copterManager, MapManager mapManager, FlightTaskManager flightTaskManager, GroupManager groupManager)
|
||
{
|
||
_copterManager = copterManager;
|
||
_mapManager = mapManager;
|
||
_flightTaskManager = flightTaskManager;
|
||
_groupManager = groupManager;
|
||
/*
|
||
System.Timers.Timer t = new System.Timers.Timer(5000); //实例化Timer类,设置间隔时间为1秒;
|
||
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到达时间的时候执行事件;
|
||
t.AutoReset = true; //设置是执行一次(false)还是一直执行(true);
|
||
t.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
|
||
*/
|
||
}
|
||
|
||
public void theout(object source, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
int allrec = 0;
|
||
int allsend = 0;
|
||
int copterrec = 0;
|
||
int coptersend = 0;
|
||
foreach (var copter in _copterManager.Copters)
|
||
{
|
||
copter.GetCommunicationNumber(out copterrec, out coptersend);
|
||
allrec += copterrec;
|
||
allsend += coptersend;
|
||
copter.ResetCommunicationNumber();
|
||
}
|
||
allrec /= 5;
|
||
allsend /= 5;
|
||
if (_copterManager.Copters.Count>0)
|
||
Communinfo = "接收:" + allrec + "/s;发送:"+ allsend+"/s 单机:"+ allrec/ _copterManager.Copters.Count+"/s;"+
|
||
allsend / _copterManager.Copters.Count+"/s";
|
||
}
|
||
|
||
private GroupManager _groupManager;
|
||
private CopterManager _copterManager;
|
||
private MapManager _mapManager;
|
||
private FlightTaskManager _flightTaskManager;
|
||
private View3DManager _view3DManager = ServiceLocator.Current.GetInstance<View3DManager>();
|
||
|
||
public CopterManager CopterManager { get { return _copterManager; } }
|
||
|
||
|
||
private ICopter _SelectedCopter;
|
||
public ICopter SelectedCopter
|
||
{
|
||
get { return _SelectedCopter; }
|
||
set { Set(nameof(SelectedCopter), ref _SelectedCopter, value); }
|
||
}
|
||
|
||
private int _virtualCopterId = 1;
|
||
private LatLng? _lastVirtualCopterLocation;
|
||
|
||
private string _Communinfo = "";
|
||
public string Communinfo
|
||
{
|
||
get { return _Communinfo; }
|
||
set { Set(nameof(Communinfo), ref _Communinfo, value); }
|
||
}
|
||
|
||
private int _IntervalNum;
|
||
public int IntervalNum
|
||
{
|
||
get { return _IntervalNum; }
|
||
set { Set(nameof(IntervalNum), ref _IntervalNum, value); }
|
||
}
|
||
private int _RowNum;
|
||
public int RowNum
|
||
{
|
||
get { return _RowNum; }
|
||
set { Set(nameof(RowNum), ref _RowNum, value); }
|
||
}
|
||
|
||
private int _ContinuousNum;
|
||
public int ContinuousNum
|
||
{
|
||
get { return _ContinuousNum; }
|
||
set { Set(nameof(ContinuousNum), ref _ContinuousNum, value); }
|
||
}
|
||
|
||
private bool _ShowTemp = false;
|
||
public bool ShowTemp
|
||
{
|
||
get { return _ShowTemp; }
|
||
set { Set(nameof(ShowTemp), ref _ShowTemp, value); }
|
||
}
|
||
|
||
public ObservableCollection<string[]> CopterGroups { get; } = new ObservableCollection<string[]>();
|
||
|
||
|
||
private int getNextcopterindex( int currindex)
|
||
{
|
||
//每行数量
|
||
int colcount = _flightTaskManager.ColumnCount;
|
||
int newind = currindex;
|
||
for (int i = 0;i< IntervalNum;i++)
|
||
{
|
||
newind +=1;
|
||
if ((newind % colcount) == 0)
|
||
newind += RowNum * colcount;
|
||
}
|
||
return newind;
|
||
}
|
||
|
||
private ICommand _IntervalSelectCoptersCommand;
|
||
public ICommand IntervalSelectCoptersCommand
|
||
{
|
||
get
|
||
{
|
||
return _IntervalSelectCoptersCommand ?? (_IntervalSelectCoptersCommand = new RelayCommand(() =>
|
||
{
|
||
if (_copterManager.AcceptingControlCopters.Count() != 1 || IntervalNum == 0 || ContinuousNum == 0)
|
||
return;
|
||
|
||
ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
|
||
_copterManager.Select(null);
|
||
int index = _copterManager.Copters.IndexOf(copter);
|
||
_copterManager.shiftkeydown = true;
|
||
int colcount = _flightTaskManager.ColumnCount;
|
||
|
||
for (; index < _copterManager.Copters.Count; index= getNextcopterindex( index) )
|
||
{
|
||
for (int i = 0; i < ContinuousNum; i++)
|
||
{
|
||
if (index >= _copterManager.Copters.Count) break;
|
||
_copterManager.Select(_copterManager.Copters[index]);
|
||
index += 1;
|
||
if ((index % colcount) == 0)
|
||
index += RowNum * colcount;
|
||
getNextcopterindex(index);
|
||
}
|
||
}
|
||
/*
|
||
for (; index < _copterManager.Copters.Count; index += IntervalNum)
|
||
{
|
||
for (int i = 0; i < ContinuousNum; i++)
|
||
{
|
||
if (index >= _copterManager.Copters.Count) break;
|
||
_copterManager.Select(_copterManager.Copters[index]);
|
||
index++;
|
||
}
|
||
}
|
||
*/
|
||
_copterManager.shiftkeydown = false;
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
private ICommand _OnlyShowSelectedCoptersCommand;
|
||
public ICommand OnlyShowSelectedCoptersCommand
|
||
{
|
||
get
|
||
{
|
||
return _OnlyShowSelectedCoptersCommand ?? (_OnlyShowSelectedCoptersCommand = new RelayCommand(async () =>
|
||
{
|
||
if (_copterManager.SelectedCopters.Count() > 0)
|
||
{
|
||
|
||
Plane.Windows.Messages.Message.Show("隐藏飞机");
|
||
_copterManager.ShowCopter.Clear();
|
||
_copterManager.ShowCopter.AddRange(_copterManager.SelectedCopters);
|
||
}
|
||
await Task.Delay(10);
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private ICommand _SortbyVIdCommand;
|
||
public ICommand SortbyVIdCommand
|
||
{
|
||
get
|
||
{
|
||
return _SortbyVIdCommand ?? (_SortbyVIdCommand = new RelayCommand( () =>
|
||
{
|
||
_copterManager.SortType = CopterManager.CopterSortType.ByVID;
|
||
//强制刷新飞机显示
|
||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
private ICommand _SortbyIdCommand;
|
||
public ICommand SortbyIdCommand
|
||
{
|
||
get
|
||
{
|
||
return _SortbyIdCommand ?? (_SortbyVIdCommand = new RelayCommand(() =>
|
||
{
|
||
_copterManager.SortType = CopterManager.CopterSortType.ByID;
|
||
|
||
//强制刷新飞机显示
|
||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private ICommand _ShowAllCoptersCommand;
|
||
public ICommand ShowAllCoptersCommand
|
||
{
|
||
get
|
||
{
|
||
return _ShowAllCoptersCommand ?? (_ShowAllCoptersCommand = new RelayCommand(async () =>
|
||
{
|
||
Plane.Windows.Messages.Message.Show("显示飞机");
|
||
_copterManager.ShowCopter.Clear();
|
||
await Task.Delay(10);
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private ICommand _ShowAllIDCommand;
|
||
public ICommand ShowAllIDCommand
|
||
{
|
||
get
|
||
{
|
||
return _ShowAllIDCommand ?? (_ShowAllIDCommand = new RelayCommand(() =>
|
||
{
|
||
|
||
_copterManager.SortType = CopterManager.CopterSortType.ByVIDShowAll;
|
||
|
||
//强制刷新飞机显示
|
||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
private ICommand _AddVirtualCopterCommand;
|
||
public ICommand AddVirtualCopterCommand
|
||
{
|
||
get
|
||
{
|
||
return _AddVirtualCopterCommand ?? (_AddVirtualCopterCommand = new RelayCommand<int>(async addcount =>
|
||
{
|
||
//给第三方时候限制数量用
|
||
// if (_copterManager.Copters.Count() >= VersionControl.CopterUpperLimit)
|
||
/// {
|
||
// return;
|
||
// }
|
||
|
||
var center = _mapManager.Center;
|
||
string id;
|
||
|
||
int colnum = _flightTaskManager.ColumnCount; //自动生成列数=4
|
||
float coldis = _flightTaskManager.ColumnDistance;//列相距5米
|
||
float rowdis = _flightTaskManager.RowDistance;//行相距5米
|
||
int orientation = _flightTaskManager.Orientation; //矩阵朝向
|
||
|
||
|
||
|
||
|
||
int currcol = 0; //当前列号
|
||
int currrow = 0; //当前行
|
||
Tuple<double, double> colheadLatLng = new Tuple<double, double>(0, 0);
|
||
Tuple<double, double> targetLatLng = new Tuple<double, double>(0, 0);
|
||
|
||
|
||
//内蒙地区
|
||
// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756
|
||
// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856)
|
||
// return ;
|
||
|
||
|
||
|
||
|
||
LatLng? colLatLng = new LatLng(center.Lat, center.Lng);
|
||
|
||
for (int i = 0; i < addcount; ++i, ++_virtualCopterId)
|
||
{
|
||
id = _virtualCopterId.ToString();
|
||
|
||
if (i == 0)
|
||
{
|
||
_lastVirtualCopterLocation = new LatLng(center.Lat, center.Lng);
|
||
|
||
colLatLng = _lastVirtualCopterLocation;
|
||
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
if (currcol < colnum)
|
||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, (currcol * coldis));
|
||
else
|
||
{
|
||
currrow++;
|
||
currcol = 0;
|
||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng, orientation + 180, rowdis);
|
||
colLatLng = new LatLng(targetLatLng.Item1, targetLatLng.Item2);
|
||
|
||
colheadLatLng = targetLatLng;
|
||
}
|
||
/*
|
||
//随机位置,偏差40cm
|
||
Random r1 = new Random();
|
||
float rdrad= ((float)r1.Next(0, 360));
|
||
float rddis = ((float)r1.Next(-40, 40) / 100.0f);
|
||
|
||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(targetLatLng.Item1, targetLatLng.Item2, rdrad, rddis);
|
||
*/
|
||
|
||
|
||
_lastVirtualCopterLocation = new LatLng(targetLatLng.Item1, targetLatLng.Item2);
|
||
}
|
||
currcol++;
|
||
|
||
|
||
|
||
|
||
/* _lastVirtualCopterLocation =
|
||
_lastVirtualCopterLocation == null ?
|
||
new LatLng(center.Lat, center.Lng) :
|
||
new LatLng(_lastVirtualCopterLocation.Value.Lat, _lastVirtualCopterLocation.Value.Lng + 0.0001);
|
||
*/
|
||
|
||
|
||
if (_copterManager.EnAddCopter_Fake())
|
||
{
|
||
var copter = new FakeCopter(SynchronizationContext.Current);
|
||
copter.SetProperties(
|
||
latitude: _lastVirtualCopterLocation.Value.Lat,
|
||
longitude: _lastVirtualCopterLocation.Value.Lng,
|
||
id: id,
|
||
name: id
|
||
);
|
||
//不再预先分配VID
|
||
// copter.VirtualId = _virtualCopterId;
|
||
await copter.ConnectAsync();
|
||
await copter.GetCopterDataAsync();
|
||
_copterManager.CopterStatus.Add(false);
|
||
_copterManager.Copters.AddCopter(copter, _copterManager.SortType);
|
||
}
|
||
}
|
||
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
|
||
_flightTaskManager.SetOriginal();
|
||
}));
|
||
}
|
||
}
|
||
|
||
private ICommand _ShowLackCopterNumsCommand;
|
||
public ICommand ShowLackCopterNumsCommand
|
||
{
|
||
get
|
||
{
|
||
return _ShowLackCopterNumsCommand ?? (_ShowLackCopterNumsCommand = new RelayCommand(async () =>
|
||
{
|
||
if (_copterManager.Copters.Count == 0) return;
|
||
ICopter lastCopter = _copterManager.Copters.Last();
|
||
int name = int.Parse(lastCopter.Name);
|
||
List<string> lackCopterNums = new List<string>();
|
||
for (int i = 1; i <= name; i++)
|
||
{
|
||
ICopter copter = null;
|
||
copter = _copterManager.Copters.FirstOrDefault(o=>o.Name == i.ToString());
|
||
if (copter == null)
|
||
lackCopterNums.Add(i.ToString());
|
||
}
|
||
if (lackCopterNums.Count > 0)
|
||
{
|
||
Windows.Messages.Message.Show($"未连接:{string.Join(",", lackCopterNums)}");
|
||
}
|
||
else
|
||
{
|
||
Windows.Messages.Message.Show($"{name}架全部连接");
|
||
}
|
||
await Task.Delay(10);
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private ICommand _SetCoptersPutCommand;
|
||
public ICommand SetCoptersPutCommand
|
||
{
|
||
get
|
||
{
|
||
return _SetCoptersPutCommand ?? (_SetCoptersPutCommand = new RelayCommand(async () =>
|
||
{
|
||
var SetCoptersPutView = new Views.SetCoptersPutView(
|
||
_flightTaskManager.ColumnCount,
|
||
_flightTaskManager.ColumnDistance,
|
||
_flightTaskManager.RowDistance,
|
||
_flightTaskManager.Orientation
|
||
);
|
||
if (SetCoptersPutView.ShowDialog() == true)
|
||
{
|
||
_flightTaskManager.ColumnCount = int.Parse(SetCoptersPutView.textboxColNum.Text);
|
||
_flightTaskManager.ColumnDistance = float.Parse(SetCoptersPutView.textboxColDis.Text);
|
||
_flightTaskManager.RowDistance = float.Parse(SetCoptersPutView.textboxRowDis.Text);
|
||
_flightTaskManager.Orientation = int.Parse(SetCoptersPutView.textboxOrientation.Text);
|
||
_flightTaskManager.SaveIni();
|
||
}
|
||
await Task.Delay(100);
|
||
}));
|
||
}
|
||
}
|
||
|
||
private ICommand _ClearCoptersCommand;
|
||
public ICommand ClearCoptersCommand
|
||
{
|
||
get
|
||
{
|
||
return _ClearCoptersCommand ?? (_ClearCoptersCommand = new RelayCommand(async () =>
|
||
{
|
||
_flightTaskManager.Pause();
|
||
await _copterManager.ClearCopters();
|
||
/*
|
||
foreach (var copter in _copterManager.Copters)
|
||
{
|
||
await copter.DisconnectAsync();
|
||
}
|
||
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
|
||
_copterManager.Copters.Clear();
|
||
_copterManager.CopterStatus.Clear();
|
||
*/
|
||
|
||
_mapManager.ClearCopters();
|
||
_view3DManager.ClearCopters();
|
||
_flightTaskManager.ClearTasks();
|
||
// UdpServerConnectionManager.Instance.ClearConnections();
|
||
|
||
_virtualCopterId = 1;
|
||
_lastVirtualCopterLocation = null;
|
||
_flightTaskManager.OriginLat = 0;
|
||
_flightTaskManager.OriginLng = 0;
|
||
}));
|
||
}
|
||
}
|
||
|
||
// private ICommand _ImportCoptersLocationCommand;
|
||
// public ICommand ImportCoptersLocationCommand
|
||
// {
|
||
// get
|
||
// {
|
||
// return _ImportCoptersLocationCommand ?? (_ImportCoptersLocationCommand = new RelayCommand(async() =>
|
||
// {
|
||
// var dialog = new Microsoft.Win32.OpenFileDialog
|
||
// {
|
||
// DefaultExt = "json",
|
||
// Filter = "编队飞行任务 (*.json)|*.json"
|
||
// };
|
||
// if (dialog.ShowDialog() == true)
|
||
// {
|
||
// var locationsText = File.ReadAllText(dialog.FileName);
|
||
// dynamic coptersLocation = JsonConvert.DeserializeObject(locationsText);
|
||
// foreach (var location in coptersLocation)
|
||
// {
|
||
// var name = location.Name;
|
||
// JArray locations = location.Value as JArray;
|
||
// var x = ((Newtonsoft.Json.Linq.JValue)(locations[0])).Value;
|
||
// float fx = Convert.ToSingle(x);
|
||
// var y = ((Newtonsoft.Json.Linq.JValue)(locations[1])).Value;
|
||
// float fy = Convert.ToSingle(y);
|
||
//
|
||
// var fc = _copterManager.Copters[int.Parse(name) - 1] as FakeCopter;
|
||
// Tuple<double, double> observationLatLng = null;
|
||
// observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||
// _flightTaskManager.OriginLat,
|
||
// _flightTaskManager.OriginLng,
|
||
// 90,
|
||
// fx);
|
||
//
|
||
//
|
||
// observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||
// observationLatLng.Item1,
|
||
// observationLatLng.Item2,
|
||
// 0,
|
||
// fy);
|
||
//
|
||
// fc.SetProperties(
|
||
// latitude: observationLatLng.Item1,
|
||
// longitude: observationLatLng.Item2
|
||
// );
|
||
// }
|
||
// }
|
||
//
|
||
// await Task.Delay(10);
|
||
// }));
|
||
// }
|
||
// }
|
||
|
||
private ICommand _ImportCoptersLocationCommand;
|
||
public ICommand ImportCoptersLocationCommand
|
||
{
|
||
get
|
||
{
|
||
return _ImportCoptersLocationCommand ?? (_ImportCoptersLocationCommand = new RelayCommand(async () =>
|
||
{
|
||
var dialog = new Microsoft.Win32.OpenFileDialog
|
||
{
|
||
DefaultExt = "txt",
|
||
Filter = "编队飞行任务 (*.json)|*.txt"
|
||
};
|
||
if (dialog.ShowDialog() == true)
|
||
{
|
||
var locationsText = File.ReadAllText(dialog.FileName);
|
||
string[] coptersLocation = locationsText.Replace("\r\n","\n").Split('\n');
|
||
foreach (var location in coptersLocation)
|
||
{
|
||
string[] locations = location.Split(' ');
|
||
var name = locations[0];
|
||
|
||
var x = locations[2];
|
||
float fx = Convert.ToSingle(x)/100;
|
||
var y = locations[4];
|
||
float fy = Convert.ToSingle(y)/100;
|
||
|
||
var fc = _copterManager.Copters[int.Parse(name)] as FakeCopter;
|
||
Tuple<double, double> observationLatLng = null;
|
||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||
_flightTaskManager.OriginLat,
|
||
_flightTaskManager.OriginLng,
|
||
90,
|
||
fx);
|
||
|
||
|
||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||
observationLatLng.Item1,
|
||
observationLatLng.Item2,
|
||
0,
|
||
fy);
|
||
|
||
fc.SetProperties(
|
||
latitude: observationLatLng.Item1,
|
||
longitude: observationLatLng.Item2
|
||
);
|
||
}
|
||
}
|
||
|
||
await Task.Delay(10);
|
||
}));
|
||
}
|
||
}
|
||
|
||
private ICommand _ApplyGroundAltCommand;
|
||
public ICommand ApplyGroundAltCommand
|
||
{
|
||
get
|
||
{
|
||
return _ApplyGroundAltCommand ?? (_ApplyGroundAltCommand = new RelayCommand(async () =>
|
||
{
|
||
|
||
foreach (var copter in _copterManager.SelectedCopters)
|
||
{
|
||
copter.GroundAlt = SelectedCopter.GroundAlt;
|
||
}
|
||
|
||
await Task.Delay(10);
|
||
}));
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|