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);
}
}
}