NavisworksTransport/PathPlanningModels.cs

2026 lines
64 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 路径编辑状态枚举
/// </summary>
public enum PathEditState
{
/// <summary>
/// 查看状态 - 只能查看路径,不能编辑
/// </summary>
Viewing,
/// <summary>
/// 新建状态 - 正在创建新路径
/// </summary>
Creating,
/// <summary>
/// 编辑状态 - 正在编辑现有路径
/// </summary>
Editing
}
/// <summary>
/// 通道检测结果
/// </summary>
public class ChannelDetectionResult
{
/// <summary>
/// 是否为有效位置
/// </summary>
public bool IsValidLocation { get; set; }
/// <summary>
/// 检测消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 检测方法
/// </summary>
public string DetectionMethod { get; set; }
}
/// <summary>
/// 物流通道检测结果
/// </summary>
public class LogisticsChannelDetectionResult
{
/// <summary>
/// 是否为有效通道
/// </summary>
public bool IsValidChannel { get; set; }
/// <summary>
/// 通道类型名称
/// </summary>
public string ChannelType { get; set; }
/// <summary>
/// 检测到的通道模型项
/// </summary>
public ModelItem DetectedChannel { get; set; }
/// <summary>
/// 物流类别
/// </summary>
public CategoryAttributeManager.LogisticsElementType? LogisticsCategory { get; set; }
/// <summary>
/// 检测置信度
/// </summary>
public double DetectionConfidence { get; set; }
/// <summary>
/// 错误消息
/// </summary>
public string ErrorMessage { get; set; }
}
/// <summary>
/// 几何分析结果
/// </summary>
public class GeometryAnalysisResult
{
/// <summary>
/// 是否可能是通道
/// </summary>
public bool IsLikelyChannel { get; set; }
/// <summary>
/// 分析原因
/// </summary>
public string Reason { get; set; }
/// <summary>
/// 最可能的通道模型项
/// </summary>
public ModelItem MostLikelyChannel { get; set; }
/// <summary>
/// 置信度
/// </summary>
public double Confidence { get; set; }
}
/// <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位置不参与XML序列化
/// </summary>
[XmlIgnore]
public Point3D Position { get; set; }
/// <summary>
/// X坐标用于XML序列化
/// </summary>
[XmlElement("X")]
public double X
{
get => Position.X;
set
{
if (Position == null)
Position = new Point3D(value, 0, 0);
else
Position = new Point3D(value, Position.Y, Position.Z);
}
}
/// <summary>
/// Y坐标用于XML序列化
/// </summary>
[XmlElement("Y")]
public double Y
{
get => Position.Y;
set
{
if (Position == null)
Position = new Point3D(0, value, 0);
else
Position = new Point3D(Position.X, value, Position.Z);
}
}
/// <summary>
/// Z坐标用于XML序列化
/// </summary>
[XmlElement("Z")]
public double Z
{
get => Position.Z;
set
{
if (Position == null)
Position = new Point3D(0, 0, value);
else
Position = new Point3D(Position.X, Position.Y, value);
}
}
/// <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("微软雅黑", 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);
}
/// <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("微软雅黑", 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);
}
/// <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("微软雅黑", 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);
}
/// <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;
}
/// <summary>
/// 路径历史记录项
/// </summary>
[Serializable]
public class PathHistoryEntry
{
/// <summary>
/// 历史记录唯一标识符
/// </summary>
public string Id { get; set; }
/// <summary>
/// 关联的路径ID
/// </summary>
public string RouteId { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public PathHistoryOperationType OperationType { get; set; }
/// <summary>
/// 路径快照(操作前的状态)
/// </summary>
public PathRoute RouteSnapshot { get; set; }
/// <summary>
/// 操作时间
/// </summary>
public DateTime OperationTime { get; set; }
/// <summary>
/// 操作描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 版本号
/// </summary>
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;
}
}
/// <summary>
/// 路径历史操作类型
/// </summary>
public enum PathHistoryOperationType
{
/// <summary>
/// 创建路径
/// </summary>
Created,
/// <summary>
/// 编辑路径
/// </summary>
Edited,
/// <summary>
/// 删除路径点
/// </summary>
PointRemoved,
/// <summary>
/// 添加路径点
/// </summary>
PointAdded,
/// <summary>
/// 路径优化
/// </summary>
Optimized,
/// <summary>
/// 手动保存
/// </summary>
ManualSave
}
/// <summary>
/// 路径历史管理器
/// </summary>
public class PathHistoryManager
{
private Dictionary<string, List<PathHistoryEntry>> _routeHistories;
private int _maxHistoryCount;
/// <summary>
/// 历史记录变更事件
/// </summary>
public event EventHandler<PathHistoryEntry> HistoryEntryAdded;
public PathHistoryManager(int maxHistoryCount = 50)
{
_routeHistories = new Dictionary<string, List<PathHistoryEntry>>();
_maxHistoryCount = maxHistoryCount;
}
/// <summary>
/// 添加历史记录
/// </summary>
public void AddHistoryEntry(PathHistoryEntry entry)
{
if (string.IsNullOrEmpty(entry.RouteId)) return;
if (!_routeHistories.ContainsKey(entry.RouteId))
{
_routeHistories[entry.RouteId] = new List<PathHistoryEntry>();
}
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);
}
/// <summary>
/// 获取路径的历史记录
/// </summary>
public List<PathHistoryEntry> GetRouteHistory(string routeId)
{
return _routeHistories.ContainsKey(routeId) ?
new List<PathHistoryEntry>(_routeHistories[routeId]) :
new List<PathHistoryEntry>();
}
/// <summary>
/// 获取最新的历史记录
/// </summary>
public PathHistoryEntry GetLatestHistory(string routeId)
{
var histories = GetRouteHistory(routeId);
return histories.LastOrDefault();
}
/// <summary>
/// 清理路径的历史记录
/// </summary>
public void ClearRouteHistory(string routeId)
{
if (_routeHistories.ContainsKey(routeId))
{
_routeHistories.Remove(routeId);
}
}
/// <summary>
/// 获取所有路径的历史记录统计
/// </summary>
public Dictionary<string, int> GetHistoryStatistics()
{
return _routeHistories.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Count
);
}
/// <summary>
/// 获取所有历史记录
/// </summary>
/// <returns>所有历史记录的列表,按时间倒序排列</returns>
public List<PathHistoryEntry> GetAllHistoryEntries()
{
var allEntries = new List<PathHistoryEntry>();
foreach (var routeHistory in _routeHistories.Values)
{
allEntries.AddRange(routeHistory);
}
// 按操作时间倒序排列(最新的在前)
return allEntries.OrderByDescending(entry => entry.OperationTime).ToList();
}
}
/// <summary>
/// 路径文件序列化帮助类
/// </summary>
public static class PathFileSerializer
{
/// <summary>
/// 将路径保存为XML文件
/// </summary>
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;
}
}
/// <summary>
/// 从XML文件加载路径
/// </summary>
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;
}
}
/// <summary>
/// 将路径保存为JSON文件简化版
/// </summary>
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;
}
}
/// <summary>
/// 从JSON文件加载路径简化版仅支持基本格式
/// </summary>
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;
}
}
/// <summary>
/// 将多个路径保存为XML文件
/// </summary>
public static bool SaveRoutesToXml(List<PathRoute> 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;
}
}
/// <summary>
/// 从XML文件加载多个路径
/// </summary>
public static List<PathRoute> 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<PathRoute>();
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载多路径XML文件失败: {ex.Message}");
return new List<PathRoute>();
}
}
/// <summary>
/// 检测文件格式
/// </summary>
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 "未知";
}
}
}
/// <summary>
/// 路径容器(用于保存多个路径)
/// </summary>
[Serializable]
public class PathRouteContainer
{
public List<PathRoute> Routes { get; set; } = new List<PathRoute>();
public DateTime CreatedTime { get; set; } = DateTime.Now;
public string Version { get; set; } = "1.0";
public string Description { get; set; } = "";
}
}