1.修改界面,分成明显的两种模式,飞行模式和编辑模式 让界面简洁和有空间加更多功能

2.加入水平旋转图像功能
This commit is contained in:
pxzleo 2017-03-12 16:53:49 +08:00
parent 09126211a1
commit 07f5b39814
12 changed files with 953 additions and 285 deletions

View File

@ -33,8 +33,8 @@
True="Collapsed" /> True="Collapsed" />
<cnv:InverseBooleanConverter x:Key="InverseBooleanConverter" /> <cnv:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<cnv:BooleanToStringConverter x:Key="ShowModifyTaskViewButtonContentConverter" <cnv:BooleanToStringConverter x:Key="ShowModifyTaskViewButtonContentConverter"
False="显示任务编辑面板" False="【飞行模式】"
True="隐藏任务编辑面板" /> True="【编辑模式】" />
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter" <cnv:BooleanToResourceConverter x:Key="CheckSignConverter"
FalseKey="CloseIcon" FalseKey="CloseIcon"
TrueKey="CheckIcon" /> TrueKey="CheckIcon" />

View File

@ -0,0 +1,350 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator
{
/**
*
*
*
* */
public class CalculationLogLatDistance
{
/**
* (km)
* */
static public double EARTH_RADIUS = 6378.137;
/**
* (km)
* */
static public double EARTH_ARC = 111.199;
/**
* (rad)
* */
public static double rad(double d)
{
return d * Math.PI / 180.0;
}
/**
*
*
* @param lon1
*
* @param lat1
*
* @param lon2
*
* @param lat2
*
* @return km
* */
public static double GetDistanceOne(double lon1, double lat1, double lon2,
double lat2)
{
double r1 = rad(lat1);
double r2 = rad(lon1);
double a = rad(lat2);
double b = rad(lon2);
double s = Math.Acos(Math.Cos(r1) * Math.Cos(a) * Math.Cos(r2 - b)
+ Math.Sin(r1) * Math.Sin(a))
* EARTH_RADIUS;
return s;
}
/**
* (google maps源码中)
*
* @param lon1
*
* @param lat1
*
* @param lon2
*
* @param lat2
*
* @return km
* */
public static double GetDistanceTwo(double lon1, double lat1, double lon2,
double lat2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2)
+ Math.Cos(radLat1) * Math.Cos(radLat2)
* Math.Pow(Math.Sin(b / 2), 2)));
s = s * EARTH_RADIUS;
return s;
}
/**
*
*
* @param lon1
*
* @param lat1
*
* @param lon2
*
* @param lat2
*
* @return km
* */
public static double GetDistanceThree(double lon1, double lat1,
double lon2, double lat2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double radLon1 = rad(lon1);
double radLon2 = rad(lon2);
if (radLat1 < 0)
radLat1 = Math.PI / 2 + Math.Abs(radLat1);// south
if (radLat1 > 0)
radLat1 = Math.PI / 2 - Math.Abs(radLat1);// north
if (radLon1 < 0)
radLon1 = Math.PI * 2 - Math.Abs(radLon1);// west
if (radLat2 < 0)
radLat2 = Math.PI / 2 + Math.Abs(radLat2);// south
if (radLat2 > 0)
radLat2 = Math.PI / 2 - Math.Abs(radLat2);// north
if (radLon2 < 0)
radLon2 = Math.PI * 2 - Math.Abs(radLon2);// west
double x1 = Math.Cos(radLon1) * Math.Sin(radLat1);
double y1 = Math.Sin(radLon1) * Math.Sin(radLat1);
double z1 = Math.Cos(radLat1);
double x2 = Math.Cos(radLon2) * Math.Sin(radLat2);
double y2 = Math.Sin(radLon2) * Math.Sin(radLat2);
double z2 = Math.Cos(radLat2);
double d = Math.Pow((x1 - x2), 2) + Math.Pow((y1 - y2), 2)
+ Math.Pow((z1 - z2), 2);
// // 余弦定理求夹角
// double theta = Math.Acos((2 - d) / 2);
d = Math.Pow(EARTH_RADIUS, 2) * d;
// //余弦定理求夹角
double theta = Math.Acos((2 * Math.Pow(EARTH_RADIUS, 2) - d)
/ (2 * Math.Pow(EARTH_RADIUS, 2)));
double dist = theta * EARTH_RADIUS;
return dist;
}
/**
*
*
* @param lon1
*
* @param lat1
*
* @param lon2
*
* @param lat2
*
* @return °
* */
public static double GetAzimuth(double lon1, double lat1, double lon2,
double lat2)
{
lat1 = rad(lat1);
lat2 = rad(lat2);
lon1 = rad(lon1);
lon2 = rad(lon2);
double azimuth = Math.Sin(lat1) * Math.Sin(lat2) + Math.Cos(lat1)
* Math.Cos(lat2) * Math.Cos(lon2 - lon1);
azimuth = Math.Sqrt(1 - azimuth * azimuth);
azimuth = Math.Cos(lat2) * Math.Sin(lon2 - lon1) / azimuth;
azimuth = Math.Asin(azimuth) * 180 / Math.PI;
if (Double.IsNaN(azimuth))
{
if (lon1 < lon2)
{
azimuth = 90.0;
}
else {
azimuth = 270.0;
}
}
return azimuth;
}
/**
* AB的距离和方位角B的经纬度()
*
* @param lon1
* A的经度
* @param lat1
* A的纬度
* @param distance
* AB距离
* @param azimuth
* AB方位角
* @return B的经纬度
* */
public static void GetOtherPoint(double lon1, double lat1,
double distance, double azimuth, out double lng2, out double lat2)
{
azimuth = rad(azimuth);
double ab = distance / EARTH_ARC;// AB间弧线长
ab = rad(ab);
double Lat = Math.Asin(Math.Sin(lat1) * Math.Cos(ab) + Math.Cos(lat1)
* Math.Sin(ab) * Math.Cos(azimuth));
double Lon = lon1
+ Math.Asin(Math.Sin(azimuth) * Math.Sin(ab) / Math.Cos(Lat));
// System.out.println(Lon + "," + Lat);
double a = Math.Acos(Math.Cos(90 - lon1) * Math.Cos(ab)
+ Math.Sin(90 - lon1) * Math.Sin(ab) * Math.Cos(azimuth));
double C = Math.Asin(Math.Sin(ab) * Math.Sin(azimuth) / Math.Sin(a));
// System.out.println("c=" + C);
lng2 = lon1 + C;
lat2 = 90 - a;
return ;
}
/**
* AB的距离和方位角B的经纬度
*
* @param lon1
* A的经度
* @param lat1
* A的纬度
* @param distance
* AB距离
* @param azimuth
* AB方位角
* @return B的经纬度
* */
public static void ConvertDistanceToLogLat(double lng1, double lat1,
double distance, double azimuth, out double lng2, out double lat2)
{
azimuth = rad(azimuth);
// 将距离转换成经度的计算公式
lng2 = lng1 + (distance * Math.Sin(azimuth))
/ (EARTH_ARC * Math.Cos(rad(lat1)));
// 将距离转换成纬度的计算公式
lat2 = lat1 + (distance * Math.Cos(azimuth)) / EARTH_ARC;
return ;
}
public static MyLatLng getMyLatLng(MyLatLng A, double distance, double angle)
{
double dx = distance * 1000 * Math.Sin((Math.PI / 180) * angle);
double dy = distance * 1000 * Math.Cos((Math.PI / 180) * angle);
double bjd = (dx / A.Ed + A.m_RadLo) * 180.0/ Math.PI;
double bwd = (dy / A.Ec + A.m_RadLa) * 180.0/ Math.PI;
return new MyLatLng(bjd, bwd);
}
/**
* AB连线与正北方向的角度
* @param A A点的经纬度
* @param B B点的经纬度
* @return AB连线与正北方向的角度0~360
*/
public static double getAngle(MyLatLng A, MyLatLng B)
{
double dx = (B.m_RadLo - A.m_RadLo) * A.Ed;
double dy = (B.m_RadLa - A.m_RadLa) * A.Ec;
double angle = 0.0;
angle = Math.Atan(Math.Abs(dx / dy)) * 180.0/ Math.PI;
double dLo = B.m_Longitude - A.m_Longitude;
double dLa = B.m_Latitude - A.m_Latitude;
if (dLo > 0 && dLa <= 0)
{
angle = (90.0- angle) + 90;
}
else if (dLo <= 0 && dLa < 0)
{
angle = angle + 180.0;
}
else if (dLo < 0 && dLa >= 0)
{
angle = (90.0- angle) + 270;
}
if (Double.IsNaN(angle)) angle = 0.0;
return angle;
}
public class MyLatLng
{
static double Rc = 6378137;
static double Rj = 6356725;
public double m_LoDeg, m_LoMin, m_LoSec;
public double m_LaDeg, m_LaMin, m_LaSec;
public double m_Longitude, m_Latitude;
public double m_RadLo, m_RadLa;
public double Ec;
public double Ed;
public MyLatLng(double longitude, double latitude)
{
m_LoDeg = (int)longitude;
m_LoMin = (int)((longitude - m_LoDeg) * 60);
m_LoSec = (longitude - m_LoDeg - m_LoMin / 60.0) * 3600;
m_LaDeg = (int)latitude;
m_LaMin = (int)((latitude - m_LaDeg) * 60);
m_LaSec = (latitude - m_LaDeg - m_LaMin / 60.0) * 3600;
m_Longitude = longitude;
m_Latitude = latitude;
m_RadLo = longitude * Math.PI / 180.0;
m_RadLa = latitude * Math.PI / 180.0;
Ec = Rj + (Rc - Rj) * (90.0- m_Latitude) / 90.0;
Ed = Ec * Math.Cos(m_RadLa);
}
}
}
}

View File

@ -101,11 +101,11 @@ namespace Plane.FormationCreator.Formation
break; break;
case FlightTaskType.TakeOff: case FlightTaskType.TakeOff:
//多架同时起飞 //多架同时起飞
await MutilRunTakeOffTaskAsync(2).ConfigureAwait(false); await MutilRunTakeOffTaskAsync(5).ConfigureAwait(false);
break; break;
case FlightTaskType.ReturnToLand: // Added by ZJF case FlightTaskType.ReturnToLand: // Added by ZJF
//多架同时返航 //多架同时返航
await MutilRunReturnToLandTaskAsync(2).ConfigureAwait(false); await MutilRunReturnToLandTaskAsync(5).ConfigureAwait(false);
break; break;
default: default:
throw new InvalidOperationException(); throw new InvalidOperationException();

View File

@ -102,15 +102,27 @@
<v:CopterListView /> <v:CopterListView />
<StackPanel Grid.Row="1"> <StackPanel Grid.Row="1">
<Separator />
<v:ControlPanelView />
<StackPanel Grid.Row="2"
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
<Separator Grid.ColumnSpan="2" />
<v:ControlPanelView />
</StackPanel>
<StackPanel Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource BooleanToVisibilityConverter}}"> <StackPanel Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource BooleanToVisibilityConverter}}">
<Separator /> <Separator />
<v:ModifyTaskView /> <v:ModifyTaskView />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="2"> <StackPanel Grid.Row="2"
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
<Separator Grid.ColumnSpan="2" /> <Separator Grid.ColumnSpan="2" />
<v:CopterInfoView DataContext="{Binding Path=CopterListViewModel.SelectedCopter}" /> <v:CopterInfoView DataContext="{Binding Path=CopterListViewModel.SelectedCopter}" />
</StackPanel> </StackPanel>

View File

@ -141,6 +141,7 @@
<Compile Include="Maps\OpenStreetMapTileSource.cs" /> <Compile Include="Maps\OpenStreetMapTileSource.cs" />
<Compile Include="ServiceLocatorConfigurer.cs" /> <Compile Include="ServiceLocatorConfigurer.cs" />
<Compile Include="Test.cs" /> <Compile Include="Test.cs" />
<Compile Include="CalculationLogLatDistance.cs" />
<Compile Include="ViewModels\ConnectViewModel.cs" /> <Compile Include="ViewModels\ConnectViewModel.cs" />
<Compile Include="ViewModels\ControlPanelViewModel.cs" /> <Compile Include="ViewModels\ControlPanelViewModel.cs" />
<Compile Include="ViewModels\CopterListViewModel.cs" /> <Compile Include="ViewModels\CopterListViewModel.cs" />

View File

@ -41,6 +41,8 @@ namespace Plane.FormationCreator.ViewModels
private int _virtualCopterId = 1; private int _virtualCopterId = 1;
private LatLng? _lastVirtualCopterLocation; private LatLng? _lastVirtualCopterLocation;
private ICommand _AddVirtualCopterCommand; private ICommand _AddVirtualCopterCommand;
public ICommand AddVirtualCopterCommand public ICommand AddVirtualCopterCommand
{ {
@ -98,249 +100,6 @@ namespace Plane.FormationCreator.ViewModels
} }
private ICommand _AverageCommand;
public ICommand AverageCommand
{
get
{
return _AverageCommand ?? (_AverageCommand = new RelayCommand<int>(async alignmentLine =>
{
double maxlat = 0;
double tlat = 0;
double minlat = 0;
double maxlng = 0;
double minlng = 0;
double tlng = 0;
double avgl=0;
if (alignmentLine == 0)
{
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
int selectednumber = _copterManager.SelectedCopters.Count()-1;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
if (minlng == 0)
minlng = tlng;
if (tlng > maxlng)
maxlng = tlng;
else if (tlng < minlng)
minlng = tlng;
}
}
avgl = (maxlng - minlng) / selectednumber;
int coptnum = 0;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng= minlng+ avgl*coptnum;
coptnum++;
}
}
}
if (alignmentLine == 90)
{
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
int selectednumber = _copterManager.SelectedCopters.Count() - 1;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
if (minlat == 0)
minlat = tlat;
if (tlat > maxlat)
maxlat = tlat;
else if (tlat < minlat)
minlat = tlat;
}
}
avgl = (maxlat - minlat) / selectednumber;
int coptnum = 0;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = minlat + avgl * coptnum;
coptnum++;
}
}
}
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
private ICommand _AlignmentCommand;
public ICommand AlignmentCommand
{
get
{
return _AlignmentCommand ?? (_AlignmentCommand = new RelayCommand<int>(async alignmentLine =>
{
double maxlat = 0;
double tlat = 0;
double maxlng = 0;
double tlng = 0;
if (alignmentLine == 0)
{
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
if (tlat > maxlat)
maxlat = tlat;
}
}
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat;
}
}
}
if (alignmentLine == 90)
{
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
if (tlng > maxlng)
maxlng = tlng;
}
}
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = maxlng;
}
}
}
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
} }
} }

View File

@ -16,9 +16,10 @@ namespace Plane.FormationCreator.ViewModels
{ {
public class ModifyTaskViewModel : ViewModelBase public class ModifyTaskViewModel : ViewModelBase
{ {
public ModifyTaskViewModel(FlightTaskManager flightTaskManager) public ModifyTaskViewModel(FlightTaskManager flightTaskManager, CopterManager copterManager)
{ {
_flightTaskManager = flightTaskManager; _flightTaskManager = flightTaskManager;
_copterManager = copterManager;
//_flightTaskManager.SingleCopterInfoChanged += (sender, e) => //_flightTaskManager.SingleCopterInfoChanged += (sender, e) =>
//{ //{
// var changedSingleInfo = e.ChangedSingleCopterInfo; // var changedSingleInfo = e.ChangedSingleCopterInfo;
@ -117,7 +118,10 @@ namespace Plane.FormationCreator.ViewModels
} }
private FlightTaskManager _flightTaskManager; private FlightTaskManager _flightTaskManager;
private CopterManager _copterManager;
public FlightTaskManager FlightTaskManager { get { return _flightTaskManager; } } public FlightTaskManager FlightTaskManager { get { return _flightTaskManager; } }
public CopterManager CopterManager { get { return _copterManager; } }
//private void InvokeForSelectedSingleCopterInfos(Action<FlightTaskSingleCopterInfo> action) //private void InvokeForSelectedSingleCopterInfos(Action<FlightTaskSingleCopterInfo> action)
//{ //{
// var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask; // var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask;
@ -208,5 +212,506 @@ namespace Plane.FormationCreator.ViewModels
})); }));
} }
} }
private ICommand _LevelAverageCommand;
public ICommand LevelAverageCommand
{
get
{
return _LevelAverageCommand ?? (_LevelAverageCommand = new RelayCommand<int>(async =>
{
double maxlng = 0;
double minlng = 0;
double tlng = 0;
double avgl = 0;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
int selectednumber = _copterManager.SelectedCopters.Count() - 1;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
if (minlng == 0)
minlng = tlng;
if (tlng > maxlng)
maxlng = tlng;
else if (tlng < minlng)
minlng = tlng;
}
}
avgl = (maxlng - minlng) / selectednumber;
int coptnum = 0;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = minlng + avgl * coptnum;
coptnum++;
}
}
///////////////////////
// await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
private ICommand _VerticlAverageCommand;
public ICommand VerticlAverageCommand
{
get
{
return _VerticlAverageCommand ?? (_VerticlAverageCommand = new RelayCommand<int>(async =>
{
double maxlat = 0;
double tlat = 0;
double minlat = 0;
double avgl = 0;
//////////////////////
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
int selectednumber = _copterManager.SelectedCopters.Count() - 1;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
if (minlat == 0)
minlat = tlat;
if (tlat > maxlat)
maxlat = tlat;
else if (tlat < minlat)
minlat = tlat;
}
}
avgl = (maxlat - minlat) / selectednumber;
int coptnum = 0;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = minlat + avgl * coptnum;
coptnum++;
}
}
///////////////////////
// await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
private ICommand _LevelAlignmentCommand;
public ICommand LevelAlignmentCommand
{
get
{
return _LevelAlignmentCommand ?? (_LevelAlignmentCommand = new RelayCommand<int>(async =>
{
double maxlat = 0;
double tlat = 0;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
if (tlat > maxlat)
maxlat = tlat;
}
}
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat;
}
}
//await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
private ICommand _VerticlAlignmentCommand;
public ICommand VerticlAlignmentCommand
{
get
{
return _VerticlAlignmentCommand ?? (_VerticlAlignmentCommand = new RelayCommand<int>(async =>
{
double maxlng = 0;
double tlng = 0;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
if (tlng > maxlng)
maxlng = tlng;
}
}
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = maxlng;
}
}
//await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
public static double DistanceOfTwoPoints(double lng1, double lat1, double lng2, double lat2, GaussSphere gs)
{
double radLat1 = Rad(lat1);
double radLat2 = Rad(lat2);
double a = radLat1 - radLat2;
double b = Rad(lng1) - Rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0));
s = Math.Round(s * 10000) / 10000;
return s;
}
private static double Rad(double d)
{
return d * Math.PI / 180.0;
}
/// <summary>
/// 高斯投影中所选用的参考椭球
/// </summary>
public enum GaussSphere
{
Beijing54,
Xian80,
WGS84,
}
//水平旋转
private ICommand _LevelRotateCommand;
public ICommand LevelRotateCommand
{
get
{
return _LevelRotateCommand ?? (_LevelRotateCommand = new RelayCommand<int>(async RotateLine =>
{
double lngsum = 0;
double latsum = 0;
int selectcount = 0;
double centlng = 0;
double centlat = 0;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
lngsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
latsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
selectcount++;
}
}
//计算旋转中心
if (selectcount > 0)
{
centlng = lngsum / selectcount;
centlat = latsum / selectcount;
}
else return;
//////////计算旋转,经测试用下面的函数组合计算比较准确
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
{
double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat,
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng,
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat);
CalculationLogLatDistance.MyLatLng mypos1, mypos2;
mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat);
mypos2 = new CalculationLogLatDistance.MyLatLng(_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng
, _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat);
double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2);
double lng2 = 0;
double lat2=0;
CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance,
lpAzimuth + (double)RotateLine,out lng2, out lat2);
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = lng2;
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2;
}
}
}
////
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
//垂直旋转
private ICommand _VerticlRotateCommand;
public ICommand VerticlRotateCommand
{
get
{
return _VerticlRotateCommand ?? (_VerticlRotateCommand = new RelayCommand<int>(async RotateLine =>
{
double lngsum = 0;
double latsum = 0;
int selectcount = 0;
double centlng = 0;
double centlat = 0;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
bool copterisselect;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
copterisselect = false;
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
copterisselect = true;
}
if (copterisselect)
{
lngsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
latsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
selectcount++;
}
}
//计算旋转中心
if (selectcount > 0)
{
centlng = lngsum / selectcount;
centlat = latsum / selectcount;
}
else return;
double dx = 0;
double dy = 0;
double ax = 0;
double ay = 0;
double x = centlng;
double y = centlat;
double k = (double)RotateLine / 180 * Math.PI;
for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++)
{
selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter;
foreach (var capter in _copterManager.SelectedCopters)
{
if (capter == selectedCopter)
{
ax = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng;
ay = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat;
dx = (ax - x) * Math.Cos(k) + (ay - y) * Math.Sin(k) + x; //此为最后的横坐标
dy = -(ax - x) * Math.Sin(k) + (ay - y) * Math.Cos(k) + y; //此为最后的纵坐标
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = dx;
_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = dy;
}
}
}
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
}));
}
}
} }
} }

View File

@ -29,7 +29,8 @@
Command="{Binding DisconnectCommand}" /> Command="{Binding DisconnectCommand}" />
</WrapPanel>--> </WrapPanel>-->
<TextBlock Text="基础控制" /> <TextBlock Text="飞行控制"
Margin="5,0,0,8"/>
<WrapPanel> <WrapPanel>
<Button Content="解锁" <Button Content="解锁"
Command="{Binding UnlockCommand}" /> Command="{Binding UnlockCommand}" />
@ -39,8 +40,7 @@
Command="{Binding HoverCommand}" /> Command="{Binding HoverCommand}" />
<Button Content="手动" <Button Content="手动"
Command="{Binding FloatCommand}" /> Command="{Binding FloatCommand}" />
<Button Content="标记"
Command="{Binding FlagCommand}" />
</WrapPanel> </WrapPanel>
<WrapPanel> <WrapPanel>
<Button Content="返航" <Button Content="返航"
@ -49,9 +49,14 @@
Command="{Binding LandCommand}" /> Command="{Binding LandCommand}" />
<Button Content="上锁" <Button Content="上锁"
Command="{Binding LockCommand}" /> Command="{Binding LockCommand}" />
<Button Content="跳过"
Command="{Binding FlagCommand}" />
<Button Content="测试" <Button Content="测试"
Visibility="Hidden"
Command="{Binding TestCommand}" /> Command="{Binding TestCommand}" />
<TextBox Width="50" Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" /> <TextBox Width="50"
Visibility="Hidden"
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
</WrapPanel> </WrapPanel>
<!--// 林俊清, 20150920, 目前不再使用 FormationController删除相关按钮。 <!--// 林俊清, 20150920, 目前不再使用 FormationController删除相关按钮。

View File

@ -10,6 +10,8 @@
d:DesignHeight="300" d:DesignHeight="300"
d:DesignWidth="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}"> d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
<StackPanel>
<TextBlock Text="飞行信息" />
<Grid> <Grid>
<Grid.Resources> <Grid.Resources>
<Style x:Key="CopterInfo_ComboBox" <Style x:Key="CopterInfo_ComboBox"
@ -161,4 +163,5 @@
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
</StackPanel>
</UserControl> </UserControl>

View File

@ -59,25 +59,13 @@
Margin="0,0,5,0" Margin="0,0,5,0"
Text="3" Text="3"
VerticalContentAlignment="Center" /> VerticalContentAlignment="Center" />
<Button Content="添加虚拟" <Button Content="添加虚拟飞行器"
VerticalContentAlignment="Center" VerticalContentAlignment="Center"
Command="{Binding AddVirtualCopterCommand}" Command="{Binding AddVirtualCopterCommand}"
CommandParameter="{Binding ElementName=txtVirtualCopterCount, Path=Text}" /> CommandParameter="{Binding ElementName=txtVirtualCopterCount, Path=Text}" />
<Button Content="清除" <Button Content="清除"
Margin="5,0,5,0"
Command="{Binding ClearCoptersCommand}" /> Command="{Binding ClearCoptersCommand}" />
<TextBox x:Name="txtAlignmentLine"
Width="30"
Margin="0,0,5,0"
Text="0"
VerticalContentAlignment="Center" />
<Button Content="对齐"
Command="{Binding AlignmentCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<Button Content="均分"
Command="{Binding AverageCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@ -18,6 +18,7 @@
</Style> </Style>
</StackPanel.Resources> </StackPanel.Resources>
<StackPanel> <StackPanel>
<Button Content="导出任务" <Button Content="导出任务"
Margin="0,5,0,0" Margin="0,5,0,0"
Command="{Binding ExportTasksCommand}" /> Command="{Binding ExportTasksCommand}" />
@ -25,30 +26,71 @@
Margin="5,5,0,0" Margin="5,5,0,0"
Command="{Binding ImportTasksCommand}" /> Command="{Binding ImportTasksCommand}" />
<TextBox Grid.Column="1"
</StackPanel>
<StackPanel>
<Button Content="上对齐"
Margin="0,5,5,0"
Command="{Binding LevelAlignmentCommand}" />
<Button Content="右对齐"
Margin="0,5,5,0"
Command="{Binding VerticlAlignmentCommand}" />
<Button Content="水平均分"
Margin="0,5,5,0"
Command="{Binding LevelAverageCommand}" />
<Button Content="垂直均分"
Margin="0,5,5,0"
Command="{Binding VerticlAverageCommand}" />
</StackPanel>
<StackPanel>
<Button Content="水平旋转"
Margin="0,5,5,0"
Command="{Binding LevelRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<Button Content="垂直旋转"
Margin="0,5,5,0"
Command="{Binding VerticlRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<TextBox x:Name="txtAlignmentLine"
Width="30" Width="30"
Margin="5, 5, 5, 0" Margin="0,5,5,0"
Text="0"
VerticalContentAlignment="Center" />
<TextBlock Text="度" Margin="0, 5, 5, 0"/>
</StackPanel>
<StackPanel>
<Button Content="计算距离"
Margin="0,5,5,0" Click="Button_Click"
/>
<TextBox Grid.Column="1"
Width="25"
Margin="0, 5, 5, 0"
HorizontalContentAlignment="Right" HorizontalContentAlignment="Right"
Name="firstCopter" Name="firstCopter"
Text="0" />
<TextBox Grid.Column="1"
Width="30"
Margin="5, 5, 5, 0"
HorizontalContentAlignment="Right"
Name="secondCopter"
Text="1" /> Text="1" />
<TextBox Grid.Column="1"
Width="25"
Margin="0, 5, 5, 0"
HorizontalContentAlignment="Right"
Name="secondCopter"
Text="2" />
<TextBox Grid.Column="1" <TextBox Grid.Column="1"
Width="40" Width="40"
Margin="5, 5, 5, 0" Margin="0, 5, 5, 0"
HorizontalContentAlignment="Right" HorizontalContentAlignment="Right"
Name="distanceCopters" Name="distanceCopters"
Text="" /> Text="" />
<TextBlock Text="米" Margin="0, 5, 5, 0"/>
<Button Content="计算"
Margin="5,5,0,0" Click="Button_Click"
/>
</StackPanel> </StackPanel>
<TabControl Margin="0,5" <TabControl Margin="0,5"
Grid.IsSharedSizeScope="True" Grid.IsSharedSizeScope="True"

View File

@ -40,8 +40,8 @@ namespace Plane.FormationCreator.Views
if (_flightTaskManager.SelectedTask != null) if (_flightTaskManager.SelectedTask != null)
{ {
var firstCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[firstIndex]; var firstCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[firstIndex-1];
var secondCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[secondIndex]; var secondCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[secondIndex-1];
double distance = GeographyUtils.CalcDistance(firstCopterInfo.TargetLat, firstCopterInfo.TargetLng, firstCopterInfo.TargetAlt, double distance = GeographyUtils.CalcDistance(firstCopterInfo.TargetLat, firstCopterInfo.TargetLng, firstCopterInfo.TargetAlt,
secondCopterInfo.TargetLat, secondCopterInfo.TargetLng, secondCopterInfo.TargetAlt); secondCopterInfo.TargetLat, secondCopterInfo.TargetLng, secondCopterInfo.TargetAlt);
@ -50,5 +50,8 @@ namespace Plane.FormationCreator.Views
} }
} }
} }
} }