1471 lines
47 KiB
C#
1471 lines
47 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Xml.Serialization;
|
||
using Autodesk.Navisworks.Api;
|
||
using System.Text;
|
||
using System.Linq;
|
||
|
||
namespace NavisworksTransport
|
||
{
|
||
/// <summary>
|
||
/// 路径点类型枚举
|
||
/// </summary>
|
||
public enum PathPointType
|
||
{
|
||
/// <summary>
|
||
/// 起点
|
||
/// </summary>
|
||
StartPoint,
|
||
|
||
/// <summary>
|
||
/// 终点
|
||
/// </summary>
|
||
EndPoint,
|
||
|
||
/// <summary>
|
||
/// 路径点
|
||
/// </summary>
|
||
WayPoint
|
||
}
|
||
|
||
/// <summary>
|
||
/// 路径点数据模型
|
||
/// </summary>
|
||
[Serializable]
|
||
public class PathPoint
|
||
{
|
||
/// <summary>
|
||
/// 路径点唯一标识符
|
||
/// </summary>
|
||
public string Id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 3D位置坐标
|
||
/// </summary>
|
||
public Point3D Position { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径点名称
|
||
/// </summary>
|
||
public string Name { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径点类型
|
||
/// </summary>
|
||
public PathPointType Type { get; set; }
|
||
|
||
/// <summary>
|
||
/// 创建时间
|
||
/// </summary>
|
||
public DateTime CreatedTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径点序号
|
||
/// </summary>
|
||
public int Index { get; set; }
|
||
|
||
/// <summary>
|
||
/// 备注信息
|
||
/// </summary>
|
||
public string Notes { get; set; }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public PathPoint()
|
||
{
|
||
Id = Guid.NewGuid().ToString();
|
||
Position = new Point3D();
|
||
Name = string.Empty;
|
||
Type = PathPointType.WayPoint;
|
||
CreatedTime = DateTime.Now;
|
||
Index = 0;
|
||
Notes = string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带参数构造函数
|
||
/// </summary>
|
||
/// <param name="position">3D坐标</param>
|
||
/// <param name="name">名称</param>
|
||
/// <param name="type">类型</param>
|
||
public PathPoint(Point3D position, string name, PathPointType type)
|
||
{
|
||
Id = Guid.NewGuid().ToString();
|
||
Position = position;
|
||
Name = name;
|
||
Type = type;
|
||
CreatedTime = DateTime.Now;
|
||
Index = 0;
|
||
Notes = string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回路径点描述字符串
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override string ToString()
|
||
{
|
||
return $"{Name} ({Type}) - X:{Position.X:F2}, Y:{Position.Y:F2}, Z:{Position.Z:F2}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 路径路线数据模型
|
||
/// </summary>
|
||
[Serializable]
|
||
public class PathRoute
|
||
{
|
||
/// <summary>
|
||
/// 路径点集合
|
||
/// </summary>
|
||
public List<PathPoint> Points { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径名称
|
||
/// </summary>
|
||
public string Name { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径ID
|
||
/// </summary>
|
||
public string Id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 预估时间(秒)
|
||
/// </summary>
|
||
public double EstimatedTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 关联通道模型ID集合
|
||
/// </summary>
|
||
public List<string> AssociatedChannelIds { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径总长度(米)
|
||
/// </summary>
|
||
public double TotalLength { get; set; }
|
||
|
||
/// <summary>
|
||
/// 创建时间
|
||
/// </summary>
|
||
public DateTime CreatedTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 最后修改时间
|
||
/// </summary>
|
||
public DateTime LastModified { get; set; }
|
||
|
||
/// <summary>
|
||
/// 路径描述
|
||
/// </summary>
|
||
public string Description { get; set; }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public PathRoute()
|
||
{
|
||
Points = new List<PathPoint>();
|
||
Name = string.Empty;
|
||
Id = Guid.NewGuid().ToString();
|
||
EstimatedTime = 0.0;
|
||
AssociatedChannelIds = new List<string>();
|
||
TotalLength = 0.0;
|
||
CreatedTime = DateTime.Now;
|
||
LastModified = DateTime.Now;
|
||
Description = string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带参数构造函数
|
||
/// </summary>
|
||
/// <param name="name">路径名称</param>
|
||
public PathRoute(string name)
|
||
{
|
||
Points = new List<PathPoint>();
|
||
Name = name;
|
||
Id = Guid.NewGuid().ToString();
|
||
EstimatedTime = 0.0;
|
||
AssociatedChannelIds = new List<string>();
|
||
TotalLength = 0.0;
|
||
CreatedTime = DateTime.Now;
|
||
LastModified = DateTime.Now;
|
||
Description = string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加路径点
|
||
/// </summary>
|
||
/// <param name="point">路径点</param>
|
||
public void AddPoint(PathPoint point)
|
||
{
|
||
point.Index = Points.Count;
|
||
Points.Add(point);
|
||
LastModified = DateTime.Now;
|
||
UpdateTotalLength();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除路径点
|
||
/// </summary>
|
||
/// <param name="point">路径点</param>
|
||
public bool RemovePoint(PathPoint point)
|
||
{
|
||
bool removed = Points.Remove(point);
|
||
if (removed)
|
||
{
|
||
// 重新设置索引
|
||
for (int i = 0; i < Points.Count; i++)
|
||
{
|
||
Points[i].Index = i;
|
||
}
|
||
LastModified = DateTime.Now;
|
||
UpdateTotalLength();
|
||
}
|
||
return removed;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据ID移除路径点
|
||
/// </summary>
|
||
/// <param name="pointId">路径点ID</param>
|
||
/// <returns>是否成功移除</returns>
|
||
public bool RemovePoint(string pointId)
|
||
{
|
||
var point = Points.FirstOrDefault(p => p.Id == pointId);
|
||
if (point != null)
|
||
{
|
||
return RemovePoint(point);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清空所有路径点
|
||
/// </summary>
|
||
public void ClearPoints()
|
||
{
|
||
Points.Clear();
|
||
LastModified = DateTime.Now;
|
||
UpdateTotalLength();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取起点
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public PathPoint GetStartPoint()
|
||
{
|
||
return Points.Find(p => p.Type == PathPointType.StartPoint);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取终点
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public PathPoint GetEndPoint()
|
||
{
|
||
return Points.Find(p => p.Type == PathPointType.EndPoint);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有路径点(按序号排序)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public List<PathPoint> GetSortedPoints()
|
||
{
|
||
var sortedPoints = new List<PathPoint>(Points);
|
||
sortedPoints.Sort((p1, p2) => p1.Index.CompareTo(p2.Index));
|
||
return sortedPoints;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重新计算路径长度
|
||
/// </summary>
|
||
public void RecalculateLength()
|
||
{
|
||
UpdateTotalLength();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新路径总长度
|
||
/// </summary>
|
||
private void UpdateTotalLength()
|
||
{
|
||
TotalLength = 0.0;
|
||
var sortedPoints = GetSortedPoints();
|
||
|
||
for (int i = 0; i < sortedPoints.Count - 1; i++)
|
||
{
|
||
var point1 = sortedPoints[i].Position;
|
||
var point2 = sortedPoints[i + 1].Position;
|
||
|
||
// 计算两点间距离
|
||
double dx = point2.X - point1.X;
|
||
double dy = point2.Y - point1.Y;
|
||
double dz = point2.Z - point1.Z;
|
||
double distance = Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||
|
||
TotalLength += distance;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证路径有效性
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsValid()
|
||
{
|
||
// 至少需要起点和终点
|
||
if (Points.Count < 2) return false;
|
||
|
||
// 必须有且仅有一个起点和一个终点
|
||
var startPoints = Points.FindAll(p => p.Type == PathPointType.StartPoint);
|
||
var endPoints = Points.FindAll(p => p.Type == PathPointType.EndPoint);
|
||
|
||
return startPoints.Count == 1 && endPoints.Count == 1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 克隆路径
|
||
/// </summary>
|
||
/// <returns>克隆的路径对象</returns>
|
||
public PathRoute Clone()
|
||
{
|
||
var clonedRoute = new PathRoute(Name + "_Copy")
|
||
{
|
||
Id = Guid.NewGuid().ToString(),
|
||
EstimatedTime = EstimatedTime,
|
||
TotalLength = TotalLength,
|
||
CreatedTime = CreatedTime,
|
||
LastModified = DateTime.Now,
|
||
Description = Description,
|
||
AssociatedChannelIds = new List<string>(AssociatedChannelIds)
|
||
};
|
||
|
||
// 克隆所有路径点
|
||
foreach (var point in Points)
|
||
{
|
||
var clonedPoint = new PathPoint(point.Position, point.Name, point.Type)
|
||
{
|
||
Id = Guid.NewGuid().ToString(),
|
||
Index = point.Index,
|
||
CreatedTime = point.CreatedTime,
|
||
Notes = point.Notes
|
||
};
|
||
clonedRoute.Points.Add(clonedPoint);
|
||
}
|
||
|
||
return clonedRoute;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回路径描述字符串
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override string ToString()
|
||
{
|
||
return $"{Name} - 点数:{Points.Count}, 长度:{TotalLength:F2}m, 预估时间:{EstimatedTime:F1}s";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 2D地图坐标
|
||
/// </summary>
|
||
[Serializable]
|
||
public class MapPoint2D
|
||
{
|
||
/// <summary>
|
||
/// X坐标
|
||
/// </summary>
|
||
public double X { get; set; }
|
||
|
||
/// <summary>
|
||
/// Y坐标
|
||
/// </summary>
|
||
public double Y { get; set; }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public MapPoint2D()
|
||
{
|
||
X = 0.0;
|
||
Y = 0.0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带参数构造函数
|
||
/// </summary>
|
||
/// <param name="x">X坐标</param>
|
||
/// <param name="y">Y坐标</param>
|
||
public MapPoint2D(double x, double y)
|
||
{
|
||
X = x;
|
||
Y = y;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回坐标描述字符串
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override string ToString()
|
||
{
|
||
return $"({X:F2}, {Y:F2})";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道边界信息
|
||
/// </summary>
|
||
[Serializable]
|
||
public class ChannelBounds
|
||
{
|
||
/// <summary>
|
||
/// 最小坐标点
|
||
/// </summary>
|
||
public Point3D MinPoint { get; set; }
|
||
|
||
/// <summary>
|
||
/// 最大坐标点
|
||
/// </summary>
|
||
public Point3D MaxPoint { get; set; }
|
||
|
||
/// <summary>
|
||
/// 中心点
|
||
/// </summary>
|
||
public Point3D Center { get; set; }
|
||
|
||
/// <summary>
|
||
/// 通道高度(Z轴方向)
|
||
/// </summary>
|
||
public double Height { get; set; }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public ChannelBounds()
|
||
{
|
||
MinPoint = new Point3D();
|
||
MaxPoint = new Point3D();
|
||
Center = new Point3D();
|
||
Height = 0.0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带包围盒参数构造函数
|
||
/// </summary>
|
||
/// <param name="boundingBox">Navisworks包围盒</param>
|
||
public ChannelBounds(BoundingBox3D boundingBox)
|
||
{
|
||
MinPoint = boundingBox.Min;
|
||
MaxPoint = boundingBox.Max;
|
||
Center = new Point3D(
|
||
(MinPoint.X + MaxPoint.X) / 2,
|
||
(MinPoint.Y + MaxPoint.Y) / 2,
|
||
(MinPoint.Z + MaxPoint.Z) / 2
|
||
);
|
||
Height = MaxPoint.Z - MinPoint.Z;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取2D投影范围
|
||
/// </summary>
|
||
/// <param name="min">最小点</param>
|
||
/// <param name="max">最大点</param>
|
||
public void Get2DProjection(out MapPoint2D min, out MapPoint2D max)
|
||
{
|
||
min = new MapPoint2D(MinPoint.X, MinPoint.Y);
|
||
max = new MapPoint2D(MaxPoint.X, MaxPoint.Y);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道选择结果
|
||
/// </summary>
|
||
public class ChannelSelectionResult
|
||
{
|
||
/// <summary>
|
||
/// 是否成功
|
||
/// </summary>
|
||
public bool Success { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 结果消息
|
||
/// </summary>
|
||
public string Message { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 总模型项数量
|
||
/// </summary>
|
||
public int TotalModelItems { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 自动检测的通道
|
||
/// </summary>
|
||
public ModelItemCollection AutoDetectedChannels { get; set; } = new ModelItemCollection();
|
||
|
||
/// <summary>
|
||
/// 已标记物流属性的模型项
|
||
/// </summary>
|
||
public ModelItemCollection LogisticsMarkedItems { get; set; } = new ModelItemCollection();
|
||
|
||
/// <summary>
|
||
/// 可通行区域
|
||
/// </summary>
|
||
public ModelItemCollection TraversableAreas { get; set; } = new ModelItemCollection();
|
||
|
||
/// <summary>
|
||
/// 通道类型模型项
|
||
/// </summary>
|
||
public ModelItemCollection ChannelItems { get; set; } = new ModelItemCollection();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道选择对话框结果
|
||
/// </summary>
|
||
public class ChannelSelectionDialogResult
|
||
{
|
||
/// <summary>
|
||
/// 是否成功
|
||
/// </summary>
|
||
public bool Success { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 结果消息
|
||
/// </summary>
|
||
public string Message { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 选中的通道
|
||
/// </summary>
|
||
public ModelItemCollection SelectedChannels { get; set; } = new ModelItemCollection();
|
||
|
||
/// <summary>
|
||
/// 选择方法
|
||
/// </summary>
|
||
public ChannelSelectionMethod SelectionMethod { get; set; } = ChannelSelectionMethod.Manual;
|
||
|
||
/// <summary>
|
||
/// 车辆尺寸
|
||
/// </summary>
|
||
public string VehicleSize { get; set; } = "标准";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道选择方法枚举
|
||
/// </summary>
|
||
public enum ChannelSelectionMethod
|
||
{
|
||
/// <summary>
|
||
/// 手动选择
|
||
/// </summary>
|
||
Manual,
|
||
|
||
/// <summary>
|
||
/// 自动检测
|
||
/// </summary>
|
||
AutoDetect,
|
||
|
||
/// <summary>
|
||
/// 基于物流属性
|
||
/// </summary>
|
||
LogisticsAttribute,
|
||
|
||
/// <summary>
|
||
/// 可通行区域
|
||
/// </summary>
|
||
TraversableAreas,
|
||
|
||
/// <summary>
|
||
/// 通道类型
|
||
/// </summary>
|
||
ChannelType
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道选择对话框
|
||
/// </summary>
|
||
public class ChannelSelectionDialog : System.Windows.Forms.Form
|
||
{
|
||
private ChannelSelectionResult _analysisResult;
|
||
private ModelItemCollection _selectedChannels;
|
||
private ChannelSelectionMethod _selectionMethod;
|
||
private string _vehicleSize;
|
||
|
||
/// <summary>
|
||
/// 选中的通道
|
||
/// </summary>
|
||
public ModelItemCollection SelectedChannels { get { return _selectedChannels; } }
|
||
|
||
/// <summary>
|
||
/// 选择方法
|
||
/// </summary>
|
||
public ChannelSelectionMethod SelectionMethod { get { return _selectionMethod; } }
|
||
|
||
/// <summary>
|
||
/// 车辆尺寸
|
||
/// </summary>
|
||
public string VehicleSize { get { return _vehicleSize; } }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="analysisResult">通道分析结果</param>
|
||
public ChannelSelectionDialog(ChannelSelectionResult analysisResult)
|
||
{
|
||
_analysisResult = analysisResult ?? new ChannelSelectionResult();
|
||
_selectedChannels = new ModelItemCollection();
|
||
_selectionMethod = ChannelSelectionMethod.Manual;
|
||
_vehicleSize = "标准";
|
||
|
||
InitializeComponent();
|
||
LoadAnalysisData();
|
||
}
|
||
|
||
// UI控件
|
||
private System.Windows.Forms.TabControl tabControl;
|
||
private System.Windows.Forms.ListView channelListView;
|
||
private System.Windows.Forms.Label statisticsLabel;
|
||
private System.Windows.Forms.ComboBox vehicleSizeComboBox;
|
||
private System.Windows.Forms.Button previewButton;
|
||
private System.Windows.Forms.Button clearHighlightButton;
|
||
private System.Windows.Forms.CheckBox selectAllCheckBox;
|
||
|
||
/// <summary>
|
||
/// 初始化对话框组件
|
||
/// </summary>
|
||
private void InitializeComponent()
|
||
{
|
||
this.Text = "通道选择";
|
||
this.Size = new System.Drawing.Size(700, 500);
|
||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||
this.MaximizeBox = false;
|
||
this.MinimizeBox = false;
|
||
|
||
// 创建选项卡控件
|
||
tabControl = new System.Windows.Forms.TabControl
|
||
{
|
||
Location = new System.Drawing.Point(10, 10),
|
||
Size = new System.Drawing.Size(670, 350),
|
||
Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left |
|
||
System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom
|
||
};
|
||
|
||
// 创建通道列表选项卡
|
||
var channelListTab = new System.Windows.Forms.TabPage("通道列表");
|
||
CreateChannelListTab(channelListTab);
|
||
tabControl.TabPages.Add(channelListTab);
|
||
|
||
// 创建筛选选项卡
|
||
var filterTab = new System.Windows.Forms.TabPage("筛选选项");
|
||
CreateFilterTab(filterTab);
|
||
tabControl.TabPages.Add(filterTab);
|
||
|
||
this.Controls.Add(tabControl);
|
||
|
||
// 统计信息标签
|
||
statisticsLabel = new System.Windows.Forms.Label
|
||
{
|
||
Location = new System.Drawing.Point(10, 370),
|
||
Size = new System.Drawing.Size(400, 60),
|
||
Text = "正在加载通道信息...",
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
|
||
};
|
||
this.Controls.Add(statisticsLabel);
|
||
|
||
// 预览按钮
|
||
previewButton = new System.Windows.Forms.Button
|
||
{
|
||
Text = "预览选中",
|
||
Size = new System.Drawing.Size(80, 25),
|
||
Location = new System.Drawing.Point(420, 370),
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
|
||
};
|
||
previewButton.Click += PreviewButton_Click;
|
||
this.Controls.Add(previewButton);
|
||
|
||
// 清除高亮按钮
|
||
clearHighlightButton = new System.Windows.Forms.Button
|
||
{
|
||
Text = "清除高亮",
|
||
Size = new System.Drawing.Size(80, 25),
|
||
Location = new System.Drawing.Point(510, 370),
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
|
||
};
|
||
clearHighlightButton.Click += ClearHighlightButton_Click;
|
||
this.Controls.Add(clearHighlightButton);
|
||
|
||
// 确定按钮
|
||
var okButton = new System.Windows.Forms.Button
|
||
{
|
||
Text = "确定",
|
||
Size = new System.Drawing.Size(75, 30),
|
||
Location = new System.Drawing.Point(520, 440),
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
DialogResult = System.Windows.Forms.DialogResult.OK,
|
||
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
|
||
};
|
||
okButton.Click += OkButton_Click;
|
||
this.Controls.Add(okButton);
|
||
|
||
// 取消按钮
|
||
var cancelButton = new System.Windows.Forms.Button
|
||
{
|
||
Text = "取消",
|
||
Size = new System.Drawing.Size(75, 30),
|
||
Location = new System.Drawing.Point(605, 440),
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
DialogResult = System.Windows.Forms.DialogResult.Cancel,
|
||
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
|
||
};
|
||
this.Controls.Add(cancelButton);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建通道列表选项卡
|
||
/// </summary>
|
||
private void CreateChannelListTab(System.Windows.Forms.TabPage tabPage)
|
||
{
|
||
// 全选复选框
|
||
selectAllCheckBox = new System.Windows.Forms.CheckBox
|
||
{
|
||
Text = "全选",
|
||
Location = new System.Drawing.Point(10, 10),
|
||
Size = new System.Drawing.Size(60, 20),
|
||
Font = new System.Drawing.Font("微软雅黑", 9)
|
||
};
|
||
selectAllCheckBox.CheckedChanged += SelectAllCheckBox_CheckedChanged;
|
||
tabPage.Controls.Add(selectAllCheckBox);
|
||
|
||
// 通道列表
|
||
channelListView = new System.Windows.Forms.ListView
|
||
{
|
||
Location = new System.Drawing.Point(10, 35),
|
||
Size = new System.Drawing.Size(640, 280),
|
||
View = System.Windows.Forms.View.Details,
|
||
FullRowSelect = true,
|
||
GridLines = true,
|
||
CheckBoxes = true,
|
||
Font = new System.Drawing.Font("微软雅黑", 9),
|
||
Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left |
|
||
System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom
|
||
};
|
||
|
||
// 添加列
|
||
channelListView.Columns.Add("名称", 200);
|
||
channelListView.Columns.Add("类型", 80);
|
||
channelListView.Columns.Add("可通行", 60);
|
||
channelListView.Columns.Add("车辆尺寸", 80);
|
||
channelListView.Columns.Add("长度(m)", 80);
|
||
channelListView.Columns.Add("宽度(m)", 80);
|
||
channelListView.Columns.Add("高度(m)", 80);
|
||
|
||
channelListView.ItemChecked += ChannelListView_ItemChecked;
|
||
tabPage.Controls.Add(channelListView);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建筛选选项卡
|
||
/// </summary>
|
||
private void CreateFilterTab(System.Windows.Forms.TabPage tabPage)
|
||
{
|
||
// 车辆尺寸选择
|
||
var vehicleSizeLabel = new System.Windows.Forms.Label
|
||
{
|
||
Text = "车辆尺寸:",
|
||
Location = new System.Drawing.Point(10, 20),
|
||
Size = new System.Drawing.Size(80, 20),
|
||
Font = new System.Drawing.Font("微软雅黑", 9)
|
||
};
|
||
tabPage.Controls.Add(vehicleSizeLabel);
|
||
|
||
vehicleSizeComboBox = new System.Windows.Forms.ComboBox
|
||
{
|
||
Location = new System.Drawing.Point(100, 18),
|
||
Size = new System.Drawing.Size(120, 25),
|
||
DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList,
|
||
Font = new System.Drawing.Font("微软雅黑", 9)
|
||
};
|
||
vehicleSizeComboBox.Items.AddRange(new string[] { "小型", "标准", "大型", "超大型" });
|
||
vehicleSizeComboBox.SelectedIndex = 1; // 默认选择"标准"
|
||
vehicleSizeComboBox.SelectedIndexChanged += VehicleSizeComboBox_SelectedIndexChanged;
|
||
tabPage.Controls.Add(vehicleSizeComboBox);
|
||
|
||
// 筛选方式选择
|
||
var filterMethodLabel = new System.Windows.Forms.Label
|
||
{
|
||
Text = "筛选方式:",
|
||
Location = new System.Drawing.Point(10, 60),
|
||
Size = new System.Drawing.Size(200, 20),
|
||
Font = new System.Drawing.Font("微软雅黑", 9)
|
||
};
|
||
tabPage.Controls.Add(filterMethodLabel);
|
||
|
||
var filterOptions = new System.Windows.Forms.RadioButton[]
|
||
{
|
||
new System.Windows.Forms.RadioButton { Text = "显示所有检测到的通道", Location = new System.Drawing.Point(20, 85), Size = new System.Drawing.Size(200, 20), Checked = true },
|
||
new System.Windows.Forms.RadioButton { Text = "仅显示已标记物流属性的通道", Location = new System.Drawing.Point(20, 110), Size = new System.Drawing.Size(200, 20) },
|
||
new System.Windows.Forms.RadioButton { Text = "仅显示可通行区域", Location = new System.Drawing.Point(20, 135), Size = new System.Drawing.Size(200, 20) },
|
||
new System.Windows.Forms.RadioButton { Text = "自动检测通道", Location = new System.Drawing.Point(20, 160), Size = new System.Drawing.Size(200, 20) }
|
||
};
|
||
|
||
foreach (var option in filterOptions)
|
||
{
|
||
option.Font = new System.Drawing.Font("微软雅黑", 9);
|
||
option.CheckedChanged += FilterOption_CheckedChanged;
|
||
tabPage.Controls.Add(option);
|
||
}
|
||
|
||
// 应用筛选按钮
|
||
var applyFilterButton = new System.Windows.Forms.Button
|
||
{
|
||
Text = "应用筛选",
|
||
Location = new System.Drawing.Point(20, 200),
|
||
Size = new System.Drawing.Size(100, 30),
|
||
Font = new System.Drawing.Font("微软雅黑", 9)
|
||
};
|
||
applyFilterButton.Click += ApplyFilterButton_Click;
|
||
tabPage.Controls.Add(applyFilterButton);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载分析数据
|
||
/// </summary>
|
||
private void LoadAnalysisData()
|
||
{
|
||
try
|
||
{
|
||
if (channelListView == null) return;
|
||
|
||
channelListView.Items.Clear();
|
||
|
||
// 根据分析结果填充通道列表
|
||
var channelsToShow = _analysisResult.ChannelItems.Count > 0
|
||
? _analysisResult.ChannelItems
|
||
: _analysisResult.AutoDetectedChannels;
|
||
|
||
foreach (ModelItem channel in channelsToShow)
|
||
{
|
||
var item = new System.Windows.Forms.ListViewItem(channel.DisplayName ?? "未命名通道");
|
||
item.Tag = channel;
|
||
|
||
// 获取通道属性信息
|
||
string channelType = "通道";
|
||
string traversable = "是";
|
||
string vehicleSize = "标准";
|
||
|
||
try
|
||
{
|
||
if (CategoryAttributeManager.HasLogisticsAttributes(channel))
|
||
{
|
||
// 这里可以添加更详细的属性读取逻辑
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
// 获取尺寸信息
|
||
double length = 0, width = 0, height = 0;
|
||
try
|
||
{
|
||
var boundingBox = channel.BoundingBox();
|
||
if (boundingBox != null)
|
||
{
|
||
length = Math.Abs(boundingBox.Max.X - boundingBox.Min.X);
|
||
width = Math.Abs(boundingBox.Max.Y - boundingBox.Min.Y);
|
||
height = Math.Abs(boundingBox.Max.Z - boundingBox.Min.Z);
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
// 添加子项
|
||
item.SubItems.Add(channelType);
|
||
item.SubItems.Add(traversable);
|
||
item.SubItems.Add(vehicleSize);
|
||
item.SubItems.Add(length.ToString("F2"));
|
||
item.SubItems.Add(width.ToString("F2"));
|
||
item.SubItems.Add(height.ToString("F2"));
|
||
|
||
channelListView.Items.Add(item);
|
||
}
|
||
|
||
// 更新统计信息
|
||
UpdateStatistics();
|
||
|
||
// 默认选择所有通道
|
||
if (_analysisResult.Success && channelsToShow.Count > 0)
|
||
{
|
||
_selectedChannels = new ModelItemCollection();
|
||
foreach (ModelItem channel in channelsToShow)
|
||
{
|
||
_selectedChannels.Add(channel);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
if (statisticsLabel != null)
|
||
{
|
||
statisticsLabel.Text = $"加载通道数据失败: {ex.Message}";
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新统计信息
|
||
/// </summary>
|
||
private void UpdateStatistics()
|
||
{
|
||
if (statisticsLabel == null) return;
|
||
|
||
var totalChannels = channelListView.Items.Count;
|
||
var selectedChannels = channelListView.CheckedItems.Count;
|
||
var logisticsMarked = _analysisResult.LogisticsMarkedItems.Count;
|
||
var autoDetected = _analysisResult.AutoDetectedChannels.Count;
|
||
|
||
statisticsLabel.Text = $"统计信息:\n" +
|
||
$"总通道数: {totalChannels} 已选择: {selectedChannels}\n" +
|
||
$"已标记物流属性: {logisticsMarked} 自动检测: {autoDetected}";
|
||
}
|
||
|
||
#region 事件处理方法
|
||
|
||
/// <summary>
|
||
/// 预览按钮点击事件
|
||
/// </summary>
|
||
private void PreviewButton_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
var selectedItems = new ModelItemCollection();
|
||
foreach (System.Windows.Forms.ListViewItem item in channelListView.CheckedItems)
|
||
{
|
||
if (item.Tag is ModelItem channel)
|
||
{
|
||
selectedItems.Add(channel);
|
||
}
|
||
}
|
||
|
||
if (selectedItems.Count > 0)
|
||
{
|
||
// 高亮显示选中的通道
|
||
var navisColor = new Autodesk.Navisworks.Api.Color(0.0, 1.0, 0.0); // 绿色
|
||
Application.ActiveDocument.Models.OverrideTemporaryColor(selectedItems, navisColor);
|
||
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.All);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.Forms.MessageBox.Show($"预览失败: {ex.Message}", "错误",
|
||
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除高亮按钮点击事件
|
||
/// </summary>
|
||
private void ClearHighlightButton_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
Application.ActiveDocument.Models.ResetAllTemporaryMaterials();
|
||
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.All);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.Forms.MessageBox.Show($"清除高亮失败: {ex.Message}", "错误",
|
||
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 确定按钮点击事件
|
||
/// </summary>
|
||
private void OkButton_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
_selectedChannels.Clear();
|
||
|
||
foreach (System.Windows.Forms.ListViewItem item in channelListView.CheckedItems)
|
||
{
|
||
if (item.Tag is ModelItem channel)
|
||
{
|
||
_selectedChannels.Add(channel);
|
||
}
|
||
}
|
||
|
||
_vehicleSize = vehicleSizeComboBox?.SelectedItem?.ToString() ?? "标准";
|
||
_selectionMethod = ChannelSelectionMethod.Manual; // 可以根据选项卡或筛选方式设置
|
||
|
||
// 清除高亮
|
||
try
|
||
{
|
||
Application.ActiveDocument.Models.ResetAllTemporaryMaterials();
|
||
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.All);
|
||
}
|
||
catch { }
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.Forms.MessageBox.Show($"确认选择失败: {ex.Message}", "错误",
|
||
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 全选复选框状态改变事件
|
||
/// </summary>
|
||
private void SelectAllCheckBox_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
bool isChecked = selectAllCheckBox.Checked;
|
||
|
||
foreach (System.Windows.Forms.ListViewItem item in channelListView.Items)
|
||
{
|
||
item.Checked = isChecked;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.Forms.MessageBox.Show($"全选操作失败: {ex.Message}", "错误",
|
||
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道列表项选中状态改变事件
|
||
/// </summary>
|
||
private void ChannelListView_ItemChecked(object sender, System.Windows.Forms.ItemCheckedEventArgs e)
|
||
{
|
||
UpdateStatistics();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 车辆尺寸选择改变事件
|
||
/// </summary>
|
||
private void VehicleSizeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
_vehicleSize = vehicleSizeComboBox.SelectedItem?.ToString() ?? "标准";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 筛选选项改变事件
|
||
/// </summary>
|
||
private void FilterOption_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
// 可以根据需要实现筛选逻辑
|
||
}
|
||
|
||
/// <summary>
|
||
/// 应用筛选按钮点击事件
|
||
/// </summary>
|
||
private void ApplyFilterButton_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 重新加载数据应用筛选
|
||
LoadAnalysisData();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.Forms.MessageBox.Show($"应用筛选失败: {ex.Message}", "错误",
|
||
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#region 路径验证与优化相关数据结构
|
||
|
||
/// <summary>
|
||
/// 路径验证结果
|
||
/// </summary>
|
||
public class PathValidationResult
|
||
{
|
||
/// <summary>
|
||
/// 路径ID
|
||
/// </summary>
|
||
public string RouteId { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 路径名称
|
||
/// </summary>
|
||
public string RouteName { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 验证是否通过
|
||
/// </summary>
|
||
public bool IsValid { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 验证消息
|
||
/// </summary>
|
||
public string Message { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 错误列表
|
||
/// </summary>
|
||
public List<string> Errors { get; set; } = new List<string>();
|
||
|
||
/// <summary>
|
||
/// 警告列表
|
||
/// </summary>
|
||
public List<string> Warnings { get; set; } = new List<string>();
|
||
|
||
/// <summary>
|
||
/// 验证时间
|
||
/// </summary>
|
||
public DateTime ValidationTime { get; set; } = DateTime.Now;
|
||
|
||
/// <summary>
|
||
/// 添加错误信息
|
||
/// </summary>
|
||
/// <param name="error">错误信息</param>
|
||
public void AddError(string error)
|
||
{
|
||
if (!string.IsNullOrEmpty(error) && !Errors.Contains(error))
|
||
{
|
||
Errors.Add(error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加警告信息
|
||
/// </summary>
|
||
/// <param name="warning">警告信息</param>
|
||
public void AddWarning(string warning)
|
||
{
|
||
if (!string.IsNullOrEmpty(warning) && !Warnings.Contains(warning))
|
||
{
|
||
Warnings.Add(warning);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取详细验证报告
|
||
/// </summary>
|
||
/// <returns>验证报告文本</returns>
|
||
public string GetDetailedReport()
|
||
{
|
||
var report = new StringBuilder();
|
||
report.AppendLine($"路径验证报告 - {RouteName} ({RouteId})");
|
||
report.AppendLine($"验证时间: {ValidationTime:yyyy-MM-dd HH:mm:ss}");
|
||
report.AppendLine($"验证结果: {(IsValid ? "通过" : "失败")}");
|
||
report.AppendLine($"消息: {Message}");
|
||
|
||
if (Errors.Count > 0)
|
||
{
|
||
report.AppendLine("\n错误列表:");
|
||
for (int i = 0; i < Errors.Count; i++)
|
||
{
|
||
report.AppendLine($" {i + 1}. {Errors[i]}");
|
||
}
|
||
}
|
||
|
||
if (Warnings.Count > 0)
|
||
{
|
||
report.AppendLine("\n警告列表:");
|
||
for (int i = 0; i < Warnings.Count; i++)
|
||
{
|
||
report.AppendLine($" {i + 1}. {Warnings[i]}");
|
||
}
|
||
}
|
||
|
||
return report.ToString();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 路径优化选项
|
||
/// </summary>
|
||
public class PathOptimizationOptions
|
||
{
|
||
/// <summary>
|
||
/// 移除重复点
|
||
/// </summary>
|
||
public bool RemoveDuplicatePoints { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 路径平滑化
|
||
/// </summary>
|
||
public bool SmoothPath { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 优化路径角度
|
||
/// </summary>
|
||
public bool OptimizeAngles { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 调整到通道中心
|
||
/// </summary>
|
||
public bool AdjustToChannels { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 重复点检测阈值(米)
|
||
/// </summary>
|
||
public double DuplicatePointThreshold { get; set; } = 0.01;
|
||
|
||
/// <summary>
|
||
/// 角度优化容差(弧度)
|
||
/// </summary>
|
||
public double AngleOptimizationTolerance { get; set; } = 0.1;
|
||
|
||
/// <summary>
|
||
/// 平滑强度(0-1)
|
||
/// </summary>
|
||
public double SmoothingStrength { get; set; } = 0.5;
|
||
|
||
/// <summary>
|
||
/// 创建默认优化选项
|
||
/// </summary>
|
||
/// <returns>默认优化选项</returns>
|
||
public static PathOptimizationOptions CreateDefault()
|
||
{
|
||
return new PathOptimizationOptions
|
||
{
|
||
RemoveDuplicatePoints = true,
|
||
SmoothPath = true,
|
||
OptimizeAngles = true,
|
||
AdjustToChannels = false,
|
||
DuplicatePointThreshold = 0.01,
|
||
AngleOptimizationTolerance = 0.1,
|
||
SmoothingStrength = 0.5
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建保守优化选项(仅基础优化)
|
||
/// </summary>
|
||
/// <returns>保守优化选项</returns>
|
||
public static PathOptimizationOptions CreateConservative()
|
||
{
|
||
return new PathOptimizationOptions
|
||
{
|
||
RemoveDuplicatePoints = true,
|
||
SmoothPath = false,
|
||
OptimizeAngles = false,
|
||
AdjustToChannels = false,
|
||
DuplicatePointThreshold = 0.001
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建激进优化选项(所有优化)
|
||
/// </summary>
|
||
/// <returns>激进优化选项</returns>
|
||
public static PathOptimizationOptions CreateAggressive()
|
||
{
|
||
return new PathOptimizationOptions
|
||
{
|
||
RemoveDuplicatePoints = true,
|
||
SmoothPath = true,
|
||
OptimizeAngles = true,
|
||
AdjustToChannels = true,
|
||
DuplicatePointThreshold = 0.05,
|
||
AngleOptimizationTolerance = 0.2,
|
||
SmoothingStrength = 0.8
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 路径优化结果
|
||
/// </summary>
|
||
public class PathOptimizationResult
|
||
{
|
||
/// <summary>
|
||
/// 优化是否成功
|
||
/// </summary>
|
||
public bool Success { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 优化消息
|
||
/// </summary>
|
||
public string Message { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 原始路径
|
||
/// </summary>
|
||
public PathRoute OriginalRoute { get; set; }
|
||
|
||
/// <summary>
|
||
/// 优化后的路径
|
||
/// </summary>
|
||
public PathRoute OptimizedRoute { get; set; }
|
||
|
||
/// <summary>
|
||
/// 原始路径长度
|
||
/// </summary>
|
||
public double OriginalLength { get; set; } = 0.0;
|
||
|
||
/// <summary>
|
||
/// 优化后路径长度
|
||
/// </summary>
|
||
public double OptimizedLength { get; set; } = 0.0;
|
||
|
||
/// <summary>
|
||
/// 长度减少量
|
||
/// </summary>
|
||
public double LengthReduction { get; set; } = 0.0;
|
||
|
||
/// <summary>
|
||
/// 长度减少百分比
|
||
/// </summary>
|
||
public double LengthReductionPercentage => OriginalLength > 0 ? (LengthReduction / OriginalLength) * 100 : 0;
|
||
|
||
/// <summary>
|
||
/// 原始点数
|
||
/// </summary>
|
||
public int OriginalPointCount { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 优化后点数
|
||
/// </summary>
|
||
public int OptimizedPointCount { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 点数减少量
|
||
/// </summary>
|
||
public int PointReduction { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 点数减少百分比
|
||
/// </summary>
|
||
public double PointReductionPercentage => OriginalPointCount > 0 ? ((double)PointReduction / OriginalPointCount) * 100 : 0;
|
||
|
||
/// <summary>
|
||
/// 优化步骤记录
|
||
/// </summary>
|
||
public List<string> OptimizationSteps { get; set; } = new List<string>();
|
||
|
||
/// <summary>
|
||
/// 优化时间
|
||
/// </summary>
|
||
public DateTime OptimizationTime { get; set; } = DateTime.Now;
|
||
|
||
/// <summary>
|
||
/// 优化耗时(毫秒)
|
||
/// </summary>
|
||
public long ElapsedMilliseconds { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 添加优化步骤记录
|
||
/// </summary>
|
||
/// <param name="step">优化步骤描述</param>
|
||
public void AddOptimizationStep(string step)
|
||
{
|
||
if (!string.IsNullOrEmpty(step))
|
||
{
|
||
OptimizationSteps.Add($"[{DateTime.Now:HH:mm:ss}] {step}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取详细优化报告
|
||
/// </summary>
|
||
/// <returns>优化报告文本</returns>
|
||
public string GetDetailedReport()
|
||
{
|
||
var report = new StringBuilder();
|
||
report.AppendLine($"路径优化报告");
|
||
report.AppendLine($"优化时间: {OptimizationTime:yyyy-MM-dd HH:mm:ss}");
|
||
report.AppendLine($"耗时: {ElapsedMilliseconds} 毫秒");
|
||
report.AppendLine($"优化结果: {(Success ? "成功" : "失败")}");
|
||
report.AppendLine($"消息: {Message}");
|
||
|
||
if (Success)
|
||
{
|
||
report.AppendLine($"\n原始路径:");
|
||
report.AppendLine($" 长度: {OriginalLength:F3} 米");
|
||
report.AppendLine($" 点数: {OriginalPointCount}");
|
||
|
||
report.AppendLine($"\n优化后路径:");
|
||
report.AppendLine($" 长度: {OptimizedLength:F3} 米");
|
||
report.AppendLine($" 点数: {OptimizedPointCount}");
|
||
|
||
report.AppendLine($"\n优化效果:");
|
||
report.AppendLine($" 长度减少: {LengthReduction:F3} 米 ({LengthReductionPercentage:F1}%)");
|
||
report.AppendLine($" 点数减少: {PointReduction} 个 ({PointReductionPercentage:F1}%)");
|
||
}
|
||
|
||
if (OptimizationSteps.Count > 0)
|
||
{
|
||
report.AppendLine("\n优化步骤:");
|
||
for (int i = 0; i < OptimizationSteps.Count; i++)
|
||
{
|
||
report.AppendLine($" {i + 1}. {OptimizationSteps[i]}");
|
||
}
|
||
}
|
||
|
||
return report.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取优化摘要
|
||
/// </summary>
|
||
/// <returns>优化摘要文本</returns>
|
||
public string GetSummary()
|
||
{
|
||
if (!Success)
|
||
{
|
||
return $"优化失败: {Message}";
|
||
}
|
||
|
||
return $"优化成功: 长度减少 {LengthReduction:F3}m ({LengthReductionPercentage:F1}%), " +
|
||
$"点数减少 {PointReduction} 个 ({PointReductionPercentage:F1}%), " +
|
||
$"共执行 {OptimizationSteps.Count} 个优化步骤";
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 路径点标记类型
|
||
/// </summary>
|
||
public enum PathPointMarkerType
|
||
{
|
||
/// <summary>
|
||
/// 文本标注
|
||
/// </summary>
|
||
TextLabel
|
||
}
|
||
|
||
/// <summary>
|
||
/// 路径点3D标记信息
|
||
/// </summary>
|
||
public class PathPointMarker
|
||
{
|
||
/// <summary>
|
||
/// 关联的路径点
|
||
/// </summary>
|
||
public PathPoint PathPoint { get; set; }
|
||
|
||
/// <summary>
|
||
/// 标记类型
|
||
/// </summary>
|
||
public PathPointMarkerType MarkerType { get; set; }
|
||
|
||
/// <summary>
|
||
/// 标注文本
|
||
/// </summary>
|
||
public string LabelText { get; set; }
|
||
|
||
/// <summary>
|
||
/// 标注位置
|
||
/// </summary>
|
||
public Point3D LabelPosition { get; set; }
|
||
|
||
/// <summary>
|
||
/// 创建时间
|
||
/// </summary>
|
||
public DateTime CreatedTime { get; set; } = DateTime.Now;
|
||
}
|
||
} |