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;
|
|
|
|
|
|
|
|
|
|
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); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int _SingleRowCount = 0;
|
|
|
|
|
public int SingleRowCount
|
|
|
|
|
{
|
|
|
|
|
get { return _SingleRowCount; }
|
|
|
|
|
set { Set(nameof(SingleRowCount), ref _SingleRowCount, value); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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
|
|
|
|
|
{
|
|
|
|
|
return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand(async () =>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int colCount = SingleRowCount;
|
|
|
|
|
int copterCount = _copterManager.Copters.Count;
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
/*
|
2019-12-11 20:41:07 +08:00
|
|
|
|
if (copterCount % colCount != 0)
|
|
|
|
|
{
|
|
|
|
|
Alert.Show($"列数设置错误!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
*/
|
|
|
|
|
//列数用户设置colCount
|
|
|
|
|
//计算行数rowCount
|
2019-12-11 20:41:07 +08:00
|
|
|
|
int rowCount = copterCount / colCount;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//有多的飞机,多一行
|
|
|
|
|
//有整除余,代表最后一行是否没有满
|
|
|
|
|
bool havemode = (copterCount % colCount != 0);
|
|
|
|
|
|
|
|
|
|
//if (havemode)
|
|
|
|
|
// rowCount++;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
int num = 1;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//目前方案是 选中3架飞机,1号飞机,第一排任意飞机,第一列任意飞机(尽量远离1号机)
|
|
|
|
|
//用于计算横向和纵向的角度
|
|
|
|
|
if (_copterManager.AcceptingControlCopters.Count() == 3)
|
2019-12-11 20:41:07 +08:00
|
|
|
|
{
|
|
|
|
|
var copters = _copterManager.AcceptingControlCopters.ToList();
|
|
|
|
|
var firstCopter = copters[0];
|
|
|
|
|
var secondCopter = copters[1];
|
|
|
|
|
var thirdCopter = copters[2];
|
2020-02-01 22:02:25 +08:00
|
|
|
|
// var fourthCopter = copters[3];
|
|
|
|
|
|
|
|
|
|
//第一列角度(1,3) 用于计算每行第一架飞机
|
|
|
|
|
float firstColDirect =(float) GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter));
|
|
|
|
|
//最后列角度(2,4) 用于计算每行最后一架飞机
|
|
|
|
|
float lastColDirect =(float) GeographyUtils.RadToDeg(secondCopter.CalcDirection2D(fourthCopter));
|
|
|
|
|
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
/*
|
|
|
|
|
// //四个角从1号机开始选取(第一排第一个1, 第一排最后2, 最后一排第一个3 , 最后一排最后4)
|
|
|
|
|
//第一列角度(1,3) 用于计算每行第一架飞机
|
|
|
|
|
float firstColazimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D(
|
|
|
|
|
firstCopter.Latitude, firstCopter.Longitude,
|
|
|
|
|
thirdCopter.Latitude, thirdCopter.Longitude));
|
|
|
|
|
//最后列角度(2,4) 用于计算每行最后一架飞机
|
|
|
|
|
float lastColazimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D(
|
|
|
|
|
secondCopter.Latitude, secondCopter.Longitude,
|
|
|
|
|
fourthCopter.Latitude, fourthCopter.Longitude));
|
|
|
|
|
|
|
|
|
|
*/
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
|
|
|
|
ICopter destCopter = null;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
ICopter sourceCopter = null;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
ICopter rowfirstCopter = null;
|
|
|
|
|
ICopter rowlastCopter = null;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//行头位置,行尾位置,用ILocation2D不用ICopter是因为可能没有飞机
|
|
|
|
|
ILocation2D rowLocfirst = null;
|
|
|
|
|
ILocation2D rowLoclast = null;
|
|
|
|
|
|
|
|
|
|
//行查找步长
|
|
|
|
|
int rowfindstep = 1;
|
|
|
|
|
//按行循环
|
2019-12-11 20:41:07 +08:00
|
|
|
|
for (int i = 0; i < rowCount; i++)
|
|
|
|
|
{
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
//第一行开始结束是(1,2)
|
2019-12-11 20:41:07 +08:00
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
rowfirstCopter = firstCopter;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowLocfirst = rowfirstCopter;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
rowlastCopter = secondCopter;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowLoclast = rowlastCopter;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//最后一行(3,4)
|
2019-12-11 20:41:07 +08:00
|
|
|
|
else if (i == rowCount - 1)
|
|
|
|
|
{
|
|
|
|
|
rowfirstCopter = thirdCopter;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowLocfirst = rowfirstCopter;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
rowlastCopter = fourthCopter;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowLoclast = rowlastCopter;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//中间的行找该行的第一架和最后一架飞机
|
2019-12-11 20:41:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowLocfirst=rowLocfirst.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f);
|
|
|
|
|
rowLoclast = rowLoclast.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f);
|
|
|
|
|
|
|
|
|
|
rowLocfirst.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rowfirstCopter = FindNextCopter(rowLocfirst, firstColDirect, 1);
|
|
|
|
|
rowlastCopter = FindNextCopter(rowLoclast, lastColDirect, 1);
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
if (rowfirstCopter == null)
|
|
|
|
|
Message.Show($"无法找到第{i + 1}行的起始飞机");
|
|
|
|
|
if (rowlastCopter == null)
|
|
|
|
|
Message.Show($"无法找到第{i + 1}行的结束飞机");
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
rowfindstep = 1;
|
|
|
|
|
//每一行按列循环
|
2019-12-11 20:41:07 +08:00
|
|
|
|
for (int j = 0; j < colCount; j++)
|
|
|
|
|
{
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
//计算每一行方向
|
2019-12-11 20:41:07 +08:00
|
|
|
|
double curRowAzimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D(
|
|
|
|
|
rowfirstCopter.Latitude, rowfirstCopter.Longitude,
|
|
|
|
|
rowlastCopter.Latitude, rowlastCopter.Longitude));
|
|
|
|
|
if (j == 0)
|
|
|
|
|
{
|
|
|
|
|
destCopter = rowfirstCopter;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
sourceCopter = rowfirstCopter;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
|
|
|
|
else if (j == colCount - 1)
|
|
|
|
|
{
|
|
|
|
|
destCopter = rowlastCopter;
|
|
|
|
|
}
|
|
|
|
|
else
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//按行查找飞机
|
2019-12-11 20:41:07 +08:00
|
|
|
|
{
|
2019-12-30 10:35:50 +08:00
|
|
|
|
ICopter tempCopter = null;
|
|
|
|
|
tempCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == num);
|
|
|
|
|
while (tempCopter != null)
|
|
|
|
|
{
|
|
|
|
|
num++;
|
|
|
|
|
j++;
|
|
|
|
|
tempCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == num);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//根据当前飞机destCopter,按curRowAzimuth方向按间距1.5米找下一个飞机
|
|
|
|
|
destCopter = FindNextCopter(sourceCopter, curRowAzimuth, rowfindstep);
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
|
|
|
|
if (destCopter == null)
|
|
|
|
|
{
|
2020-02-01 22:02:25 +08:00
|
|
|
|
Message.Show($"在寻找第{num}号位置时候无法找到对应位置飞机");
|
|
|
|
|
//增加步长继续找
|
|
|
|
|
rowfindstep++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Alert.Show($"在寻找第{num}号位置时候无法找到对应位置飞机");
|
|
|
|
|
//return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rowfindstep = 1;
|
|
|
|
|
sourceCopter = destCopter;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
if (destCopter != null)
|
|
|
|
|
{
|
|
|
|
|
//赋予虚拟ID
|
|
|
|
|
destCopter.VirtualId = num;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
Message.Show($"飞机{destCopter.Name} 虚拟ID = {destCopter.VirtualId}");
|
|
|
|
|
}
|
2019-12-11 20:41:07 +08:00
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await Task.Delay(10);
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
private ICopter FindNextCopter(ILocation2D startLoc, double azimuth, int findstep)
|
2019-12-11 20:41:07 +08:00
|
|
|
|
{
|
|
|
|
|
ICopter retCopter = null;
|
|
|
|
|
bool foundCopter = false;
|
|
|
|
|
float stepLength = 0;
|
2020-02-01 22:02:25 +08:00
|
|
|
|
double mindis = 500.0f;
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
while (!foundCopter)
|
|
|
|
|
{
|
2020-02-01 22:02:25 +08:00
|
|
|
|
mindis = 500.0f;
|
|
|
|
|
stepLength += 1.5f * findstep;
|
|
|
|
|
//计算startCopter按azimuth方向移动stepLength后的位置targetLatLng
|
2019-12-11 20:41:07 +08:00
|
|
|
|
Tuple<double, double> targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
2020-02-01 22:02:25 +08:00
|
|
|
|
startLoc.Latitude, startLoc.Longitude, (float)azimuth, stepLength);
|
2019-12-11 20:41:07 +08:00
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//所有没有虚拟ID的飞机
|
2019-12-11 20:41:07 +08:00
|
|
|
|
List<ICopter> remainCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList();
|
|
|
|
|
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
foreach (var copter in remainCopters)
|
|
|
|
|
{
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//计算这些飞机和targetLatLng的距离
|
2019-12-11 20:41:07 +08:00
|
|
|
|
double temp = GeographyUtils.CalcDistance2D(copter.Latitude, copter.Longitude,
|
|
|
|
|
targetLatLng.Item1, targetLatLng.Item2);
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
//找最近的飞机
|
|
|
|
|
if (temp < mindis)
|
|
|
|
|
{
|
|
|
|
|
mindis = temp;
|
|
|
|
|
retCopter = copter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//如果目标点最近未标注飞机小于1米就认为找到了
|
|
|
|
|
if (mindis < 1.0)
|
2019-12-11 20:41:07 +08:00
|
|
|
|
{
|
|
|
|
|
foundCopter = true;
|
|
|
|
|
retCopter = copter;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
//不找更多步长
|
|
|
|
|
break;
|
2019-12-11 20:41:07 +08:00
|
|
|
|
if (stepLength > 15)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
if (foundCopter)
|
|
|
|
|
return retCopter;
|
|
|
|
|
else
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据当前位置和角度距离查找下一个位置
|
|
|
|
|
private ILocation2D FindNextLocal(ILocation2D startLoc, float directionDegrees, float distance)
|
|
|
|
|
{
|
|
|
|
|
ILocation2D retLoc = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//计算startCopter按azimuth方向移动stepLength后的位置targetLatLng
|
|
|
|
|
Tuple<double, double> targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
|
|
|
|
startLoc.Latitude, startLoc.Longitude, directionDegrees, distance);
|
|
|
|
|
return retLoc;
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-01 22:02:25 +08:00
|
|
|
|
|
|
|
|
|
|
2019-12-11 20:41:07 +08:00
|
|
|
|
}
|