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
{
///
/// Interaction logic for MapView.xaml
///
public partial class MapView : UserControl
{
public MapView()
{
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance();
_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();
private MapManager _mapManager = ServiceLocator.Current.GetInstance();
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance();
private AppConfig _appConfig = ServiceLocator.Current.GetInstance();
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().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(async copter =>
{
copter.LocationChanged -= Copter_LocationChanged;
await Task.Delay(100); // 如果不等待一段时间,Copter_DataStreamReceived 很可能再被调用一次。
RemoveCopter(copter);
});
e.NewItems?.ForEach(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 _copterDrawings = new Dictionary();
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().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);
}
}
}