From 58e7b858f126d1cd93cde0f6d0783042c8f540c1 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Thu, 22 Jan 2026 00:10:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B7=AF=E5=BE=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E8=B0=83=E7=94=A8=20RecalculateAndSaveRoute=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E7=A1=AE=E4=BF=9D=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=8E=E6=AD=A3=E7=A1=AE=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=92=8C=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Core/Animation/PathAnimationManager.cs | 5 +- src/Core/PathPlanningManager.cs | 63 +------- src/Core/PathPlanningModels.cs | 104 ++++++++----- src/Core/PathPointRenderPlugin.cs | 137 ------------------ src/PathPlanning/PathOptimizer.cs | 4 +- src/UI/WPF/ViewModels/PathEditingViewModel.cs | 10 ++ 6 files changed, 87 insertions(+), 236 deletions(-) diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 78234c2..b7c86da 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -2838,7 +2838,7 @@ namespace NavisworksTransport.Core.Animation } // 包含路径边的摘要信息(区分不同的曲线化结果) - if (route?.Edges != null) + if (route?.Edges != null && route.Edges.Count > 0) { foreach (var edge in route.Edges) { @@ -2853,6 +2853,9 @@ namespace NavisworksTransport.Core.Animation } } + // 包含路径最后修改时间(确保路径修改后重新生成动画) + sb.Append($"LastModified:{route?.LastModified:yyyyMMddHHmmss}"); + // 计算哈希 using (var md5 = System.Security.Cryptography.MD5.Create()) { diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs index 86d906e..d88cb19 100644 --- a/src/Core/PathPlanningManager.cs +++ b/src/Core/PathPlanningManager.cs @@ -511,7 +511,7 @@ namespace NavisworksTransport if (route != null && route.Points.Count >= 2 && generationMethod != RouteGenerationMethod.Manual) { // 使用统一的曲线化和保存方法 - RecalculateAndSaveRoute(route, $"RouteGenerated({generationMethod})"); + route.RecalculateAndSaveRoute($"RouteGenerated({generationMethod})"); } else if (generationMethod == RouteGenerationMethod.Manual) { @@ -631,7 +631,7 @@ namespace NavisworksTransport if (needRecalculate) { // 使用统一的曲线化和保存方法 - RecalculateAndSaveRoute(route, $"PathPointsListUpdated({updateReason})"); + route.RecalculateAndSaveRoute($"PathPointsListUpdated({updateReason})"); } var eventArgs = new PathPointsListUpdatedEventArgs(route, updateReason, _managerId); @@ -1771,7 +1771,7 @@ namespace NavisworksTransport UpdateAerialPathRelatedPoints(CurrentRoute, _editingPointIndex); // 核心修复:调用统一更新函数 - CurrentRoute.UpdatePathDataComplete($"修改路径点 {pointToUpdate.Name} 位置"); + CurrentRoute.RecalculateAndSaveRoute($"修改路径点 {pointToUpdate.Name} 位置"); // 添加历史记录 var historyEntry = new PathHistoryEntry( @@ -3249,59 +3249,6 @@ namespace NavisworksTransport /// /// 重新计算曲线化路径并保存到数据库 /// - /// 要计算的路径 - /// 上下文信息(用于日志) - private void RecalculateAndSaveRoute(PathRoute route, string context) - { - if (route == null || route.Points.Count < 2) - { - LogManager.Info($"跳过曲线化计算(路径点不足): {context}"); - return; - } - - try - { - // 空中路径不进行曲线化,直接保存 - if (route.PathType == PathType.Aerial) - { - string aerialSubTypeName = route.AerialSubType == AerialSubType.Rail ? "空轨" : "吊装"; - LogManager.Info($"{aerialSubTypeName}路径跳过曲线化,直接保存: {route.Name}"); - SavePathToDatabase(route); - LogManager.Info($"{aerialSubTypeName}路径已保存到数据库: {route.Name}"); - return; - } - - // 地面路径进行曲线化 - double samplingStep = ConfigManager.Instance.Current.PathEditing.ArcSamplingStep; - route.TurnRadius = ConfigManager.Instance.Current.PathEditing.DefaultPathTurnRadius; - List warnings; - PathCurveEngine.ApplyCurvatureToRoute(route, samplingStep, out warnings); - LogManager.Info($"路径曲线化完成({context}): {route.Name}, 转弯半径: {route.TurnRadius:F2}m, 边数: {route.Edges.Count}"); - - // 如果有警告,显示到状态栏 - if (warnings != null && warnings.Count > 0) - { - // 只显示第一个警告(避免刷屏) - string firstWarning = warnings[0]; - if (warnings.Count > 1) - { - firstWarning += $"(还有 {warnings.Count - 1} 个类似问题)"; - } - - // 通过StatusChanged事件发送警告 - RaiseStatusChanged(firstWarning, PathPlanningStatusType.Warning); - LogManager.Warning($"路径曲线化警告: {firstWarning}"); - } - - // 曲线化计算完成后,立即保存数据库 - SavePathToDatabase(route); - LogManager.Info($"路径曲线化后已保存到数据库: {route.Name}"); - } - catch (Exception ex) - { - LogManager.Error($"路径曲线化和保存失败({context}): {ex.Message}", ex); - } - } #endregion @@ -3323,7 +3270,7 @@ namespace NavisworksTransport if (route == null) return; // 使用统一的曲线化和保存方法 - RecalculateAndSaveRoute(route, "UpdateRoute"); + route.RecalculateAndSaveRoute("UpdateRoute"); } #endregion @@ -4144,7 +4091,7 @@ namespace NavisworksTransport /// /// 保存路径时同时保存到数据库 /// - private void SavePathToDatabase(PathRoute route) + public void SavePathToDatabase(PathRoute route) { try { diff --git a/src/Core/PathPlanningModels.cs b/src/Core/PathPlanningModels.cs index 33e7a65..28aecf1 100644 --- a/src/Core/PathPlanningModels.cs +++ b/src/Core/PathPlanningModels.cs @@ -662,7 +662,7 @@ namespace NavisworksTransport { Points.Add(point); // 调用统一更新函数(内部会重新设置索引) - UpdatePathDataComplete("添加路径点"); + RecalculateAndSaveRoute("添加路径点"); } /// @@ -674,7 +674,7 @@ namespace NavisworksTransport { Points.Insert(insertIndex, point); // 调用统一更新函数(内部会重新设置索引) - UpdatePathDataComplete("插入路径点"); + RecalculateAndSaveRoute("插入路径点"); } /// @@ -687,7 +687,7 @@ namespace NavisworksTransport if (removed) { // 调用统一更新函数(内部会重新设置索引) - UpdatePathDataComplete("移除路径点"); + RecalculateAndSaveRoute("移除路径点"); } return removed; } @@ -716,7 +716,7 @@ namespace NavisworksTransport Edges.Clear(); IsCurved = false; // 调用统一更新函数 - UpdatePathDataComplete("清空路径点"); + RecalculateAndSaveRoute("清空路径点"); } /// @@ -781,50 +781,78 @@ namespace NavisworksTransport } /// - /// 完整更新路径数据(坐标点、边、曲线、长度) - /// 根据路径类型自动决定是否重新计算曲线 + /// 重新计算路径数据并保存到数据库 + /// 统一的路径数据更新入口:重新设置索引、更新长度、计算曲线、保存到数据库 /// - /// 更新原因(用于日志) - public void UpdatePathDataComplete(string updateReason = "路径数据更新") + /// 上下文信息(用于日志) + public void RecalculateAndSaveRoute(string context = "路径数据更新") { - // 1. 重新设置路径点索引 - for (int i = 0; i < Points.Count; i++) + if (Points.Count < 2) { - Points[i].Index = i; + LogManager.Info($"跳过路径数据更新(路径点不足): {Name}, 原因: {context}"); + return; } - // 2. 根据路径类型决定是否重新计算曲线 - if (PathType == PathType.Ground) + try { - // 地面路径:需要曲线化 - double samplingStep = ConfigManager.Instance.Current.PathEditing.ArcSamplingStep; - double turnRadius = ConfigManager.Instance.Current.PathEditing.DefaultPathTurnRadius; + // 1. 重新设置路径点索引 + for (int i = 0; i < Points.Count; i++) + { + Points[i].Index = i; + } - PathCurveEngine.ApplyCurvatureToRoute(this, samplingStep, out _); - LogManager.Info($"[路径更新] 地面路径已重新曲线化: {Name}"); + // 2. 根据路径类型决定是否重新计算曲线 + if (PathType == PathType.Aerial) + { + // 空中路径:使用直线,不需要曲线化 + Edges.Clear(); + IsCurved = false; + UpdateTotalLength(); + string aerialSubTypeName = AerialSubType == AerialSubType.Rail ? "空轨" : "吊装"; + LogManager.Info($"{aerialSubTypeName}路径已更新(直线模式): {Name}, 原因: {context}"); + } + else if (PathType == PathType.Ground) + { + // 地面路径:进行曲线化 + double samplingStep = ConfigManager.Instance.Current.PathEditing.ArcSamplingStep; + TurnRadius = ConfigManager.Instance.Current.PathEditing.DefaultPathTurnRadius; + List warnings; + PathCurveEngine.ApplyCurvatureToRoute(this, samplingStep, out warnings); + LogManager.Info($"地面路径已曲线化: {Name}, 原因: {context}, 转弯半径: {TurnRadius:F2}m, 边数: {Edges.Count}"); + + // 如果有警告,记录日志 + if (warnings != null && warnings.Count > 0) + { + foreach (var warning in warnings) + { + LogManager.Warning($"路径曲线化警告: {warning}"); + } + } + } + else + { + // 未知路径类型:使用直线 + Edges.Clear(); + IsCurved = false; + UpdateTotalLength(); + LogManager.Warning($"未知路径类型,使用直线模式: {Name}, 原因: {context}"); + } + + // 3. 更新最后修改时间 + LastModified = DateTime.Now; + + // 4. 保存到数据库(通过PathPlanningManager) + var pathPlanningManager = PathPlanningManager.Instance; + if (pathPlanningManager != null) + { + pathPlanningManager.SavePathToDatabase(this); + LogManager.Info($"路径数据已保存到数据库: {Name}, 原因: {context}, 总长度: {TotalLength:F2}米"); + } } - else if (PathType == PathType.Aerial) + catch (Exception ex) { - // 吊装/空轨路径:使用直线,不需要曲线化 - // 清空Edges,使用Points直接计算 - Edges.Clear(); - IsCurved = false; - UpdateTotalLength(); - LogManager.Info($"[路径更新] 空中路径已更新(直线模式): {Name}"); + LogManager.Error($"路径数据更新和保存失败({context}): {ex.Message}", ex); } - else - { - // 未知路径类型:使用直线 - Edges.Clear(); - IsCurved = false; - UpdateTotalLength(); - LogManager.Warning($"[路径更新] 未知路径类型,使用直线模式: {Name}"); - } - - // 3. 更新最后修改时间 - LastModified = DateTime.Now; - - LogManager.Info($"[路径更新] 路径数据完整更新完成: {Name}, 原因: {updateReason}, 总长度: {TotalLength:F2}米"); } /// diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs index 2e6a4ce..959393a 100644 --- a/src/Core/PathPointRenderPlugin.cs +++ b/src/Core/PathPointRenderPlugin.cs @@ -2149,143 +2149,6 @@ namespace NavisworksTransport return lineRadiusInMeters * UnitsConverter.GetMetersToUnitsConversionFactor(); } - /// - /// 添加路径点到指定路径 - /// - /// 路径ID - /// 新的路径点 - /// 插入位置索引,-1表示添加到末尾 - public void AddPointToPath(string pathId, PathPoint newPoint, int insertIndex = -1) - { - var visualization = GetPathVisualization(pathId); - if (visualization == null) - { - return; - } - - try - { - var pathRoute = visualization.PathRoute; - - if (insertIndex == -1) - { - // 添加到末尾 - newPoint.Index = pathRoute.Points.Count; - pathRoute.Points.Add(newPoint); - } - else - { - // 插入到指定位置 - pathRoute.Points.Insert(insertIndex, newPoint); - // 重新分配所有点的索引 - ReindexPoints(pathRoute); - } - - // 重建可视化 - BuildVisualization(visualization); - RequestViewRefresh(); - } - catch (Exception ex) - { - LogManager.Error($"[路径编辑] 添加路径点失败: {ex.Message}", ex); - } - } - - /// - /// 从指定路径移除路径点 - /// - /// 路径ID - /// 要移除的点索引 - public void RemovePointFromPath(string pathId, int pointIndex) - { - var visualization = GetPathVisualization(pathId); - if (visualization == null) - { - return; - } - - try - { - var pathRoute = visualization.PathRoute; - var pointToRemove = pathRoute.Points.FirstOrDefault(p => p.Index == pointIndex); - - if (pointToRemove != null) - { - pathRoute.Points.Remove(pointToRemove); - // 重新分配索引 - ReindexPoints(pathRoute); - - // 重建可视化 - BuildVisualization(visualization); - RequestViewRefresh(); - } - else - { - LogManager.Warning($"[路径编辑] 未找到索引为 {pointIndex} 的路径点"); - } - } - catch (Exception ex) - { - LogManager.Error($"[路径编辑] 移除路径点失败: {ex.Message}", ex); - } - } - - /// - /// 更新指定路径中的路径点 - /// - /// 路径ID - /// 要更新的点索引 - /// 更新后的路径点 - public void UpdatePointInPath(string pathId, int pointIndex, PathPoint updatedPoint) - { - var visualization = GetPathVisualization(pathId); - if (visualization == null) - { - return; - } - - try - { - var pathRoute = visualization.PathRoute; - var existingPoint = pathRoute.Points.FirstOrDefault(p => p.Index == pointIndex); - - if (existingPoint != null) - { - // 保持索引不变 - updatedPoint.Index = pointIndex; - - // 替换点 - var index = pathRoute.Points.IndexOf(existingPoint); - pathRoute.Points[index] = updatedPoint; - - // 重建可视化 - BuildVisualization(visualization); - RequestViewRefresh(); - } - else - { - LogManager.Warning($"[路径编辑] 未找到索引为 {pointIndex} 的路径点"); - } - } - catch (Exception ex) - { - LogManager.Error($"[路径编辑] 更新路径点失败: {ex.Message}", ex); - } - } - - /// - /// 重新分配路径点索引 - /// - /// 路径对象 - private void ReindexPoints(PathRoute pathRoute) - { - // 按照当前在List中的位置重新分配连续索引 - for (int i = 0; i < pathRoute.Points.Count; i++) - { - pathRoute.Points[i].Index = i; - } - } - /// /// 获取路径可视化对象 /// diff --git a/src/PathPlanning/PathOptimizer.cs b/src/PathPlanning/PathOptimizer.cs index 0aaafda..b82bb5e 100644 --- a/src/PathPlanning/PathOptimizer.cs +++ b/src/PathPlanning/PathOptimizer.cs @@ -477,8 +477,8 @@ namespace NavisworksTransport.PathPlanning optimizedRoute.Points.Add(point); } - // 重新计算路径长度 - optimizedRoute.RecalculateLength(); + // 重新计算路径数据并保存到数据库 + optimizedRoute.RecalculateAndSaveRoute("路径优化"); return optimizedRoute; } diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs index d095b80..6b4d984 100644 --- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs +++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs @@ -1832,6 +1832,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels { var pointCount = SelectedPathRoute.Points.Count; + // 清空 Core 层的路径点 + var coreRoute = _pathPlanningManager?.Routes?.FirstOrDefault(r => r.Name == SelectedPathRoute.Name); + if (coreRoute != null) + { + coreRoute.Points.Clear(); + coreRoute.RecalculateAndSaveRoute("清空路径"); + LogManager.Info($"已清空Core路径: {coreRoute.Name}"); + } + + // 清空 UI 层的路径点 await _uiStateManager.ExecuteUIUpdateAsync(() => { SelectedPathRoute.Points.Clear();