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; } = ""; } }