Plane.FormationCreator/Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs

245 lines
9.8 KiB
C#
Raw Normal View History

2019-12-11 20:41:07 +08:00
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Plane.Copters;
using Plane.FormationCreator.Formation;
using Plane.Geography;
using Plane.Windows.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.Practices.ServiceLocation;
2019-12-11 20:41:07 +08:00
namespace Plane.FormationCreator.ViewModels
{
2020-02-01 22:02:25 +08:00
public class ConfigVirtualIdViewModel : ViewModelBase
2019-12-11 20:41:07 +08:00
{
CopterManager _copterManager;
public ConfigVirtualIdViewModel(CopterManager copterManager)
{
_copterManager = copterManager;
}
private int _SingleVirtualId = 0;
public int SingleVirtualId
{
get { return _SingleVirtualId; }
set { Set(nameof(SingleVirtualId), ref _SingleVirtualId, value); }
}
2019-12-11 20:41:07 +08:00
/// <summary>
/// 清除所有编号
/// </summary>
private ICommand _ClearVirtualIdCommand;
public ICommand ClearVirtualIdCommand
{
get
{
return _ClearVirtualIdCommand ?? (_ClearVirtualIdCommand = new RelayCommand(() =>
{
foreach (var c in _copterManager.Copters)
{
c.VirtualId = 0;
}
Message.Show($"已清除所有飞机编号");
}));
}
}
2020-02-01 22:02:25 +08:00
2019-12-11 20:41:07 +08:00
/// <summary>
/// 设置单个虚拟ID
/// </summary>
private ICommand _SetSingleVirtualIdCommand;
public ICommand SetSingleVirtualIdCommand
{
get
{
return _SetSingleVirtualIdCommand ?? (_SetSingleVirtualIdCommand = new RelayCommand(() =>
{
if (SingleVirtualId <= 0)
{
System.Windows.MessageBox.Show("编号必须大于0");
return;
}
if (_copterManager.AcceptingControlCopters.Count() == 1)
{
var copter = _copterManager.AcceptingControlCopters.FirstOrDefault();
copter.VirtualId = SingleVirtualId;
Message.Show($"飞机{copter.Name} 设置编号={SingleVirtualId}");
}
}));
}
}
private ICommand _AutoLocationNumsCommand;
public ICommand AutoLocationNumsCommand
{
get
{
2020-02-01 22:02:25 +08:00
//目前方案是
//1.保证所有没有正确定位的飞机都人工编号,
//2.然后选中3架飞机1号飞机第一排任意飞机第一列任意飞机尽量远离1号机
//3.开始计算
return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand( () =>
{
//飞机摆放最小间距
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
float StepDis_Row = _flightTaskManager.ColumnDistance; //行内间距-列间距
float StepDis_Col = _flightTaskManager.RowDistance ; //列间距-行间距
float FindDis =Math.Min(StepDis_Row, StepDis_Col); //查找半径
if (_copterManager.AcceptingControlCopters.Count() >= 2)
{
var copters = _copterManager.AcceptingControlCopters.ToList();
var firstCopter = copters[0];
var secondCopter = copters[1];
ICopter thirdCopter=null;
if (_copterManager.AcceptingControlCopters.Count()>2)
thirdCopter = copters[2];
//行角度(1,2) 用于查找每行的飞机位置
float RowDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(secondCopter));
//列角度(1,3) 用于查找每行第一架飞机
float ColDirect = 0;
if (thirdCopter!=null)
ColDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter));
ICopter FindedCopter = firstCopter;
ICopter LastCopter = firstCopter;
ILocation2D LastRowHewadCopter = firstCopter;
firstCopter.VirtualId = 1;
while (FindedCopter!=null)
2019-12-11 20:41:07 +08:00
{
//按一行找飞机
FindedCopter = FindNextCopter(LastCopter, RowDirect, StepDis_Row, FindDis);
//一行找不到了 找下一行的前3架飞机
if ((FindedCopter == null)&&(thirdCopter!=null))
FindedCopter = FindNextColHeadCopter(out LastRowHewadCopter,LastRowHewadCopter, ColDirect, StepDis_Col, RowDirect, StepDis_Row, 3, FindDis);
//如果找到了分配ID
if (FindedCopter != null)
{
FindedCopter.VirtualId = GetVID(LastCopter.VirtualId);
Message.Show($"分配飞机VID:{FindedCopter.VirtualId}");
LastCopter = FindedCopter;
}
2019-12-11 20:41:07 +08:00
}
}
2019-12-11 20:41:07 +08:00
}));
}
}
//根据位置和查找范围查找飞机
private ICopter FindCopteratLoc(ILocation2D startLoc, float findDis)
2019-12-11 20:41:07 +08:00
{
ICopter retCopter = null;
ICopter foundCopter = null;
double mindis = 1000;
//所有没有虚拟ID的飞机
List<ICopter> NoVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList();
//找距离startLoc最近的飞机
foreach (var copter in NoVIDCopters)
2019-12-11 20:41:07 +08:00
{
//计算这些飞机和startLoc的距离
double temp = startLoc.CalcDistance2D(copter);
//找最近的飞机
if (temp < mindis)
2019-12-11 20:41:07 +08:00
{
mindis = temp;
foundCopter = copter;
2019-12-11 20:41:07 +08:00
}
}
//如果找到的最近的飞机小于查找半径就认为找到了
if (mindis < findDis)
retCopter = foundCopter;
return retCopter;
2020-02-01 22:02:25 +08:00
}
//根据VID查找飞机
private ICopter FindCopteratVID(int VID)
2020-02-01 22:02:25 +08:00
{
List<ICopter> HaveVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == VID).ToList();
if (HaveVIDCopters.Count==1)
return HaveVIDCopters[0];
return null;
}
2020-02-01 22:02:25 +08:00
//计算VID,找下一个没有提前分配的VID
private int GetVID(int VirtualId)
{
int retvid = VirtualId+1;
ICopter Copter = FindCopteratVID(retvid);
while (Copter!=null)
Copter = FindCopteratVID(++retvid);
return retvid;
2020-02-01 22:02:25 +08:00
}
/// <summary>
/// 按方向步长等找下一架飞机
/// </summary>
/// <param name="Copter">起始飞机</param>
/// <param name="Direct">方向</param>
/// <param name="findstep">步长</param>
/// <param name="finddis">查找半径</param>
/// <returns>找到的飞机</returns>
private ICopter FindNextCopter(ILocation2D Copter, float Direct,float findstep,float finddis,int findstepnum=5)
{
ICopter FindedCopter = null;
ILocation2D FindLoc = null;
int step = 1;
while ((FindedCopter == null) && (step <= findstepnum))
{
//查找下一个飞机应在摆放的位置
FindLoc = Copter.CalcLatLngSomeMetersAway2D(Direct, findstep * step++);
//该位置是否有飞机
FindedCopter = FindCopteratLoc(FindLoc, finddis);
}
return FindedCopter;
}
2020-02-01 22:02:25 +08:00
/// <summary>
///按方向步长等找下一行的第一架飞机同时输出该行第一个应该摆放飞机的位置
/// </summary>
/// <param name="HeadLoc">输出第一架飞机应该在的位置</param>
/// <param name="Copter">起始飞机</param>
/// <param name="ColDirect">列角度</param>
/// <param name="Colstep">列步长</param>
/// <param name="RowDirect">行角度</param>
/// <param name="Rowstep">行步长</param>
/// <param name="Rowstepnum">行查找深度</param>
/// <param name="finddis">位置查找范围</param>
/// <returns>找到的飞机</returns>
private ICopter FindNextColHeadCopter(out ILocation2D HeadLoc, ILocation2D Copter, float ColDirect, float Colstep,
float RowDirect, float Rowstep, int Rowstepnum,float finddis, int Colfindstepnum = 5)
{
ICopter FindedCopter = null;
HeadLoc = null;
int step = 1;
while ((FindedCopter == null) && (step <= Colfindstepnum))
{
//查找下一行第一架飞机应在摆放的位置
HeadLoc = Copter.CalcLatLngSomeMetersAway2D(ColDirect, Colstep * step++);
//该位置是否有飞机
FindedCopter = FindCopteratLoc(HeadLoc, finddis);
//如果没有飞机,横着找找行有没飞机
if (FindedCopter==null)
FindedCopter=FindNextCopter(HeadLoc, RowDirect, Rowstep, finddis, Rowstepnum);
}
return FindedCopter;
2019-12-11 20:41:07 +08:00
}
2019-12-11 20:41:07 +08:00
}
2020-02-01 22:02:25 +08:00
2019-12-11 20:41:07 +08:00
}