Plane.FormationCreator/Plane.FormationCreator/Views/MapView.xaml.cs
zxd 66fb5531a1 修复问题:
添加原点后未拖动会提示没有原点
2018-07-17 14:16:38 +08:00

520 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Plane.Copters;
using Plane;
using Plane.FormationCreator.Formation;
using Plane.Logging;
using Microsoft.Win32;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Plane.Collections;
using Microsoft.Maps.MapControl.WPF;
using Microsoft.Maps.MapControl.WPF.Overlays;
using System.Windows.Media.Effects;
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.ViewModels;
using Plane.Geography;
using Plane.FormationCreator.Maps;
using Plane.Windows.Messages;
namespace Plane.FormationCreator.Views
{
/// <summary>
/// Interaction logic for MapView.xaml
/// </summary>
public partial class MapView : UserControl
{
public MapView()
{
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance<MapViewModel>();
_mapManager.MapView = this;
_mapManager.SetCenterGetter(() => new LatLng { Lat = map.Center.Latitude, Lng = map.Center.Longitude });
_flightTaskManager.TaskAdded += FlightTaskManager_TaskAdded;
_flightTaskManager.OnOriginalSet += FlightTaskManager_SetOriginal;
Task.Factory.StartNew(async () =>
{
int delay = 500;
while (true)
{
if (Dispatcher.Invoke(RemoveLoadingErrorMessage))
{
delay = 2000;
}
await Task.Delay(delay);
}
});
_copterManager.SelectedCoptersChanged += (sender, e) =>
{
//if (AppEx.Instance.CurrentMode.IsForTasks())
//{
e.RemovedCopters?.ForEach(copter => _copterDrawings.GetValue(copter)?.SetEffect(false));
e.AddedCopters?.ForEach(copter => _copterDrawings.GetValue(copter)?.SetEffect(true));
//}
};
_flightTaskManager.PropertyChanged += (sender, e) =>
{
switch (e.PropertyName)
{
case nameof(FlightTaskManager.SelectedTaskIndex):
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
copterDrawing.SetTaskEffect(_flightTaskManager.SelectedTaskIndex);
}
break;
case nameof(FlightTaskManager.RightSelectedTaskIndex): // 单击右键触发
int taskIndexTmp = Math.Abs(_flightTaskManager.RightSelectedTaskIndex);
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
copterDrawing.SetTaskRightEffect(taskIndexTmp,
_flightTaskManager.Tasks[taskIndexTmp].IsRightSelected);
}
_flightTaskManager.Tasks[taskIndexTmp].IsRightSelected = !_flightTaskManager.Tasks[taskIndexTmp].IsRightSelected;
break;
default:
break;
}
};
map.MouseLeftButtonDown += (sender, e) =>
{
if (IsMouseOnCopterOrWaypoint(e.OriginalSource))
{
e.Handled = true;
}
};
_copterManager.Copters.ForEach(copter => copter.LocationChanged += Copter_LocationChanged);
_copterManager.Copters.CollectionChanged += Copters_CollectionChanged;
//_copterManager.Copters.ForEach(copter => AddOrMoveCopterForModifyingTask(copter));
//_copterManager.Copters.CollectionChanged += CoptersForModifyingTask_CollectionChanged;
map.MouseDoubleClick += async (sender, e) =>
{
e.Handled = true;
//// Test
//var pos = map.ViewportPointToLocation(e.GetPosition(map));
//AddOrMoveCopter(new FakeCopter(pos.Latitude, pos.Longitude));
// 林俊清, 20150930, AppMode 存在意义已不大;只有正在运行任务的时候才不允许指点。
//if (AppEx.Current.AppMode != AppMode.ControllingCopters) return;
if (_flightTaskManager.IsPaused == false) return;
var copters = _copterManager.AcceptingControlCopters;
if (!copters.Any()) return;
var pos = map.ViewportPointToLocation(e.GetPosition(map));
var centerLat = copters.Average(c => c.Latitude);
var centerLng = copters.Average(c => c.Longitude);
var latDelta = pos.Latitude - centerLat;
var lngDelta = pos.Longitude - centerLng;
await Task.WhenAll(copters.Select(copter => copter.FlyToAsync(copter.Latitude + latDelta, copter.Longitude + lngDelta, copter.Altitude)));
};
var center = _appConfig.Center;
map.Center = new Location(center.Lat, center.Lng);
map.ZoomLevel = _appConfig.ZoomLevel;
map.ViewChangeOnFrame += (object sender, MapEventArgs e) =>
{
if ( map.Mode.GetType().ToString() == "Microsoft.Maps.MapControl.WPF.AerialMode")
if (map.ZoomLevel >19)
map.ZoomLevel = 19;
};
Rectangle rectangle = new Rectangle();
bool drawRectangle = false;
Point startPosition = new Point();
Point leftTopPoint = new Point();
map.MouseRightButtonDown += (sender, e) =>
{
rectangle = new Rectangle();
rectangle.Width = 0;
rectangle.Height = 0;
rectangle.StrokeThickness = 1;
rectangle.Stroke = new SolidColorBrush(Color.FromRgb(0, 120, 215));
rectangle.Fill = new SolidColorBrush(Color.FromArgb(80, 0, 120, 215));
rectangle.Tag = "Rectangle";
map.Children.Add(rectangle);
startPosition = e.GetPosition(this);
MapLayer.SetPosition(rectangle, map.ViewportPointToLocation(startPosition));
drawRectangle = true;
};
map.MouseMove += (sender, e) =>
{
if (drawRectangle)
{
Point mousePosition = e.GetPosition(this);
rectangle.Width = Math.Abs(mousePosition.X - startPosition.X);
rectangle.Height = Math.Abs(mousePosition.Y - startPosition.Y);
leftTopPoint = new Point(Math.Min(mousePosition.X, startPosition.X), Math.Min(mousePosition.Y, startPosition.Y));
MapLayer.SetPosition(rectangle, map.ViewportPointToLocation(leftTopPoint));
}
};
int selectedCount = 0;
map.MouseRightButtonUp += (sender, e) =>
{
selectedCount = 0;
if (rectangle != null && map.Children.Contains(rectangle))
{
map.Children.Remove(rectangle);
if (_flightTaskManager.SelectedTask != null)
{
_copterManager.shiftkeydown = true;
_copterManager.Select(null);
foreach (FlightTaskSingleCopterInfo taskCopterInfo in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
Location seekLocation = new Location(taskCopterInfo.TargetLat, taskCopterInfo.TargetLng);
Point seekPoint = map.LocationToViewportPoint(seekLocation);
if ((seekPoint.X > leftTopPoint.X && seekPoint.X < leftTopPoint.X + rectangle.Width) &&
seekPoint.Y > leftTopPoint.Y && seekPoint.Y < leftTopPoint.Y + rectangle.Height)
{
selectedCount++;
_copterManager.Select(taskCopterInfo.Copter);
}
}
_copterManager.shiftkeydown = false;
}
}
rectangle = null;
drawRectangle = false;
};
map.MouseLeave += (sender, e) =>
{
if (map.Children.Contains(rectangle))
{
map.Children.Remove(rectangle);
}
rectangle = null;
drawRectangle = false;
};
map.MouseMove += new MouseEventHandler(OriginalMove);
map.MouseLeftButtonUp += new MouseButtonEventHandler(OriginalMouseUp);
}
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private MapManager _mapManager = ServiceLocator.Current.GetInstance<MapManager>();
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
private AppConfig _appConfig = ServiceLocator.Current.GetInstance<AppConfig>();
const string COPTER_TAG = "Copter";
const string WAYPOINT_TAG = "Waypoint";
const string ORIGINALPOINT_TAG = "Originalpoint";
public void Refresh()
{
foreach (var drawing in _copterDrawings.Values)
{
drawing.Track.Locations.Clear();
}
}
public bool RemoveLoadingErrorMessage()
{
var errorElement = map.Children.OfType<LoadingErrorMessage>().FirstOrDefault();
if (errorElement != null)
{
map.Children.Remove(errorElement);
return true;
}
else
{
return false;
}
}
public void GoHome()
{
map.ZoomLevel = 19;
map.Center = new Location(40.0559055, 116.322233);
}
private void Copters_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
e.OldItems?.ForEach<ICopter>(async copter =>
{
copter.LocationChanged -= Copter_LocationChanged;
await Task.Delay(100); // 如果不等待一段时间Copter_DataStreamReceived 很可能再被调用一次。
RemoveCopter(copter);
});
e.NewItems?.ForEach<ICopter>(copter => copter.LocationChanged += Copter_LocationChanged);
}
private void Copter_LocationChanged(object sender, EventArgs e)
{
var copter = sender as ICopter;
if (App.Current.CheckAccess())
{
AddOrMoveCopter(copter);
}
else
{
App.Current.Dispatcher.InvokeAsync(() => AddOrMoveCopter(copter));
}
}
private Dictionary<ICopter, CopterDrawing> _copterDrawings = new Dictionary<ICopter, CopterDrawing>();
private void AddOrMoveCopter(ICopter copter)
{
var drawing = _copterDrawings.ContainsKey(copter) ?
_copterDrawings[copter] :
(_copterDrawings[copter] = new CopterDrawing(copter, map));
drawing.AddOrMoveCopter();
}
private void RemoveCopter(ICopter copter)
{
if (_copterDrawings.ContainsKey(copter))
{
var drawing = _copterDrawings[copter];
drawing.RemoveCopter();
_copterDrawings.Remove(copter);
}
}
public void ClearCopters()
{
for (int i = map.Children.Count - 1; i >= 0; i--)
{
if (!(map.Children[i] is MapTileLayer))
{
map.Children.RemoveAt(i);
}
}
_copterDrawings.Clear();
}
private bool IsMouseOnCopterOrWaypoint(object originalSource)
{
var elem = originalSource as FrameworkElement;
string tag;
while (elem != map && elem != null)
{
tag = elem.Tag?.ToString();
if (tag == COPTER_TAG || tag == WAYPOINT_TAG || tag == ORIGINALPOINT_TAG)
{
return true;
}
elem = elem.Parent as FrameworkElement;
}
return false;
}
private void FlightTaskManager_TaskAdded(object sender, FlightTaskAddedEventArgs e)
{
foreach (var info in e.AddedTask.SingleCopterInfos)
{
var drawingInfo = _copterDrawings[info.Copter];
var location = new Location(info.TargetLat, info.TargetLng, info.TargetAlt);
drawingInfo.AddWaypoint(location, e.AddedTask.TaskType);
}
}
Ellipse original = null;
private void FlightTaskManager_SetOriginal(object sender, FlightTaskAddedOriginalEventArgs e)
{
if (map.Children.Contains(original))
return;
Location location = new Location();
if (e.Lat == 0 && e.Lng == 0)
location = map.Center;
else
location = new Location(e.Lat, e.Lng);
original = new Ellipse
{
Tag = ORIGINALPOINT_TAG,
Fill = new SolidColorBrush(Color.FromRgb(0, 0, 0)),
StrokeThickness = 3,
Stroke = new SolidColorBrush(Color.FromRgb(255, 255, 255)),
Width = 18,
Height = 18,
};
map.Children.Add(original);
MapLayer.SetPosition(original, location);
original.ToolTip = location.ToString();
originaDrag = false;
_flightTaskManager.OriginLat = location.Latitude;
_flightTaskManager.OriginLng = location.Longitude;
original.MouseLeftButtonDown += new MouseButtonEventHandler(OriginalMouseDown);
}
private bool originaDrag = false;
double wpOffsetX = 0;
double wpOffsetY = 0;
private void OriginalMouseDown(object sender, MouseButtonEventArgs e)
{
originaDrag = true;
var posInObject = e.GetPosition(original);
wpOffsetX = posInObject.X;
wpOffsetY = posInObject.Y;
}
private void OriginalMove(object sender, MouseEventArgs e)
{
if (originaDrag)
{
Point eventPos = e.GetPosition(map);
var leftTopPos = new Point(eventPos.X - wpOffsetX, eventPos.Y - wpOffsetY);
MapLayer.SetPosition(original, map.ViewportPointToLocation(leftTopPos));
}
}
private void OriginalMouseUp(object sender, MouseButtonEventArgs e)
{
if (originaDrag)
{
Point eventPos = e.GetPosition(map);
Location location = map.ViewportPointToLocation(eventPos);
_flightTaskManager.OriginLat = location.Latitude;
_flightTaskManager.OriginLng = location.Longitude;
original.ToolTip = location.ToString();
Console.WriteLine("original-----------"+original.ToolTip);
Clipboard.SetDataObject(string.Format("{0},{1}", location.Latitude, location.Longitude), true);
originaDrag = false;
}
}
private void MapSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch ((e.AddedItems[0] as FrameworkElement).Tag.ToString())
{
case "卫星地图":
map.Mode = new AerialMode();
RemoveTileLayers();
break;
case "道路":
// map.Mode = new GoogleMode();
map.Mode = new RoadMode();
RemoveTileLayers();
break;
case "OpenStreet":
map.Mode = new MercatorMode();
if (!map.Children.OfType<OpenStreetMapTileLayer>().Any())
{
map.Children.Add(new OpenStreetMapTileLayer
{ UriFormat =
"http://tile.openstreetmap.org/{z}/{x}/{y}.png"
});
}
break;
}
}
private void showallpoint_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = (CheckBox)sender;
bool ischecked= chk.IsChecked ?? false;
foreach (var taskitme in _flightTaskManager.Tasks)
{
// if taskitme.IsRightSelected = chk.IsChecked ?? true;
if ((taskitme.IsRightSelected == ischecked) && (!taskitme.IsSelected))
{
_flightTaskManager.RightSelect(taskitme);
// TaskbarControl.setRightSelect(taskitme, ischecked);
}
}
}
private void showpanline_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = (CheckBox)sender;
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
copterDrawing.SetShowroute(chk.IsChecked);
}
}
private void showrealtimeline_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = (CheckBox)sender;
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
copterDrawing.SetShowtrack (chk.IsChecked);
}
}
private void RemoveTileLayers()
{
for (int i = map.Children.Count - 1; i >= 0; i--)
{
if (map.Children[i] is MapTileLayer)
{
map.Children.RemoveAt(i);
}
}
}
}
static class LocationExtensions
{
public static double CalcDistance(this Location loc1, Location loc2)
{
if (loc1 == null)
{
throw new ArgumentNullException(nameof(loc1));
}
if (loc2 == null)
{
throw new ArgumentNullException(nameof(loc2));
}
return GeographyUtils.CalcDistance(loc1.Latitude, loc1.Longitude, loc1.Altitude, loc2.Latitude, loc2.Longitude, loc2.Altitude);
}
}
}