using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Autodesk.Navisworks.Api;
using System.Text;
using System.Linq;
using System.IO;
namespace NavisworksTransport
{
///
/// 路径编辑状态枚举
///
public enum PathEditState
{
///
/// 查看状态 - 只能查看路径,不能编辑
///
Viewing,
///
/// 新建状态 - 正在创建新路径
///
Creating,
///
/// 编辑状态 - 正在编辑现有路径
///
Editing
}
///
/// 通道检测结果
///
public class ChannelDetectionResult
{
///
/// 是否为有效位置
///
public bool IsValidLocation { get; set; }
///
/// 检测消息
///
public string Message { get; set; }
///
/// 检测方法
///
public string DetectionMethod { get; set; }
}
///
/// 物流通道检测结果
///
public class LogisticsChannelDetectionResult
{
///
/// 是否为有效通道
///
public bool IsValidChannel { get; set; }
///
/// 通道类型名称
///
public string ChannelType { get; set; }
///
/// 检测到的通道模型项
///
public ModelItem DetectedChannel { get; set; }
///
/// 物流类别
///
public CategoryAttributeManager.LogisticsElementType? LogisticsCategory { get; set; }
///
/// 检测置信度
///
public double DetectionConfidence { get; set; }
///
/// 错误消息
///
public string ErrorMessage { get; set; }
}
///
/// 几何分析结果
///
public class GeometryAnalysisResult
{
///
/// 是否可能是通道
///
public bool IsLikelyChannel { get; set; }
///
/// 分析原因
///
public string Reason { get; set; }
///
/// 最可能的通道模型项
///
public ModelItem MostLikelyChannel { get; set; }
///
/// 置信度
///
public double Confidence { get; set; }
}
///
/// 路径点类型枚举
///
public enum PathPointType
{
///
/// 起点
///
StartPoint,
///
/// 终点
///
EndPoint,
///
/// 路径点
///
WayPoint
}
///
/// 路径点数据模型
///
[Serializable]
public class PathPoint
{
///
/// 路径点唯一标识符
///
public string Id { get; set; }
///
/// 3D位置坐标
///
public Point3D Position { get; set; }
///
/// 路径点名称
///
public string Name { get; set; }
///
/// 路径点类型
///
public PathPointType Type { get; set; }
///
/// 创建时间
///
public DateTime CreatedTime { get; set; }
///
/// 路径点序号
///
public int Index { get; set; }
///
/// 备注信息
///
public string Notes { get; set; }
///
/// 构造函数
///
public PathPoint()
{
Id = Guid.NewGuid().ToString();
Position = new Point3D();
Name = string.Empty;
Type = PathPointType.WayPoint;
CreatedTime = DateTime.Now;
Index = 0;
Notes = string.Empty;
}
///
/// 带参数构造函数
///
/// 3D坐标
/// 名称
/// 类型
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;
}
///
/// 返回路径点描述字符串
///
///
public override string ToString()
{
return $"{Name} ({Type}) - X:{Position.X:F2}, Y:{Position.Y:F2}, Z:{Position.Z:F2}";
}
}
///
/// 路径路线数据模型
///
[Serializable]
public class PathRoute
{
///
/// 路径点集合
///
public List Points { get; set; }
///
/// 路径名称
///
public string Name { get; set; }
///
/// 路径ID
///
public string Id { get; set; }
///
/// 预估时间(秒)
///
public double EstimatedTime { get; set; }
///
/// 关联通道模型ID集合
///
public List AssociatedChannelIds { get; set; }
///
/// 路径总长度(米)
///
public double TotalLength { get; set; }
///
/// 创建时间
///
public DateTime CreatedTime { get; set; }
///
/// 最后修改时间
///
public DateTime LastModified { get; set; }
///
/// 路径描述
///
public string Description { get; set; }
///
/// 构造函数
///
public PathRoute()
{
Points = new List();
Name = string.Empty;
Id = Guid.NewGuid().ToString();
EstimatedTime = 0.0;
AssociatedChannelIds = new List();
TotalLength = 0.0;
CreatedTime = DateTime.Now;
LastModified = DateTime.Now;
Description = string.Empty;
}
///
/// 带参数构造函数
///
/// 路径名称
public PathRoute(string name)
{
Points = new List();
Name = name;
Id = Guid.NewGuid().ToString();
EstimatedTime = 0.0;
AssociatedChannelIds = new List();
TotalLength = 0.0;
CreatedTime = DateTime.Now;
LastModified = DateTime.Now;
Description = string.Empty;
}
///
/// 添加路径点
///
/// 路径点
public void AddPoint(PathPoint point)
{
point.Index = Points.Count;
Points.Add(point);
LastModified = DateTime.Now;
UpdateTotalLength();
}
///
/// 移除路径点
///
/// 路径点
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;
}
///
/// 根据ID移除路径点
///
/// 路径点ID
/// 是否成功移除
public bool RemovePoint(string pointId)
{
var point = Points.FirstOrDefault(p => p.Id == pointId);
if (point != null)
{
return RemovePoint(point);
}
return false;
}
///
/// 清空所有路径点
///
public void ClearPoints()
{
Points.Clear();
LastModified = DateTime.Now;
UpdateTotalLength();
}
///
/// 获取起点
///
///
public PathPoint GetStartPoint()
{
return Points.Find(p => p.Type == PathPointType.StartPoint);
}
///
/// 获取终点
///
///
public PathPoint GetEndPoint()
{
return Points.Find(p => p.Type == PathPointType.EndPoint);
}
///
/// 获取所有路径点(按序号排序)
///
///
public List GetSortedPoints()
{
var sortedPoints = new List(Points);
sortedPoints.Sort((p1, p2) => p1.Index.CompareTo(p2.Index));
return sortedPoints;
}
///
/// 重新计算路径长度
///
public void RecalculateLength()
{
UpdateTotalLength();
}
///
/// 更新路径总长度
///
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;
}
}
///
/// 验证路径有效性
///
///
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;
}
///
/// 克隆路径
///
/// 克隆的路径对象
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(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;
}
///
/// 返回路径描述字符串
///
///
public override string ToString()
{
return $"{Name} - 点数:{Points.Count}, 长度:{TotalLength:F2}m, 预估时间:{EstimatedTime:F1}s";
}
}
///
/// 2D地图坐标
///
[Serializable]
public class MapPoint2D
{
///
/// X坐标
///
public double X { get; set; }
///
/// Y坐标
///
public double Y { get; set; }
///
/// 构造函数
///
public MapPoint2D()
{
X = 0.0;
Y = 0.0;
}
///
/// 带参数构造函数
///
/// X坐标
/// Y坐标
public MapPoint2D(double x, double y)
{
X = x;
Y = y;
}
///
/// 返回坐标描述字符串
///
///
public override string ToString()
{
return $"({X:F2}, {Y:F2})";
}
}
///
/// 通道边界信息
///
[Serializable]
public class ChannelBounds
{
///
/// 最小坐标点
///
public Point3D MinPoint { get; set; }
///
/// 最大坐标点
///
public Point3D MaxPoint { get; set; }
///
/// 中心点
///
public Point3D Center { get; set; }
///
/// 通道高度(Z轴方向)
///
public double Height { get; set; }
///
/// 构造函数
///
public ChannelBounds()
{
MinPoint = new Point3D();
MaxPoint = new Point3D();
Center = new Point3D();
Height = 0.0;
}
///
/// 带包围盒参数构造函数
///
/// Navisworks包围盒
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;
}
///
/// 获取2D投影范围
///
/// 最小点
/// 最大点
public void Get2DProjection(out MapPoint2D min, out MapPoint2D max)
{
min = new MapPoint2D(MinPoint.X, MinPoint.Y);
max = new MapPoint2D(MaxPoint.X, MaxPoint.Y);
}
}
///
/// 通道选择结果
///
public class ChannelSelectionResult
{
///
/// 是否成功
///
public bool Success { get; set; } = false;
///
/// 结果消息
///
public string Message { get; set; } = "";
///
/// 总模型项数量
///
public int TotalModelItems { get; set; } = 0;
///
/// 自动检测的通道
///
public ModelItemCollection AutoDetectedChannels { get; set; } = new ModelItemCollection();
///
/// 已标记物流属性的模型项
///
public ModelItemCollection LogisticsMarkedItems { get; set; } = new ModelItemCollection();
///
/// 可通行区域
///
public ModelItemCollection TraversableAreas { get; set; } = new ModelItemCollection();
///
/// 通道类型模型项
///
public ModelItemCollection ChannelItems { get; set; } = new ModelItemCollection();
}
///
/// 通道选择对话框结果
///
public class ChannelSelectionDialogResult
{
///
/// 是否成功
///
public bool Success { get; set; } = false;
///
/// 结果消息
///
public string Message { get; set; } = "";
///
/// 选中的通道
///
public ModelItemCollection SelectedChannels { get; set; } = new ModelItemCollection();
///
/// 选择方法
///
public ChannelSelectionMethod SelectionMethod { get; set; } = ChannelSelectionMethod.Manual;
///
/// 车辆尺寸
///
public string VehicleSize { get; set; } = "标准";
}
///
/// 通道选择方法枚举
///
public enum ChannelSelectionMethod
{
///
/// 手动选择
///
Manual,
///
/// 自动检测
///
AutoDetect,
///
/// 基于物流属性
///
LogisticsAttribute,
///
/// 可通行区域
///
TraversableAreas,
///
/// 通道类型
///
ChannelType
}
///
/// 通道选择对话框
///
public class ChannelSelectionDialog : System.Windows.Forms.Form
{
private ChannelSelectionResult _analysisResult;
private ModelItemCollection _selectedChannels;
private ChannelSelectionMethod _selectionMethod;
private string _vehicleSize;
///
/// 选中的通道
///
public ModelItemCollection SelectedChannels { get { return _selectedChannels; } }
///
/// 选择方法
///
public ChannelSelectionMethod SelectionMethod { get { return _selectionMethod; } }
///
/// 车辆尺寸
///
public string VehicleSize { get { return _vehicleSize; } }
///
/// 构造函数
///
/// 通道分析结果
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;
///
/// 初始化对话框组件
///
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("微软雅黑", 8),
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("微软雅黑", 8),
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("微软雅黑", 8),
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("微软雅黑", 8),
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("微软雅黑", 8),
DialogResult = System.Windows.Forms.DialogResult.Cancel,
Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
};
this.Controls.Add(cancelButton);
}
///
/// 创建通道列表选项卡
///
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("微软雅黑", 8)
};
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("微软雅黑", 8),
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);
}
///
/// 创建筛选选项卡
///
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("微软雅黑", 8)
};
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("微软雅黑", 8)
};
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("微软雅黑", 8)
};
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("微软雅黑", 8);
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("微软雅黑", 8)
};
applyFilterButton.Click += ApplyFilterButton_Click;
tabPage.Controls.Add(applyFilterButton);
}
///
/// 加载分析数据
///
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}";
}
}
}
///
/// 更新统计信息
///
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 事件处理方法
///
/// 预览按钮点击事件
///
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);
}
}
///
/// 清除高亮按钮点击事件
///
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);
}
}
///
/// 确定按钮点击事件
///
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);
}
}
///
/// 全选复选框状态改变事件
///
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);
}
}
///
/// 通道列表项选中状态改变事件
///
private void ChannelListView_ItemChecked(object sender, System.Windows.Forms.ItemCheckedEventArgs e)
{
UpdateStatistics();
}
///
/// 车辆尺寸选择改变事件
///
private void VehicleSizeComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
_vehicleSize = vehicleSizeComboBox.SelectedItem?.ToString() ?? "标准";
}
///
/// 筛选选项改变事件
///
private void FilterOption_CheckedChanged(object sender, EventArgs e)
{
// 可以根据需要实现筛选逻辑
}
///
/// 应用筛选按钮点击事件
///
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 路径验证与优化相关数据结构
///
/// 路径验证结果
///
public class PathValidationResult
{
///
/// 路径ID
///
public string RouteId { get; set; } = "";
///
/// 路径名称
///
public string RouteName { get; set; } = "";
///
/// 验证是否通过
///
public bool IsValid { get; set; } = false;
///
/// 验证消息
///
public string Message { get; set; } = "";
///
/// 错误列表
///
public List Errors { get; set; } = new List();
///
/// 警告列表
///
public List Warnings { get; set; } = new List();
///
/// 验证时间
///
public DateTime ValidationTime { get; set; } = DateTime.Now;
///
/// 添加错误信息
///
/// 错误信息
public void AddError(string error)
{
if (!string.IsNullOrEmpty(error) && !Errors.Contains(error))
{
Errors.Add(error);
}
}
///
/// 添加警告信息
///
/// 警告信息
public void AddWarning(string warning)
{
if (!string.IsNullOrEmpty(warning) && !Warnings.Contains(warning))
{
Warnings.Add(warning);
}
}
///
/// 获取详细验证报告
///
/// 验证报告文本
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();
}
}
///
/// 路径优化选项
///
public class PathOptimizationOptions
{
///
/// 移除重复点
///
public bool RemoveDuplicatePoints { get; set; } = true;
///
/// 路径平滑化
///
public bool SmoothPath { get; set; } = true;
///
/// 优化路径角度
///
public bool OptimizeAngles { get; set; } = true;
///
/// 调整到通道中心
///
public bool AdjustToChannels { get; set; } = false;
///
/// 重复点检测阈值(米)
///
public double DuplicatePointThreshold { get; set; } = 0.01;
///
/// 角度优化容差(弧度)
///
public double AngleOptimizationTolerance { get; set; } = 0.1;
///
/// 平滑强度(0-1)
///
public double SmoothingStrength { get; set; } = 0.5;
///
/// 创建默认优化选项
///
/// 默认优化选项
public static PathOptimizationOptions CreateDefault()
{
return new PathOptimizationOptions
{
RemoveDuplicatePoints = true,
SmoothPath = true,
OptimizeAngles = true,
AdjustToChannels = false,
DuplicatePointThreshold = 0.01,
AngleOptimizationTolerance = 0.1,
SmoothingStrength = 0.5
};
}
///
/// 创建保守优化选项(仅基础优化)
///
/// 保守优化选项
public static PathOptimizationOptions CreateConservative()
{
return new PathOptimizationOptions
{
RemoveDuplicatePoints = true,
SmoothPath = false,
OptimizeAngles = false,
AdjustToChannels = false,
DuplicatePointThreshold = 0.001
};
}
///
/// 创建激进优化选项(所有优化)
///
/// 激进优化选项
public static PathOptimizationOptions CreateAggressive()
{
return new PathOptimizationOptions
{
RemoveDuplicatePoints = true,
SmoothPath = true,
OptimizeAngles = true,
AdjustToChannels = true,
DuplicatePointThreshold = 0.05,
AngleOptimizationTolerance = 0.2,
SmoothingStrength = 0.8
};
}
}
///
/// 路径优化结果
///
public class PathOptimizationResult
{
///
/// 优化是否成功
///
public bool Success { get; set; } = false;
///
/// 优化消息
///
public string Message { get; set; } = "";
///
/// 原始路径
///
public PathRoute OriginalRoute { get; set; }
///
/// 优化后的路径
///
public PathRoute OptimizedRoute { get; set; }
///
/// 原始路径长度
///
public double OriginalLength { get; set; } = 0.0;
///
/// 优化后路径长度
///
public double OptimizedLength { get; set; } = 0.0;
///
/// 长度减少量
///
public double LengthReduction { get; set; } = 0.0;
///
/// 长度减少百分比
///
public double LengthReductionPercentage => OriginalLength > 0 ? (LengthReduction / OriginalLength) * 100 : 0;
///
/// 原始点数
///
public int OriginalPointCount { get; set; } = 0;
///
/// 优化后点数
///
public int OptimizedPointCount { get; set; } = 0;
///
/// 点数减少量
///
public int PointReduction { get; set; } = 0;
///
/// 点数减少百分比
///
public double PointReductionPercentage => OriginalPointCount > 0 ? ((double)PointReduction / OriginalPointCount) * 100 : 0;
///
/// 优化步骤记录
///
public List OptimizationSteps { get; set; } = new List();
///
/// 优化时间
///
public DateTime OptimizationTime { get; set; } = DateTime.Now;
///
/// 优化耗时(毫秒)
///
public long ElapsedMilliseconds { get; set; } = 0;
///
/// 添加优化步骤记录
///
/// 优化步骤描述
public void AddOptimizationStep(string step)
{
if (!string.IsNullOrEmpty(step))
{
OptimizationSteps.Add($"[{DateTime.Now:HH:mm:ss}] {step}");
}
}
///
/// 获取详细优化报告
///
/// 优化报告文本
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();
}
///
/// 获取优化摘要
///
/// 优化摘要文本
public string GetSummary()
{
if (!Success)
{
return $"优化失败: {Message}";
}
return $"优化成功: 长度减少 {LengthReduction:F3}m ({LengthReductionPercentage:F1}%), " +
$"点数减少 {PointReduction} 个 ({PointReductionPercentage:F1}%), " +
$"共执行 {OptimizationSteps.Count} 个优化步骤";
}
}
#endregion
///
/// 路径点标记类型
///
public enum PathPointMarkerType
{
///
/// 文本标注
///
TextLabel
}
///
/// 路径点3D标记信息
///
public class PathPointMarker
{
///
/// 关联的路径点
///
public PathPoint PathPoint { get; set; }
///
/// 标记类型
///
public PathPointMarkerType MarkerType { get; set; }
///
/// 标注文本
///
public string LabelText { get; set; }
///
/// 标注位置
///
public Point3D LabelPosition { get; set; }
///
/// 创建时间
///
public DateTime CreatedTime { get; set; } = DateTime.Now;
}
///
/// 路径历史记录项
///
[Serializable]
public class PathHistoryEntry
{
///
/// 历史记录唯一标识符
///
public string Id { get; set; }
///
/// 关联的路径ID
///
public string RouteId { get; set; }
///
/// 操作类型
///
public PathHistoryOperationType OperationType { get; set; }
///
/// 路径快照(操作前的状态)
///
public PathRoute RouteSnapshot { get; set; }
///
/// 操作时间
///
public DateTime OperationTime { get; set; }
///
/// 操作描述
///
public string Description { get; set; }
///
/// 版本号
///
public int Version { get; set; }
public PathHistoryEntry()
{
Id = Guid.NewGuid().ToString();
OperationTime = DateTime.Now;
Description = string.Empty;
Version = 1;
}
public PathHistoryEntry(string routeId, PathHistoryOperationType operationType, PathRoute routeSnapshot, string description = "")
{
Id = Guid.NewGuid().ToString();
RouteId = routeId;
OperationType = operationType;
RouteSnapshot = routeSnapshot?.Clone(); // 创建副本
OperationTime = DateTime.Now;
Description = description;
Version = 1;
}
}
///
/// 路径历史操作类型
///
public enum PathHistoryOperationType
{
///
/// 创建路径
///
Created,
///
/// 编辑路径
///
Edited,
///
/// 删除路径点
///
PointRemoved,
///
/// 添加路径点
///
PointAdded,
///
/// 路径优化
///
Optimized,
///
/// 手动保存
///
ManualSave
}
///
/// 路径历史管理器
///
public class PathHistoryManager
{
private Dictionary> _routeHistories;
private int _maxHistoryCount;
///
/// 历史记录变更事件
///
public event EventHandler HistoryEntryAdded;
public PathHistoryManager(int maxHistoryCount = 50)
{
_routeHistories = new Dictionary>();
_maxHistoryCount = maxHistoryCount;
}
///
/// 添加历史记录
///
public void AddHistoryEntry(PathHistoryEntry entry)
{
if (string.IsNullOrEmpty(entry.RouteId)) return;
if (!_routeHistories.ContainsKey(entry.RouteId))
{
_routeHistories[entry.RouteId] = new List();
}
var histories = _routeHistories[entry.RouteId];
// 设置版本号
entry.Version = histories.Count + 1;
histories.Add(entry);
// 限制历史记录数量
if (histories.Count > _maxHistoryCount)
{
histories.RemoveAt(0);
// 重新计算版本号
for (int i = 0; i < histories.Count; i++)
{
histories[i].Version = i + 1;
}
}
HistoryEntryAdded?.Invoke(this, entry);
}
///
/// 获取路径的历史记录
///
public List GetRouteHistory(string routeId)
{
return _routeHistories.ContainsKey(routeId) ?
new List(_routeHistories[routeId]) :
new List();
}
///
/// 获取最新的历史记录
///
public PathHistoryEntry GetLatestHistory(string routeId)
{
var histories = GetRouteHistory(routeId);
return histories.LastOrDefault();
}
///
/// 清理路径的历史记录
///
public void ClearRouteHistory(string routeId)
{
if (_routeHistories.ContainsKey(routeId))
{
_routeHistories.Remove(routeId);
}
}
///
/// 获取所有路径的历史记录统计
///
public Dictionary GetHistoryStatistics()
{
return _routeHistories.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Count
);
}
///
/// 获取所有历史记录
///
/// 所有历史记录的列表,按时间倒序排列
public List GetAllHistoryEntries()
{
var allEntries = new List();
foreach (var routeHistory in _routeHistories.Values)
{
allEntries.AddRange(routeHistory);
}
// 按操作时间倒序排列(最新的在前)
return allEntries.OrderByDescending(entry => entry.OperationTime).ToList();
}
}
///
/// 路径文件序列化帮助类
///
public static class PathFileSerializer
{
///
/// 将路径保存为XML文件
///
public static bool SaveToXml(PathRoute route, string filePath)
{
try
{
var serializer = new XmlSerializer(typeof(PathRoute));
using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
{
serializer.Serialize(writer, route);
}
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"保存XML文件失败: {ex.Message}");
return false;
}
}
///
/// 从XML文件加载路径
///
public static PathRoute LoadFromXml(string filePath)
{
try
{
var serializer = new XmlSerializer(typeof(PathRoute));
using (var reader = new StreamReader(filePath, Encoding.UTF8))
{
return (PathRoute)serializer.Deserialize(reader);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载XML文件失败: {ex.Message}");
return null;
}
}
///
/// 将路径保存为JSON文件(简化版)
///
public static bool SaveToJson(PathRoute route, string filePath)
{
try
{
// 使用简单的字符串格式化代替JSON序列化
var json = new StringBuilder();
json.AppendLine("{");
json.AppendLine($" \"Id\": \"{route.Id}\",");
json.AppendLine($" \"Name\": \"{route.Name}\",");
json.AppendLine($" \"Description\": \"{route.Description}\",");
json.AppendLine($" \"CreatedTime\": \"{route.CreatedTime:yyyy-MM-dd HH:mm:ss}\",");
json.AppendLine($" \"TotalLength\": {route.TotalLength},");
json.AppendLine($" \"EstimatedTime\": {route.EstimatedTime},");
json.AppendLine(" \"Points\": [");
for (int i = 0; i < route.Points.Count; i++)
{
var point = route.Points[i];
json.AppendLine(" {");
json.AppendLine($" \"Id\": \"{point.Id}\",");
json.AppendLine($" \"Name\": \"{point.Name}\",");
json.AppendLine($" \"Type\": \"{point.Type}\",");
json.AppendLine($" \"Position\": {{\"X\": {point.Position.X}, \"Y\": {point.Position.Y}, \"Z\": {point.Position.Z}}},");
json.AppendLine($" \"CreatedTime\": \"{point.CreatedTime:yyyy-MM-dd HH:mm:ss}\",");
json.AppendLine($" \"Index\": {point.Index},");
json.AppendLine($" \"Notes\": \"{point.Notes}\"");
json.AppendLine(i < route.Points.Count - 1 ? " }," : " }");
}
json.AppendLine(" ]");
json.AppendLine("}");
File.WriteAllText(filePath, json.ToString(), Encoding.UTF8);
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"保存JSON文件失败: {ex.Message}");
return false;
}
}
///
/// 从JSON文件加载路径(简化版,仅支持基本格式)
///
public static PathRoute LoadFromJson(string filePath)
{
try
{
// 简化实现:仅支持基本的JSON格式
// 由于不依赖外部JSON库,这里使用XML格式作为fallback
System.Diagnostics.Debug.WriteLine("JSON加载功能简化,建议使用XML格式");
return null;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载JSON文件失败: {ex.Message}");
return null;
}
}
///
/// 将多个路径保存为XML文件
///
public static bool SaveRoutesToXml(List routes, string filePath)
{
try
{
var container = new PathRouteContainer { Routes = routes };
var serializer = new XmlSerializer(typeof(PathRouteContainer));
using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
{
serializer.Serialize(writer, container);
}
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"保存多路径XML文件失败: {ex.Message}");
return false;
}
}
///
/// 从XML文件加载多个路径
///
public static List LoadRoutesFromXml(string filePath)
{
try
{
var serializer = new XmlSerializer(typeof(PathRouteContainer));
using (var reader = new StreamReader(filePath, Encoding.UTF8))
{
var container = (PathRouteContainer)serializer.Deserialize(reader);
return container?.Routes ?? new List();
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载多路径XML文件失败: {ex.Message}");
return new List();
}
}
///
/// 检测文件格式
///
public static string DetectFileFormat(string filePath)
{
var extension = Path.GetExtension(filePath).ToLowerInvariant();
switch (extension)
{
case ".xml":
return "XML";
case ".json":
return "JSON";
default:
// 尝试检测内容
try
{
var content = File.ReadAllText(filePath).Trim();
if (content.StartsWith("<") && content.EndsWith(">"))
return "XML";
if (content.StartsWith("{") && content.EndsWith("}"))
return "JSON";
}
catch { }
return "未知";
}
}
}
///
/// 路径容器(用于保存多个路径)
///
[Serializable]
public class PathRouteContainer
{
public List Routes { get; set; } = new List();
public DateTime CreatedTime { get; set; } = DateTime.Now;
public string Version { get; set; } = "1.0";
public string Description { get; set; } = "";
}
}