using Emgu.CV;
using RichCreator.Utility;
using RichCreator.Utility.PathFindings;
using RichCreator.Utility.Structs;
using System;
using System.Collections.Generic;
using System.Linq;
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.Shapes;
using ZTImage;
namespace RichCreator.Editor.Tools
{
///
/// AStarTools.xaml 的交互逻辑
///
public partial class MapEditor : Window
{
public MapEditor()
{
InitializeComponent();
}
private bool isinit = false;//是否加载图片
private HousePathInfo housePathInfo = null;//房间信息
private bool moveable = false;//可移动的
private Line tempLine = null;//临时线
private Polyline tempPolyline = null;//临时障碍物
private System.Drawing.Image image = null;// 当前图像
private List startEndFindPathPoint = new List();//测试寻路起点和终点
#region 事件
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
///
/// 加载图片
///
///
///
private void OpenFromFile_Click(object sender, RoutedEventArgs e)
{
string imagePath = string.Empty;
Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
ofd.DefaultExt = ".jpg";
ofd.Filter = "image file|*.jpg;*.png;";
ofd.Multiselect = false;
if (ofd.ShowDialog() == true)
{
imagePath = ofd.FileName;
}
else
{
return;
}
Mat source = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Color);
this.image = source.Bitmap;
SetImage();
}
///
/// 复制JSON
///
///
///
private void CopyJSON_Click(object sender, RoutedEventArgs e)
{
if (!isinit)
{
return;
}
string json = this.housePathInfo.ToJsonString();
Clipboard.SetDataObject(json, true);
MessageBox.Show("copy success");
}
///
/// 从JSON创建
///
///
///
private void CreateFromJSON_Click(object sender, RoutedEventArgs e)
{
if (!isinit)
{
MessageBox.Show("请先加载图片");
return;
}
SerializeInput input = new SerializeInput();
if (input.ShowDialog() != true)
{
return;
}
var info = ZTImage.Json.JsonParser.ToObject(input.ColorString);
if (info == null)
{
return;
}
//依次加载,障碍物,定位点,寻路点,巡逻线,寻路线
//加载障碍物
for (int i = 0; i < info.Obstacles.Count; i++)
{
Polygon polygon=CreateObstacleUI(info.Obstacles[i]);
this.HouseInfoLayer.Children.Add(polygon);
}
//加载定位点
for (int i = 0; i < info.LocationPoints.Count; i++)
{
Canvas lp = CreateLocationPointUI(info.LocationPoints[i]);
this.HouseInfoLayer.Children.Add(lp);
}
//加载寻路点
for (int i = 0; i < info.FindPathPoints.Count; i++)
{
Canvas fp = CreateFindPathPointUI(info.FindPathPoints[i]);
this.HouseInfoLayer.Children.Add(fp);
}
//加载巡逻线
for (int i = 0; i < info.LoopLines.Count; i++)
{
Line llline = CreateLoopLineUI(info.LoopLines[i]);
this.HouseInfoLayer.Children.Add(llline);
}
//加载寻路线
for (int i = 0; i < info.FindPathLines.Count; i++)
{
Line fpline = CreateFindPathLineUI(info.FindPathLines[i]);
this.HouseInfoLayer.Children.Add(fpline);
}
this.housePathInfo = info;
}
///
/// 清理定位点
///
///
///
private void ClearPosition_Click(object sender, RoutedEventArgs e)
{
if (!isinit)
{
return;
}
this.LocationPointLayer.Children.Clear();
this.housePathInfo.ClearLocationPosiltion();
}
///
/// 清空寻路测试点的起点和终点
///
///
///
private void ClearStartEndPoint_Click(object sender, RoutedEventArgs e)
{
if (!isinit)
{
return;
}
this.StartEndPointLayer.Children.Clear();
this.startEndFindPathPoint.Clear();
}
///
/// 测试寻路
///
///
///
private void TestFindPath_Click(object sender, RoutedEventArgs e)
{
if (this.startEndFindPathPoint.Count < 2)
{
MessageBox.Show("请选择测试的起点和终点");
}
ZTPoint start = this.startEndFindPathPoint[0];
ZTPoint end = this.startEndFindPathPoint[1];
List path=this.housePathInfo.FindPath(start, end);
//todo:绘制路径
}
///
/// 鼠标按下
///
///
///
private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e)
{
if (!isinit)
{
return;
}
//是否添加障碍物
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
Int32 number = TypeConverter.StringToInt(this.tagNumber.Text, 0);
if (e.LeftButton == MouseButtonState.Released)
{
return;
}
Point point = GetPosition(e);
if (op == OperateActionD.Obstacle)
{
//障碍物
}
else if (op == OperateActionD.LocationPoint)
{
//定位点
ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), number);
if (this.housePathInfo.AddLocationPosition(lp))
{
Canvas lpControl = CreateLocationPointUI(lp);
this.LocationPointLayer.Children.Add(lpControl);
}
}
else if (op == OperateActionD.FindPathPoint)
{
//寻路点
ZTPoint fp = new ZTPoint((Int32)point.X, (Int32)point.Y);
if (this.housePathInfo.AddFindPathPoint(fp))
{
Canvas fpControl = CreateFindPathPointUI(fp);
this.HouseInfoLayer.Children.Add(fpControl);
}
}
else if (op == OperateActionD.LoopLine)
{
//循环线
ZTPoint llPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y));
if (!llPoint.Equals(ZTPoint.Empty))
{
tempLine = CreateTempLoopLineUI(llPoint);
this.HouseInfoLayer.Children.Add(tempLine);
moveable = true;
}
}
else if (op == OperateActionD.FindPathLine)
{
//寻路线
ZTPoint fpPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y));
if (!fpPoint.Equals(ZTPoint.Empty))
{
tempLine = CreateTempFindPathLineUI(fpPoint);
this.HouseInfoLayer.Children.Add(tempLine);
moveable = true;
}
}
else if (op == OperateActionD.StartEndPoint)
{
//画寻路起始和终点
ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y);
Canvas lseControl = CreateStartEndPointUI(sepoint);
this.StartEndPointLayer.Children.Add(lseControl);
this.startEndFindPathPoint.Add(sepoint);
}
}
///
/// 鼠标移动
///
///
///
private void SourceImage_MouseMove(object sender, MouseEventArgs e)
{
if (!isinit)
{
return;
}
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
Point point = GetPosition(e);
if (op == OperateActionD.LoopLine)
{
//巡逻线
if (!moveable)
{
return;
}
tempLine.X2 = point.X;
tempLine.Y2 = point.Y;
}
else if (op == OperateActionD.FindPathLine)
{
//寻路线
if (!moveable)
{
return;
}
tempLine.X2 = point.X;
tempLine.Y2 = point.Y;
}
else if (op == OperateActionD.Obstacle)
{
//障碍物线
if (!moveable)
{
return;
}
tempLine.X2 = point.X;
tempLine.Y2 = point.Y;
}
}
///
/// 鼠标提起
///
///
///
private void SourceImage_MouseUp(object sender, MouseButtonEventArgs e)
{
if (!isinit)
{
return;
}
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
Point point = GetPosition(e);
if (op == OperateActionD.LoopLine)
{
//巡逻线
if (!moveable)
{
return;
}
moveable = false;
if (tempLine == null)
{
return;
}
ZTPoint startPoint = (ZTPoint)tempLine.Tag;
ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y));
if (!centerPoint.Equals(ZTPoint.Empty))
{
ZTLinePoint ll = new ZTLinePoint(startPoint, centerPoint);
if (this.housePathInfo.AddLoopLine(ll))
{
Line llline = CreateLoopLineUI(ll);
this.HouseInfoLayer.Children.Add(llline);
}
}
this.HouseInfoLayer.Children.Remove(tempLine);
tempLine = null;
}
else if (op == OperateActionD.FindPathLine)
{
//寻路线
if (!moveable)
{
return;
}
moveable = false;
if (tempLine == null)
{
return;
}
ZTPoint startPoint = (ZTPoint)tempLine.Tag;
ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y));
if (!centerPoint.Equals(ZTPoint.Empty))
{
ZTLinePoint fp = new ZTLinePoint(startPoint, centerPoint);
if (this.housePathInfo.AddFindPathLine(fp))
{
Line fpline = CreateFindPathLineUI(fp);
this.HouseInfoLayer.Children.Add(fpline);
}
}
this.HouseInfoLayer.Children.Remove(tempLine);
tempLine = null;
}
else if (op == OperateActionD.Obstacle)
{
//绘制障碍物
//判断是否起点
if (tempPolyline == null)
{
//首次画
this.points.Add(point);
this.tempPolyline = CreateTempObstacleUI(point);
this.tempLine = CreateObstacleLineUI(new ZTPoint((Int32)point.X, (Int32)point.Y));
moveable = true;
this.HouseInfoLayer.Children.Add(this.tempPolyline);
this.HouseInfoLayer.Children.Add(this.tempLine);
}
else
{
if (IsLastPoint(point))
{
//判断是否跟最后一个点重合,如果重合则不处理
//判断是否只有两个点,如果是则不处理
return;
}
if (IsFirstPoint(point) && this.points.Count > 2)
{
//到起点,完成,向houseinfo里添加障碍物 ,画折线,
ZTPoint[] obstaclePoints = new ZTPoint[this.points.Count];
for (int i = 0; i < this.points.Count; i++)
{
obstaclePoints[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y);
}
ZTPolygon ztpolygon = new ZTPolygon(obstaclePoints);
this.housePathInfo.AddObstacle(ztpolygon);
Polygon polygon = CreateObstacleUI(ztpolygon);
this.HouseInfoLayer.Children.Add(polygon);
this.HouseInfoLayer.Children.Remove(tempPolyline);
tempPolyline = null;
this.HouseInfoLayer.Children.Remove(tempLine);
tempLine = null;
this.points.Clear();
moveable = false;
}
else
{
//向points里添加障碍点,画折线,更新tempLine,
this.points.Add(point);
//画折线
this.tempPolyline.Points.Add(point);
//更新tempLine
tempLine.X1 = point.X;
tempLine.Y1 = point.Y;
tempLine.X2 = point.X;
tempLine.Y2 = point.Y;
}
}
}
}
#endregion
#region createUI
///
/// 设置图像
///
///
///
private void SetImage()
{
BitmapImage t = ImageHelper.BitmapToImageSource(image);
this.SourceImage.Source = t;
mainContainer.Width = image.Width;
mainContainer.Height = image.Height;
this.housePathInfo = new HousePathInfo(image.Width, image.Height);
System.Threading.ThreadPool.QueueUserWorkItem((obj) =>
{
System.Threading.Thread.Sleep(1000);
isinit = true;
});
}
///
/// 创建定位点UI
/// 外方内圆
///
private Canvas CreateLocationPointUI(ParametersPoint point)
{
//
Canvas main = new Canvas();
main.Tag = point;
Canvas.SetLeft(main, point.Point.X);
Canvas.SetTop(main, point.Point.Y);
Rectangle rect = new Rectangle();
Canvas.SetLeft(rect, -10);
Canvas.SetTop(rect, -10);
rect.Width = 20;
rect.Height = 20;
rect.Stroke = new SolidColorBrush(Colors.Red);
rect.StrokeThickness = 1;
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Opacity = 0.5f;
main.Children.Add(rect);
Ellipse elli = new Ellipse();
Canvas.SetLeft(elli, -2);
Canvas.SetTop(elli, -2);
elli.Width = 4;
elli.Height = 4;
elli.Stroke = new SolidColorBrush(Colors.Black);
elli.StrokeThickness = 1;
elli.Fill = new SolidColorBrush(Colors.Black);
main.Children.Add(elli);
TextBlock tb = new TextBlock();
tb.Text = point.Parameter.ToString();
tb.FontSize = 9;
main.Children.Add(tb);
return main;
}
///
/// 创建寻路点UI
///
private Canvas CreateFindPathPointUI(ZTPoint findPathPoint)
{
//
Canvas main = new Canvas();
main.Tag = findPathPoint;
main.MouseRightButtonUp += FindPathPoint_MouseRightButtonUp;
Canvas.SetLeft(main, findPathPoint.X);
Canvas.SetTop(main, findPathPoint.Y);
Ellipse elli = new Ellipse();
Canvas.SetLeft(elli, -10);
Canvas.SetTop(elli, -10);
elli.Width = 20;
elli.Height = 20;
elli.Stroke = new SolidColorBrush(Colors.Red);
elli.StrokeThickness = 1;
elli.Fill = new SolidColorBrush(Colors.Red);
elli.Opacity = 0.5f;
main.Children.Add(elli);
Rectangle rect = new Rectangle();
Canvas.SetLeft(rect, -2);
Canvas.SetTop(rect, -2);
rect.Width = 4;
rect.Height = 4;
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.StrokeThickness = 1;
rect.Fill = new SolidColorBrush(Colors.Black);
rect.StrokeThickness = 1;
main.Children.Add(rect);
return main;
}
///
/// 寻路点右击
///
///
///
private void FindPathPoint_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
Canvas c = sender as Canvas;
if (c == null)
{
return;
}
ZTPoint fp = default(ZTPoint);
try
{
fp = (ZTPoint)c.Tag;
}
catch
{
return;
}
if (this.housePathInfo.RemoveFindPathPoint(fp))
{
this.HouseInfoLayer.Children.Remove(c);
}
}
///
/// 创建巡逻线UI
///
private Line CreateLoopLineUI(ZTLinePoint linePoint)
{
Line edgeLine = new Line();
edgeLine.Tag = linePoint;
edgeLine.MouseRightButtonUp += LoopLine_MouseRightButtonUp;
edgeLine.Stroke = new SolidColorBrush(Colors.Red);
edgeLine.StrokeThickness = 6;
edgeLine.X1 = linePoint.X1;
edgeLine.Y1 = linePoint.Y1;
edgeLine.X2 = linePoint.X2;
edgeLine.Y2 = linePoint.Y2;
edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 };
edgeLine.StrokeDashCap = PenLineCap.Triangle;
edgeLine.StrokeEndLineCap = PenLineCap.Square;
edgeLine.StrokeStartLineCap = PenLineCap.Round;
return edgeLine;
}
///
/// 巡逻线右击
///
///
///
private void LoopLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
Line c = sender as Line;
if (c == null)
{
return;
}
ZTLinePoint fp = default(ZTLinePoint);
try
{
fp = (ZTLinePoint)c.Tag;
}
catch
{
return;
}
if (this.housePathInfo.RemoveLoopLine(fp))
{
this.HouseInfoLayer.Children.Remove(c);
}
}
///
/// 创建临时巡逻线UI
///
///
///
private Line CreateTempLoopLineUI(ZTPoint point)
{
Line edgeLine = new Line();
edgeLine.Tag = point;
edgeLine.Stroke = new SolidColorBrush(Colors.Red);
edgeLine.StrokeThickness = 3;
edgeLine.X1 = point.X;
edgeLine.Y1 = point.Y;
edgeLine.X2 = point.X;
edgeLine.Y2 = point.Y;
edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 };
edgeLine.StrokeDashCap = PenLineCap.Triangle;
edgeLine.StrokeEndLineCap = PenLineCap.Square;
edgeLine.StrokeStartLineCap = PenLineCap.Round;
return edgeLine;
}
///
/// 创建寻路线UI
///
private Line CreateFindPathLineUI(ZTLinePoint linePoint)
{
Line edgeLine = new Line();
edgeLine.Tag = linePoint;
edgeLine.MouseRightButtonUp += FindPathLine_MouseRightButtonUp; ;
edgeLine.Stroke = new SolidColorBrush(Colors.Red);
edgeLine.StrokeThickness = 3;
edgeLine.X1 = linePoint.X1;
edgeLine.Y1 = linePoint.Y1;
edgeLine.X2 = linePoint.X2;
edgeLine.Y2 = linePoint.Y2;
return edgeLine;
}
///
/// 寻路线右键
///
///
///
private void FindPathLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
Line c = sender as Line;
if (c == null)
{
return;
}
ZTLinePoint fp = default(ZTLinePoint);
try
{
fp = (ZTLinePoint)c.Tag;
}
catch
{
return;
}
if (this.housePathInfo.RemoveFindPathLine(fp))
{
this.HouseInfoLayer.Children.Remove(c);
}
}
///
/// 创建临时寻路线UI
///
///
///
private Line CreateTempFindPathLineUI(ZTPoint point)
{
Line edgeLine = new Line();
edgeLine.Tag = point;
edgeLine.Stroke = new SolidColorBrush(Colors.Red);
edgeLine.StrokeThickness = 3;
edgeLine.X1 = point.X;
edgeLine.Y1 = point.Y;
edgeLine.X2 = point.X;
edgeLine.Y2 = point.Y;
return edgeLine;
}
///
/// 创建临时障碍物UI
///
///
private Polyline CreateTempObstacleUI(Point point)
{
//
Polyline polyline = new Polyline();
polyline.StrokeThickness = 1;
polyline.Stroke = new SolidColorBrush(Colors.Black);
polyline.Opacity = 0.5f;
polyline.Points.Add(point);
return polyline;
}
///
/// 创建障碍物UI
///
///
private Polygon CreateObstacleUI(ZTPolygon ztpolygon)
{
//
Polygon polygon = new Polygon();
polygon.Tag = ztpolygon;
polygon.MouseRightButtonUp += Polygon_MouseRightButtonUp;
polygon.StrokeThickness = 1;
polygon.Stroke = new SolidColorBrush(Colors.Black);
polygon.Fill = new SolidColorBrush(Colors.Black);
polygon.Opacity = 0.7f;
for (int i = 0; i < this.points.Count; i++)
{
polygon.Points.Add(this.points[i]);
}
return polygon;
}
///
/// 障碍物右键删除
///
///
///
private void Polygon_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
Polygon c = sender as Polygon;
if (c == null)
{
return;
}
ZTPolygon ztp = default(ZTPolygon);
try
{
ztp = (ZTPolygon)c.Tag;
}
catch
{
return;
}
if (this.housePathInfo.RemoveObstacle(ztp))
{
this.HouseInfoLayer.Children.Remove(c);
}
}
///
/// 创建临时障碍物线UI
///
///
///
private Line CreateObstacleLineUI(ZTPoint point)
{
Line edgeLine = new Line();
edgeLine.Tag = point;
edgeLine.Stroke = new SolidColorBrush(Colors.Black);
edgeLine.StrokeThickness = 1;
edgeLine.X1 = point.X;
edgeLine.Y1 = point.Y;
edgeLine.X2 = point.X;
edgeLine.Y2 = point.Y;
return edgeLine;
}
///
/// 获取当前位置点
///
///
///
private ZTPoint GetFindPathPoint(ZTPoint point)
{
ZTPoint temp = ZTPoint.Empty;
for (int i = 0; i < this.housePathInfo.FindPathPoints.Count; i++)
{
temp = this.housePathInfo.FindPathPoints[i];
if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10)
{
return temp;
}
}
return ZTPoint.Empty;
}
///
/// 创建起始和终止寻路点
///
///
///
private Canvas CreateStartEndPointUI(ZTPoint point)
{
Canvas main = new Canvas();
main.Tag = point;
Canvas.SetLeft(main, point.X);
Canvas.SetTop(main, point.Y);
Rectangle rect = new Rectangle();
Canvas.SetLeft(rect, -10);
Canvas.SetTop(rect, -10);
rect.Width = 20;
rect.Height = 20;
rect.Stroke = new SolidColorBrush(Colors.Green);
rect.StrokeThickness = 1;
rect.Fill = new SolidColorBrush(Colors.Green);
rect.Opacity = 0.5f;
main.Children.Add(rect);
Ellipse elli = new Ellipse();
Canvas.SetLeft(elli, -2);
Canvas.SetTop(elli, -2);
elli.Width = 4;
elli.Height = 4;
elli.Stroke = new SolidColorBrush(Colors.Black);
elli.StrokeThickness = 1;
elli.Fill = new SolidColorBrush(Colors.Black);
main.Children.Add(elli);
return main;
}
#endregion
#region Tools
///
/// 计算当前鼠标位置和颜色
///
///
///
///
///
private Point GetPosition(MouseEventArgs e)
{
Point point = e.GetPosition(this.scrollViewer);
Int32 x = (Int32)Math.Round(this.scrollViewer.HorizontalOffset + point.X);
Int32 y = (Int32)Math.Round(this.scrollViewer.VerticalOffset + point.Y);
return new Point(x, y);
}
private List points = new List();
///
/// 是否第一个点
///
///
///
private bool IsFirstPoint(Point point)
{
Point temp = this.points[0];
if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10)
{
return true;
}
return false;
}
///
/// 是否最后一个点
///
///
///
private bool IsLastPoint(Point point)
{
Point temp = this.points[this.points.Count - 1];
if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10)
{
return true;
}
return false;
}
#endregion
///
/// 操作类型
///
public enum OperateActionD
{
Obstacle = 0,//障碍物
LocationPoint,//定位点
FindPathPoint,//寻路点
LoopLine,//循环线
FindPathLine,//寻路线
StartEndPoint,//测试起终点
}
}
}