增加数据库路径载入事件,避免事件职责混乱

This commit is contained in:
tian 2026-01-06 10:30:34 +08:00
parent 7fc62537d1
commit 2d2e60c58b
5 changed files with 134 additions and 34 deletions

View File

@ -44,6 +44,12 @@ namespace NavisworksTransport.Core
/// </summary>
event EventHandler<RouteGeneratedEventArgs> RouteGenerated;
/// <summary>
/// 路径加载完成事件
/// 当从数据库加载路径完成时触发
/// </summary>
event EventHandler<RoutesLoadedEventArgs> RoutesLoaded;
/// <summary>
/// 当前路径变更事件
/// 当当前活动路径发生变化时触发

View File

@ -60,7 +60,7 @@ namespace NavisworksTransport
double clampedCosAlpha = Math.Max(-1.0, Math.Min(1.0, cosAlpha));
double angleRad = Math.Acos(clampedCosAlpha);
LogManager.Info($"[CalculateFillet] 角度计算: cosAlpha={cosAlpha:F4}, clampedCosAlpha={clampedCosAlpha:F4}, angleRad={angleRad:F4}rad ({angleRad * 180.0 / Math.PI:F2}度)");
LogManager.Debug($"[CalculateFillet] 角度计算: cosAlpha={cosAlpha:F4}, clampedCosAlpha={clampedCosAlpha:F4}, angleRad={angleRad:F4}rad ({angleRad * 180.0 / Math.PI:F2}度)");
// 如果几乎共线,返回无效轨迹
if (angleRad < 0.01 || angleRad > Math.PI - 0.01)
@ -127,14 +127,14 @@ namespace NavisworksTransport
dotTsTe = Math.Max(-1.0, Math.Min(1.0, dotTsTe));
double actualDeflectionAngle = Math.Acos(dotTsTe);
LogManager.Info($"[CalculateFillet] 计算实际偏转角度:");
LogManager.Info($" Ts=({ts.X:F3},{ts.Y:F3},{ts.Z:F3}), Te=({te.X:F3},{te.Y:F3},{te.Z:F3})");
LogManager.Info($" ArcCenter=({arcCenter.X:F3},{arcCenter.Y:F3},{arcCenter.Z:F3})");
LogManager.Info($" Ts到圆心向量: ({tsToCenter.X:F3},{tsToCenter.Y:F3},{tsToCenter.Z:F3})");
LogManager.Info($" Te到圆心向量: ({teToCenter.X:F3},{teToCenter.Y:F3},{teToCenter.Z:F3})");
LogManager.Info($" 点积: {dotTsTe:F4}");
LogManager.Info($" 实际偏转角度: {actualDeflectionAngle * 180.0 / Math.PI:F2}度");
LogManager.Info($" 半径截断: {radiusTruncated}, 请求半径: {turnRadius:F2}米, 实际半径: {actualRadius:F2}米");
LogManager.Debug($"[CalculateFillet] 计算实际偏转角度:");
LogManager.Debug($" Ts=({ts.X:F3},{ts.Y:F3},{ts.Z:F3}), Te=({te.X:F3},{te.Y:F3},{te.Z:F3})");
LogManager.Debug($" ArcCenter=({arcCenter.X:F3},{arcCenter.Y:F3},{arcCenter.Z:F3})");
LogManager.Debug($" Ts到圆心向量: ({tsToCenter.X:F3},{tsToCenter.Y:F3},{tsToCenter.Z:F3})");
LogManager.Debug($" Te到圆心向量: ({teToCenter.X:F3},{teToCenter.Y:F3},{teToCenter.Z:F3})");
LogManager.Debug($" 点积: {dotTsTe:F4}");
LogManager.Debug($" 实际偏转角度: {actualDeflectionAngle * 180.0 / Math.PI:F2}度");
LogManager.Debug($" 半径截断: {radiusTruncated}, 请求半径: {turnRadius:F2}米, 实际半径: {actualRadius:F2}米");
double arcLength = actualRadius * actualDeflectionAngle;
@ -182,8 +182,8 @@ namespace NavisworksTransport
// 打印角度信息
double angleDegrees = trajectory.DeflectionAngle * 180.0 / Math.PI;
LogManager.Info($"圆弧采样: 角度={angleDegrees:F2}度, 弧度={trajectory.DeflectionAngle:F4}, 半径={trajectory.ActualRadius:F2}m, 长度={trajectory.ArcLength:F2}m");
LogManager.Info($" Ts=({trajectory.Ts.X:F3},{trajectory.Ts.Y:F3},{trajectory.Ts.Z:F3}), Te=({trajectory.Te.X:F3},{trajectory.Te.Y:F3},{trajectory.Te.Z:F3})");
LogManager.Debug($"圆弧采样: 角度={angleDegrees:F2}度, 弧度={trajectory.DeflectionAngle:F4}, 半径={trajectory.ActualRadius:F2}m, 长度={trajectory.ArcLength:F2}m");
LogManager.Debug($" Ts=({trajectory.Ts.X:F3},{trajectory.Ts.Y:F3},{trajectory.Ts.Z:F3}), Te=({trajectory.Te.X:F3},{trajectory.Te.Y:F3},{trajectory.Te.Z:F3})");
// 根据采样步长计算采样点数量
int sampleCount = Math.Max(2, (int)Math.Ceiling(trajectory.ArcLength / samplingStep));
@ -198,7 +198,7 @@ namespace NavisworksTransport
new Point3D(endVec.X, endVec.Y, endVec.Z));
Vector3D rotationAxis = new Vector3D(cross.X, cross.Y, cross.Z).Normalize();
LogManager.Info($" 旋转轴=({rotationAxis.X:F6},{rotationAxis.Y:F6},{rotationAxis.Z:F6})");
LogManager.Debug($" 旋转轴=({rotationAxis.X:F6},{rotationAxis.Y:F6},{rotationAxis.Z:F6})");
// 计算有向旋转角度(使用 Atan2 而不是 Acos以保留方向信息
double dot = GeometryHelper.DotProduct(
@ -208,8 +208,8 @@ namespace NavisworksTransport
// 使用 Atan2 计算有向角度,确保旋转方向正确
double signedAngle = Math.Atan2(crossMag, dot);
LogManager.Info($" 重新计算的有向角度: {signedAngle:F4}rad ({signedAngle * 180.0 / Math.PI:F2}度)");
LogManager.Info($" 使用DeflectionAngle: {trajectory.DeflectionAngle:F4}rad ({trajectory.DeflectionAngle * 180.0 / Math.PI:F2}度)");
LogManager.Debug($" 重新计算的有向角度: {signedAngle:F4}rad ({signedAngle * 180.0 / Math.PI:F2}度)");
LogManager.Debug($" 使用DeflectionAngle: {trajectory.DeflectionAngle:F4}rad ({trajectory.DeflectionAngle * 180.0 / Math.PI:F2}度)");
// 使用trajectory.DeflectionAngle而不是重新计算的角度
signedAngle = trajectory.DeflectionAngle;
@ -230,7 +230,7 @@ namespace NavisworksTransport
if (i == 0 || i == sampleCount)
{
LogManager.Info($" 采样点[{i}/{sampleCount}]: t={t:F4}, theta={theta:F4}rad, 坐标=({sampledPoint.X:F3},{sampledPoint.Y:F3},{sampledPoint.Z:F3})");
LogManager.Debug($" 采样点[{i}/{sampleCount}]: t={t:F4}, theta={theta:F4}rad, 坐标=({sampledPoint.X:F3},{sampledPoint.Y:F3},{sampledPoint.Z:F3})");
}
points.Add(sampledPoint);
@ -241,7 +241,7 @@ namespace NavisworksTransport
{
var lastPoint = points.Last();
double distanceToTe = (lastPoint - trajectory.Te).Length;
LogManager.Info($" 终点验证: 目标Te=({trajectory.Te.X:F3},{trajectory.Te.Y:F3},{trajectory.Te.Z:F3}), 实际终点=({lastPoint.X:F3},{lastPoint.Y:F3},{lastPoint.Z:F3}), 误差={distanceToTe:F6}m");
LogManager.Debug($" 终点验证: 目标Te=({trajectory.Te.X:F3},{trajectory.Te.Y:F3},{trajectory.Te.Z:F3}), 实际终点=({lastPoint.X:F3},{lastPoint.Y:F3},{lastPoint.Z:F3}), 误差={distanceToTe:F6}m");
if (distanceToTe > 0.001)
{
LogManager.Warning($" 圆弧采样终点误差: {distanceToTe:F6}m");

View File

@ -306,6 +306,7 @@ namespace NavisworksTransport
public event EventHandler<RouteGeneratedEventArgs> RouteGenerated;
public event EventHandler<CurrentRouteChangedEventArgs> CurrentRouteChanged;
public event EventHandler<PathPointsListUpdatedEventArgs> PathPointsListUpdated;
public event EventHandler<RoutesLoadedEventArgs> RoutesLoaded;
// 保留原有事件以保持向后兼容
[Obsolete("请使用新的强类型事件接口")]
@ -657,6 +658,32 @@ namespace NavisworksTransport
}
}
private void RaiseRoutesLoaded(IReadOnlyList<PathRoute> routes, string loadSource = "Database")
{
try
{
var eventArgs = new RoutesLoadedEventArgs(routes, loadSource, _managerId);
if (_uiStateManager != null)
{
_uiStateManager.QueueUIUpdate(() =>
{
RoutesLoaded?.Invoke(this, eventArgs);
});
}
else
{
RoutesLoaded?.Invoke(this, eventArgs);
}
LogManager.Info($"[路径加载完成] 从{loadSource}加载了 {routes.Count} 条路径");
}
catch (Exception ex)
{
LogManager.Error($"[路径加载完成] 事件触发失败: {ex.Message}");
}
}
#endregion
#region
@ -3810,13 +3837,9 @@ namespace NavisworksTransport
LogManager.Info($"设置当前路径为: {_currentRoute.Name}");
}
// 历史路径加载完成后触发RouteGenerated事件通知UI刷新
// 使用特殊的生成方法标记这是数据库加载
foreach (var route in _routes)
{
RaiseRouteGenerated(route, RouteGenerationMethod.DatabaseLoad);
}
LogManager.Info($"已触发{_routes.Count}个RouteGenerated事件通知UI刷新历史路径");
// 历史路径加载完成后触发RoutesLoaded事件通知UI刷新
RaiseRoutesLoaded(_routes.AsReadOnly(), "Database");
LogManager.Info($"已触发RoutesLoaded事件通知UI刷新历史路径列表");
}
else
{

View File

@ -247,6 +247,36 @@ namespace NavisworksTransport.Core
}
}
/// <summary>
/// 路径加载完成事件参数
/// 当从数据库加载路径完成时触发
/// </summary>
public class RoutesLoadedEventArgs : PathPlanningEventArgsBase
{
/// <summary>
/// 加载的路径列表
/// </summary>
public IReadOnlyList<PathRoute> Routes { get; }
/// <summary>
/// 加载的路径数量
/// </summary>
public int RouteCount { get; }
/// <summary>
/// 加载来源
/// </summary>
public string LoadSource { get; }
public RoutesLoadedEventArgs(IReadOnlyList<PathRoute> routes, string loadSource = "Database", string managerId = null)
: base(managerId)
{
Routes = routes ?? new List<PathRoute>();
RouteCount = Routes.Count;
LoadSource = loadSource;
}
}
#region
/// <summary>

View File

@ -2578,6 +2578,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 订阅路径生成事件(用于处理自动路径)
_pathPlanningManager.RouteGenerated += OnRouteGenerated;
// 订阅路径加载完成事件(用于处理数据库加载的路径)
_pathPlanningManager.RoutesLoaded += OnRoutesLoaded;
// 添加错误事件订阅 - 用于处理自动路径规划失败等错误
_pathPlanningManager.ErrorOccurred += OnPathPlanningError;
@ -2603,6 +2606,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
_pathPlanningManager.CurrentRouteChanged -= OnCurrentRouteChanged;
_pathPlanningManager.EditStateChanged -= OnEditStateChanged;
_pathPlanningManager.RouteGenerated -= OnRouteGenerated;
_pathPlanningManager.RoutesLoaded -= OnRoutesLoaded;
_pathPlanningManager.ErrorOccurred -= OnPathPlanningError;
LogManager.Info("PathEditingViewModel已取消订阅PathPlanningManager事件包括ErrorOccurred");
@ -2972,20 +2976,52 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
else if (e.GenerationMethod == RouteGenerationMethod.DatabaseLoad)
{
// 从数据库加载的历史路径
LogManager.Info($"*** 开始处理数据库加载路径: {e.Route.Name} ***");
// 注意DatabaseLoad现在由OnRoutesLoaded事件处理这里不再处理
LogManager.Warning($"*** OnRouteGenerated收到DatabaseLoad方法这不应该发生应该由OnRoutesLoaded处理 ***");
}
}, "处理路径生成事件");
}
catch (Exception ex)
{
LogManager.Error($"*** OnRouteGenerated异常: {ex.Message} ***", ex);
}
}
/// <summary>
/// 处理路径加载完成事件(用于数据库加载)
/// </summary>
private async void OnRoutesLoaded(object sender, RoutesLoadedEventArgs e)
{
LogManager.Info($"*** OnRoutesLoaded被调用Sender: {sender?.GetType().Name}, RouteCount: {e?.RouteCount}, LoadSource: {e?.LoadSource} ***");
if (e?.Routes == null)
{
LogManager.Warning("*** OnRoutesLoaded: RoutesLoadedEventArgs或Routes为null退出处理 ***");
return;
}
try
{
await SafeExecuteAsync(() =>
{
LogManager.Info($"PathEditingViewModel收到路径加载完成事件: 加载了 {e.RouteCount} 条路径,来源: {e.LoadSource}");
// 处理从数据库加载的历史路径
foreach (var coreRoute in e.Routes)
{
LogManager.Info($"*** 开始处理数据库加载路径: {coreRoute.Name} ***");
// 创建对应的 WPF ViewModel
var dbPathViewModel = new PathRouteViewModel
{
Id = e.Route.Id,
Name = e.Route.Name,
Description = e.Route.Description,
Id = coreRoute.Id,
Name = coreRoute.Name,
Description = coreRoute.Description,
IsActive = false // 历史路径默认不激活
};
// 转换路径点
foreach (var corePoint in e.Route.Points)
foreach (var corePoint in coreRoute.Points)
{
var wpfPoint = new PathPointViewModel
{
@ -3002,23 +3038,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Info($"*** 已创建PathRouteViewModel数据库路径包含 {dbPathViewModel.Points.Count} 个点 ***");
// 检查是否已存在同名路径,避免重复添加
var existingPath = PathRoutes.FirstOrDefault(p => p.Name == e.Route.Name);
var existingPath = PathRoutes.FirstOrDefault(p => p.Name == coreRoute.Name);
if (existingPath == null)
{
// 添加到 UI 列表
PathRoutes.Add(dbPathViewModel);
LogManager.Info($"*** 数据库路径已添加到UI列表: {e.Route.Name}当前PathRoutes.Count = {PathRoutes.Count} ***");
LogManager.Info($"*** 数据库路径已添加到UI列表: {coreRoute.Name}当前PathRoutes.Count = {PathRoutes.Count} ***");
}
else
{
LogManager.Info($"*** 数据库路径已存在,跳过: {e.Route.Name} ***");
LogManager.Info($"*** 数据库路径已存在,跳过: {coreRoute.Name} ***");
}
}
}, "处理路径生成事件");
// 更新状态消息
string statusMessage = $"✅ 已从{e.LoadSource}加载 {e.RouteCount} 条历史路径";
UpdateMainStatus(statusMessage);
LogManager.Info($"*** 状态已更新: {statusMessage} ***");
}, "处理路径加载完成事件");
}
catch (Exception ex)
{
LogManager.Error($"*** OnRouteGenerated异常: {ex.Message} ***", ex);
LogManager.Error($"*** OnRoutesLoaded异常: {ex.Message} ***", ex);
}
}