优化路径数据更新逻辑,统一调用 RecalculateAndSaveRoute 方法,确保路径修改后正确保存和更新

This commit is contained in:
tian 2026-01-22 00:10:30 +08:00
parent 52ca335e9f
commit 58e7b858f1
6 changed files with 87 additions and 236 deletions

View File

@ -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())
{

View File

@ -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
/// <summary>
/// 重新计算曲线化路径并保存到数据库
/// </summary>
/// <param name="route">要计算的路径</param>
/// <param name="context">上下文信息(用于日志)</param>
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<string> 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
/// <summary>
/// 保存路径时同时保存到数据库
/// </summary>
private void SavePathToDatabase(PathRoute route)
public void SavePathToDatabase(PathRoute route)
{
try
{

View File

@ -662,7 +662,7 @@ namespace NavisworksTransport
{
Points.Add(point);
// 调用统一更新函数(内部会重新设置索引)
UpdatePathDataComplete("添加路径点");
RecalculateAndSaveRoute("添加路径点");
}
/// <summary>
@ -674,7 +674,7 @@ namespace NavisworksTransport
{
Points.Insert(insertIndex, point);
// 调用统一更新函数(内部会重新设置索引)
UpdatePathDataComplete("插入路径点");
RecalculateAndSaveRoute("插入路径点");
}
/// <summary>
@ -687,7 +687,7 @@ namespace NavisworksTransport
if (removed)
{
// 调用统一更新函数(内部会重新设置索引)
UpdatePathDataComplete("移除路径点");
RecalculateAndSaveRoute("移除路径点");
}
return removed;
}
@ -716,7 +716,7 @@ namespace NavisworksTransport
Edges.Clear();
IsCurved = false;
// 调用统一更新函数
UpdatePathDataComplete("清空路径点");
RecalculateAndSaveRoute("清空路径点");
}
/// <summary>
@ -781,50 +781,78 @@ namespace NavisworksTransport
}
/// <summary>
/// 完整更新路径数据(坐标点、边、曲线、长度)
/// 根据路径类型自动决定是否重新计算曲线
/// 重新计算路径数据并保存到数据库
/// 统一的路径数据更新入口:重新设置索引、更新长度、计算曲线、保存到数据库
/// </summary>
/// <param name="updateReason">更新原因(用于日志)</param>
public void UpdatePathDataComplete(string updateReason = "路径数据更新")
/// <param name="context">上下文信息(用于日志)</param>
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<string> 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}米");
}
/// <summary>

View File

@ -2149,143 +2149,6 @@ namespace NavisworksTransport
return lineRadiusInMeters * UnitsConverter.GetMetersToUnitsConversionFactor();
}
/// <summary>
/// 添加路径点到指定路径
/// </summary>
/// <param name="pathId">路径ID</param>
/// <param name="newPoint">新的路径点</param>
/// <param name="insertIndex">插入位置索引,-1表示添加到末尾</param>
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);
}
}
/// <summary>
/// 从指定路径移除路径点
/// </summary>
/// <param name="pathId">路径ID</param>
/// <param name="pointIndex">要移除的点索引</param>
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);
}
}
/// <summary>
/// 更新指定路径中的路径点
/// </summary>
/// <param name="pathId">路径ID</param>
/// <param name="pointIndex">要更新的点索引</param>
/// <param name="updatedPoint">更新后的路径点</param>
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);
}
}
/// <summary>
/// 重新分配路径点索引
/// </summary>
/// <param name="pathRoute">路径对象</param>
private void ReindexPoints(PathRoute pathRoute)
{
// 按照当前在List中的位置重新分配连续索引
for (int i = 0; i < pathRoute.Points.Count; i++)
{
pathRoute.Points[i].Index = i;
}
}
/// <summary>
/// 获取路径可视化对象
/// </summary>

View File

@ -477,8 +477,8 @@ namespace NavisworksTransport.PathPlanning
optimizedRoute.Points.Add(point);
}
// 重新计算路径长度
optimizedRoute.RecalculateLength();
// 重新计算路径数据并保存到数据库
optimizedRoute.RecalculateAndSaveRoute("路径优化");
return optimizedRoute;
}

View File

@ -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();