using System; using System.Collections.Generic; using System.IO; using System.Xml; using System.Xml.Serialization; using System.Text; using System.Linq; using Autodesk.Navisworks.Api; namespace NavisworksTransport { /// /// 路径数据管理器 /// 负责路径数据的导入导出、持久化存储和DELMIA格式兼容 /// public class PathDataManager { private const string DEFAULT_EXPORT_FOLDER = "PathPlanningExports"; private const string DEFAULT_FILE_EXTENSION = ".xml"; private const string JSON_FILE_EXTENSION = ".json"; // DELMIA兼容格式配置 private readonly string _delmiaNamespace = "http://www.3ds.com/delmia/pathplanning"; private readonly string _delmiaVersion = "1.0"; /// /// 导出路径到XML文件(DELMIA兼容格式) /// /// 路径集合 /// 文件路径 /// 导出设置 /// 是否成功 public bool ExportToXml(List routes, string filePath, ExportSettings exportSettings = null) { if (routes == null || routes.Count == 0) { throw new ArgumentException("路径集合不能为空"); } try { // 确保导出目录存在 var directory = Path.GetDirectoryName(filePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } // 创建XML文档 var xmlDoc = new XmlDocument(); var declaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null); xmlDoc.AppendChild(declaration); // 创建根元素 var rootElement = xmlDoc.CreateElement("PathPlanningData", _delmiaNamespace); rootElement.SetAttribute("version", _delmiaVersion); rootElement.SetAttribute("generator", "NavisworksTransport"); rootElement.SetAttribute("timestamp", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss")); xmlDoc.AppendChild(rootElement); // 添加项目信息 var projectInfo = CreateProjectInfoElement(xmlDoc, exportSettings); rootElement.AppendChild(projectInfo); // 添加路径数据 var routesElement = xmlDoc.CreateElement("Routes", _delmiaNamespace); rootElement.AppendChild(routesElement); foreach (var route in routes) { if (route.IsValid()) { var routeElement = CreateRouteElement(xmlDoc, route, exportSettings); routesElement.AppendChild(routeElement); } } // 保存文件 using (var writer = new XmlTextWriter(filePath, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.Indentation = 2; xmlDoc.WriteTo(writer); } return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"导出XML文件失败: {ex.Message}"); return false; } } /// /// 从XML文件导入路径 /// /// 文件路径 /// 路径集合 public List ImportFromXml(string filePath) { var routes = new List(); if (!File.Exists(filePath)) { throw new FileNotFoundException($"文件不存在: {filePath}"); } try { var xmlDoc = new XmlDocument(); xmlDoc.Load(filePath); // 验证根元素 var rootElement = xmlDoc.DocumentElement; if (rootElement?.Name != "PathPlanningData") { throw new InvalidOperationException("无效的路径规划数据文件格式"); } // 读取路径数据 var routesElement = rootElement.SelectSingleNode("*[local-name()='Routes']"); if (routesElement != null) { foreach (XmlNode routeNode in routesElement.ChildNodes) { if (routeNode.NodeType == XmlNodeType.Element) { var route = ParseRouteElement(routeNode); if (route != null && route.IsValid()) { routes.Add(route); } } } } return routes; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"导入XML文件失败: {ex.Message}"); throw; } } /// /// 导出路径到JSON文件(简化实现) /// /// 路径集合 /// 文件路径 /// 导出设置 /// 是否成功 public bool ExportToJson(List routes, string filePath, ExportSettings exportSettings = null) { // JSON功能暂未实现,建议使用XML格式 return ExportToXml(routes, filePath.Replace(".json", ".xml"), exportSettings); } /// /// 从JSON文件导入路径(简化实现) /// /// 文件路径 /// 路径集合 public List ImportFromJson(string filePath) { // JSON功能暂未实现,建议使用XML格式 return ImportFromXml(filePath.Replace(".json", ".xml")); } /// /// 保存路径到Navisworks文件 /// /// 路径集合 /// 文件路径 /// 是否成功 public bool SaveToNavisworksFile(List routes, string filePath) { try { // 创建临时属性来存储路径数据 var document = Application.ActiveDocument; if (document == null) { throw new InvalidOperationException("没有活动的Navisworks文档"); } // 简化实现:跳过路径数据序列化 // 这里可以将路径数据保存为自定义属性 // 由于Navisworks API的限制,这里是简化实现 // 实际应用中可能需要使用COM API来添加自定义属性 // 保存当前文档 if (Path.GetExtension(filePath).ToLower() == ".nwd") { document.PublishFile(filePath, new PublishProperties()); } else { document.SaveFile(filePath); } return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"保存到Navisworks文件失败: {ex.Message}"); return false; } } /// /// 从Navisworks文件加载路径 /// /// 文件路径 /// 路径集合 public List LoadFromNavisworksFile(string filePath) { var routes = new List(); try { // 这里应该从Navisworks文件的自定义属性中读取路径数据 // 由于API限制,这里是简化实现 // 实际应用中需要使用COM API来读取自定义属性 return routes; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"从Navisworks文件加载失败: {ex.Message}"); return routes; } } /// /// 导出DELMIA兼容格式 /// /// 路径集合 /// 文件路径 /// 导出设置 /// 是否成功 public bool ExportDelmiaFormat(List routes, string filePath, ExportSettings exportSettings = null) { try { // 确保导出目录存在 var directory = Path.GetDirectoryName(filePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } var xmlDoc = new XmlDocument(); var declaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null); xmlDoc.AppendChild(declaration); // 创建DELMIA格式的根元素 var rootElement = xmlDoc.CreateElement("DELMIA_PathPlanning", _delmiaNamespace); rootElement.SetAttribute("version", _delmiaVersion); rootElement.SetAttribute("units", exportSettings?.Units ?? "meters"); xmlDoc.AppendChild(rootElement); // 添加任务信息 var taskInfo = xmlDoc.CreateElement("TaskInfo", _delmiaNamespace); taskInfo.SetAttribute("name", exportSettings?.ProjectName ?? "物流路径规划"); taskInfo.SetAttribute("description", exportSettings?.Description ?? "从Navisworks导出的路径规划任务"); taskInfo.SetAttribute("created", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss")); rootElement.AppendChild(taskInfo); // 添加路径集合 var pathsElement = xmlDoc.CreateElement("Paths", _delmiaNamespace); rootElement.AppendChild(pathsElement); foreach (var route in routes.Where(r => r.IsValid())) { var pathElement = CreateDelmiaPathElement(xmlDoc, route, exportSettings); pathsElement.AppendChild(pathElement); } // 保存文件 using (var writer = new XmlTextWriter(filePath, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.Indentation = 2; xmlDoc.WriteTo(writer); } return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"导出DELMIA格式失败: {ex.Message}"); return false; } } /// /// 获取默认导出路径 /// /// 文件名 /// 格式 /// 完整路径 public string GetDefaultExportPath(string fileName, ExportFormat format) { var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var exportPath = Path.Combine(documentsPath, DEFAULT_EXPORT_FOLDER); if (!Directory.Exists(exportPath)) { Directory.CreateDirectory(exportPath); } var extension = format == ExportFormat.Json ? JSON_FILE_EXTENSION : DEFAULT_FILE_EXTENSION; return Path.Combine(exportPath, fileName + extension); } /// /// 验证导出文件 /// /// 文件路径 /// 格式 /// 验证结果 public ValidationResult ValidateExportFile(string filePath, ExportFormat format) { var result = new ValidationResult(); try { if (!File.Exists(filePath)) { result.IsValid = false; result.Errors.Add("文件不存在"); return result; } if (format == ExportFormat.Xml) { // 验证XML格式 var xmlDoc = new XmlDocument(); xmlDoc.Load(filePath); if (xmlDoc.DocumentElement?.Name != "PathPlanningData" && xmlDoc.DocumentElement?.Name != "DELMIA_PathPlanning") { result.Warnings.Add("XML根元素格式可能不正确"); } } else if (format == ExportFormat.Json) { // JSON验证暂未实现 result.Warnings.Add("JSON格式验证暂未实现,建议使用XML格式"); } result.IsValid = true; } catch (Exception ex) { result.IsValid = false; result.Errors.Add($"文件验证失败: {ex.Message}"); } return result; } #region 私有辅助方法 /// /// 创建项目信息元素 /// private XmlElement CreateProjectInfoElement(XmlDocument xmlDoc, ExportSettings settings) { var projectInfo = xmlDoc.CreateElement("ProjectInfo", _delmiaNamespace); projectInfo.SetAttribute("name", settings?.ProjectName ?? "NavisworksTransport路径规划"); projectInfo.SetAttribute("description", settings?.Description ?? "物流路径规划数据"); projectInfo.SetAttribute("units", settings?.Units ?? "meters"); projectInfo.SetAttribute("coordinateSystem", settings?.CoordinateSystem ?? "Global"); return projectInfo; } /// /// 创建路径元素 /// private XmlElement CreateRouteElement(XmlDocument xmlDoc, PathRoute route, ExportSettings settings) { var routeElement = xmlDoc.CreateElement("Route", _delmiaNamespace); routeElement.SetAttribute("id", route.Id); routeElement.SetAttribute("name", route.Name); routeElement.SetAttribute("description", route.Description ?? ""); routeElement.SetAttribute("totalLength", route.TotalLength.ToString("F3")); routeElement.SetAttribute("created", route.CreatedTime.ToString("yyyy-MM-ddTHH:mm:ss")); // 添加路径点 var pointsElement = xmlDoc.CreateElement("Points", _delmiaNamespace); routeElement.AppendChild(pointsElement); var sortedPoints = route.GetSortedPoints(); foreach (var point in sortedPoints) { var pointElement = xmlDoc.CreateElement("Point", _delmiaNamespace); pointElement.SetAttribute("id", point.Id); pointElement.SetAttribute("name", point.Name); pointElement.SetAttribute("type", point.Type.ToString()); pointElement.SetAttribute("index", point.Index.ToString()); pointElement.SetAttribute("x", point.Position.X.ToString("F6")); pointElement.SetAttribute("y", point.Position.Y.ToString("F6")); pointElement.SetAttribute("z", point.Position.Z.ToString("F6")); pointElement.SetAttribute("created", point.CreatedTime.ToString("yyyy-MM-ddTHH:mm:ss")); pointsElement.AppendChild(pointElement); } return routeElement; } /// /// 解析路径元素 /// private PathRoute ParseRouteElement(XmlNode routeNode) { try { var route = new PathRoute { Id = routeNode.Attributes?["id"]?.Value ?? Guid.NewGuid().ToString(), Name = routeNode.Attributes?["name"]?.Value ?? "导入路径", Description = routeNode.Attributes?["description"]?.Value ?? "" }; // 解析创建时间 if (DateTime.TryParse(routeNode.Attributes?["created"]?.Value, out DateTime createdTime)) { route.CreatedTime = createdTime; } // 解析路径点 var pointsNode = routeNode.SelectSingleNode("*[local-name()='Points']"); if (pointsNode != null) { foreach (XmlNode pointNode in pointsNode.ChildNodes) { if (pointNode.NodeType == XmlNodeType.Element) { var point = ParsePointElement(pointNode); if (point != null) { route.AddPoint(point); } } } } return route; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"解析路径元素失败: {ex.Message}"); return null; } } /// /// 解析路径点元素 /// private PathPoint ParsePointElement(XmlNode pointNode) { try { var point = new PathPoint { Id = pointNode.Attributes?["id"]?.Value ?? Guid.NewGuid().ToString(), Name = pointNode.Attributes?["name"]?.Value ?? "" }; // 解析位置 if (double.TryParse(pointNode.Attributes?["x"]?.Value, out double x) && double.TryParse(pointNode.Attributes?["y"]?.Value, out double y) && double.TryParse(pointNode.Attributes?["z"]?.Value, out double z)) { point.Position = new Point3D(x, y, z); } // 解析索引 if (int.TryParse(pointNode.Attributes?["index"]?.Value, out int index)) { point.Index = index; } // 解析类型 if (Enum.TryParse(pointNode.Attributes?["type"]?.Value, out PathPointType type)) { point.Type = type; } // 解析创建时间 if (DateTime.TryParse(pointNode.Attributes?["created"]?.Value, out DateTime createdTime)) { point.CreatedTime = createdTime; } return point; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"解析路径点元素失败: {ex.Message}"); return null; } } /// /// 创建DELMIA路径元素 /// private XmlElement CreateDelmiaPathElement(XmlDocument xmlDoc, PathRoute route, ExportSettings settings) { var pathElement = xmlDoc.CreateElement("Path", _delmiaNamespace); pathElement.SetAttribute("id", route.Id); pathElement.SetAttribute("name", route.Name); pathElement.SetAttribute("type", "Transportation"); pathElement.SetAttribute("length", route.TotalLength.ToString("F3")); // 添加路径段 var segmentsElement = xmlDoc.CreateElement("Segments", _delmiaNamespace); pathElement.AppendChild(segmentsElement); var sortedPoints = route.GetSortedPoints(); for (int i = 0; i < sortedPoints.Count - 1; i++) { var segmentElement = xmlDoc.CreateElement("Segment", _delmiaNamespace); segmentElement.SetAttribute("index", i.ToString()); // 起点 var startElement = xmlDoc.CreateElement("Start", _delmiaNamespace); AddDelmiaPointData(xmlDoc, startElement, sortedPoints[i]); segmentElement.AppendChild(startElement); // 终点 var endElement = xmlDoc.CreateElement("End", _delmiaNamespace); AddDelmiaPointData(xmlDoc, endElement, sortedPoints[i + 1]); segmentElement.AppendChild(endElement); segmentsElement.AppendChild(segmentElement); } return pathElement; } /// /// 添加DELMIA点数据 /// private void AddDelmiaPointData(XmlDocument xmlDoc, XmlElement element, PathPoint point) { element.SetAttribute("x", point.Position.X.ToString("F6")); element.SetAttribute("y", point.Position.Y.ToString("F6")); element.SetAttribute("z", point.Position.Z.ToString("F6")); element.SetAttribute("name", point.Name); element.SetAttribute("type", point.Type.ToString()); } #endregion } /// /// 导出格式枚举 /// public enum ExportFormat { Xml, Json, Delmia, Navisworks } /// /// 导出设置 /// public class ExportSettings { /// /// 项目名称 /// public string ProjectName { get; set; } = "NavisworksTransport路径规划"; /// /// 项目描述 /// public string Description { get; set; } = "物流路径规划数据"; /// /// 单位 /// public string Units { get; set; } = "meters"; /// /// 坐标系 /// public string CoordinateSystem { get; set; } = "Global"; /// /// 是否包含时间戳 /// public bool IncludeTimestamps { get; set; } = true; /// /// 是否包含元数据 /// public bool IncludeMetadata { get; set; } = true; /// /// 精度(小数位数) /// public int Precision { get; set; } = 6; } /// /// 验证结果 /// public class ValidationResult { /// /// 是否有效 /// public bool IsValid { get; set; } = true; /// /// 错误信息 /// public List Errors { get; set; } = new List(); /// /// 警告信息 /// public List Warnings { get; set; } = new List(); /// /// 获取所有消息 /// /// 消息集合 public IEnumerable GetAllMessages() { return Errors.Concat(Warnings); } } }