14 KiB
14 KiB
分层预览智能遍历需求分析
需求概述
新的分层处理逻辑需求
修改分层预览的业务逻辑,实现基于属性的智能停止遍历机制:
- 智能遍历逻辑:从一级节点开始,遍历每个节点查找指定的分层属性
- 分支停止机制:如果找到分层属性,记录下来作为一个分层,不再遍历其下级节点
- 深度递归控制:如果没找到,继续遍历其子节点,直到找到为止,遍历深度受到用户指定的遍历深度限制
- 智能检测特殊处理:使用一组候选的分层属性,对每个节点进行查找,按属性的评分(优先级)确定选择何种属性
- 自定义查找特殊处理:用指定的分层属性,在每个节点的"分层信息"属性类别中查找
现有架构分析
1. 当前遍历机制的局限性
现有实现方式:
// 当前的两阶段处理方式
var allItems = GetAllModelItems(config.MaxDepth); // 阶段1:收集所有指定深度内的节点
var groups = strategy.GroupItems(allItems, config); // 阶段2:对所有节点进行属性分析和分组
存在的问题:
- 采用固定深度遍历,无法实现智能停止
- 先收集所有节点,再统一分组,无法在遍历过程中动态决策
- 核心问题:无法实现"找到属性就停止该分支遍历"的逻辑
需要的新逻辑:
// 需要的边遍历边检查逻辑
foreach (一级节点) {
if (节点有指定分层属性) {
记录为分层,停止遍历该分支;
} else {
递归遍历子节点(深度限制);
}
}
2. 现有策略接口的不足
当前IGroupingStrategy接口:
public interface IGroupingStrategy
{
Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config);
}
接口局限性:
- 只能处理预收集的节点集合
- 无法在遍历过程中动态决策是否继续遍历
- 不支持单节点的属性检查和分支控制
3. 属性检查机制的缺陷
现有策略类的问题:
- 如
FloorAttributeStrategy仅检查特定的固定属性 - 没有通用的"分层信息"属性类别检查机制
- 不支持候选属性组和优先级评分
- 缺乏多属性竞争选择逻辑
架构改造方案
1. 核心遍历算法重设计
新的智能遍历算法:
public List<SplitPreviewResult> PreviewSplitWithSmartTraversal(
SplitConfiguration config, ISmartGroupingStrategy strategy)
{
var results = new List<SplitPreviewResult>();
// 从每个模型的一级节点开始遍历
foreach (Model model in document.Models)
{
foreach (ModelItem rootChild in model.RootItem.Children)
{
TraverseNodeWithAttributeCheck(rootChild, strategy, config, results, 1);
}
}
return results;
}
private void TraverseNodeWithAttributeCheck(ModelItem node,
ISmartGroupingStrategy strategy, SplitConfiguration config,
List<SplitPreviewResult> results, int currentDepth)
{
// 检查当前节点是否有分层属性
var layerInfo = strategy.ExtractLayerInfo(node);
if (layerInfo != null && layerInfo.IsValid)
{
// 找到分层属性,停止遍历该分支,添加到结果
var layerResult = CreateLayerResult(layerInfo, node);
results.Add(layerResult);
return; // 关键:停止该分支遍历
}
// 未找到属性且未达深度限制,继续遍历子节点
if (currentDepth < config.MaxDepth && node.Children != null)
{
foreach (ModelItem child in node.Children)
{
TraverseNodeWithAttributeCheck(child, strategy, config, results, currentDepth + 1);
}
}
}
2. 新策略接口设计
ISmartGroupingStrategy接口:
public interface ISmartGroupingStrategy
{
string GroupTypeName { get; }
/// <summary>
/// 核心方法:检查单个节点的分层信息
/// </summary>
LayerInfo ExtractLayerInfo(ModelItem node);
/// <summary>
/// 支持候选属性组的智能检测
/// </summary>
LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates);
}
支持数据结构:
public class LayerInfo
{
public bool IsValid { get; set; }
public string LayerName { get; set; }
public string AttributeName { get; set; }
public string AttributeValue { get; set; }
public int Priority { get; set; } // 用于智能检测的优先级
public string CategoryName { get; set; } // 属性类别
}
public class AttributeCandidate
{
public string AttributeName { get; set; }
public string CategoryName { get; set; } // 如"分层信息"
public int Priority { get; set; } // 优先级评分
public Func<string, string> ValueProcessor { get; set; } // 值处理函数
}
3. 智能检测策略实现
SmartLayerDetectionStrategy类:
public class SmartLayerDetectionStrategy : ISmartGroupingStrategy
{
private readonly List<AttributeCandidate> _candidates = new List<AttributeCandidate>
{
// 按优先级排序的候选属性
new AttributeCandidate { AttributeName = "楼层", CategoryName = "分层信息", Priority = 10 },
new AttributeCandidate { AttributeName = "Floor", CategoryName = "Identity Data", Priority = 9 },
new AttributeCandidate { AttributeName = "Level", CategoryName = "Constraints", Priority = 8 },
new AttributeCandidate { AttributeName = "分区", CategoryName = "分层信息", Priority = 7 },
new AttributeCandidate { AttributeName = "Zone", CategoryName = "Identity Data", Priority = 6 },
new AttributeCandidate { AttributeName = "子系统", CategoryName = "分层信息", Priority = 5 },
new AttributeCandidate { AttributeName = "System Type", CategoryName = "Mechanical", Priority = 4 },
// ... 更多候选属性
};
public LayerInfo ExtractLayerInfo(ModelItem node)
{
return ExtractBestLayerInfo(node, _candidates);
}
public LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates)
{
LayerInfo bestMatch = null;
int highestPriority = -1;
// 遍历所有候选属性,找到优先级最高的有效属性
foreach (var candidate in candidates)
{
var value = GetAttributeValue(node, candidate.CategoryName, candidate.AttributeName);
if (!string.IsNullOrEmpty(value) && candidate.Priority > highestPriority)
{
bestMatch = new LayerInfo
{
IsValid = true,
LayerName = candidate.ValueProcessor?.Invoke(value) ?? value,
AttributeName = candidate.AttributeName,
AttributeValue = value,
Priority = candidate.Priority,
CategoryName = candidate.CategoryName
};
highestPriority = candidate.Priority;
}
}
return bestMatch ?? new LayerInfo { IsValid = false };
}
private string GetAttributeValue(ModelItem node, string categoryName, string attributeName)
{
try
{
// 实现Navisworks属性检查逻辑
foreach (PropertyCategory category in node.PropertyCategories)
{
if (category.DisplayName == categoryName)
{
foreach (DataProperty property in category.Properties)
{
if (property.DisplayName == attributeName)
{
return property.Value.ToDisplayString();
}
}
}
}
}
catch (Exception ex)
{
LogManager.Warning($"获取属性值失败: {ex.Message}");
}
return null;
}
}
4. 自定义属性检查策略
CustomAttributeStrategy类:
public class CustomAttributeStrategy : ISmartGroupingStrategy
{
private readonly string _targetAttributeName;
private readonly string _targetCategoryName;
public string GroupTypeName => $"自定义属性({_targetAttributeName})";
public CustomAttributeStrategy(string attributeName, string categoryName = "分层信息")
{
_targetAttributeName = attributeName;
_targetCategoryName = categoryName;
}
public LayerInfo ExtractLayerInfo(ModelItem node)
{
var value = GetAttributeValue(node, _targetCategoryName, _targetAttributeName);
if (!string.IsNullOrEmpty(value))
{
return new LayerInfo
{
IsValid = true,
LayerName = value,
AttributeName = _targetAttributeName,
AttributeValue = value,
Priority = 1,
CategoryName = _targetCategoryName
};
}
return new LayerInfo { IsValid = false };
}
public LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates)
{
// 对于自定义策略,只检查指定的单个属性
return ExtractLayerInfo(node);
}
private string GetAttributeValue(ModelItem node, string categoryName, string attributeName)
{
// 与智能检测策略相同的实现
// ...
}
}
5. 遍历结果处理
CreateLayerResult方法设计:
private SplitPreviewResult CreateLayerResult(LayerInfo layerInfo, ModelItem rootNode)
{
// 收集该节点下的所有子项
var allChildItems = new ModelItemCollection();
CollectAllDescendants(rootNode, allChildItems);
return new SplitPreviewResult
{
LayerName = SanitizeLayerName(layerInfo.LayerName),
ItemCount = allChildItems.Count,
EstimatedFileSize = EstimateFileSize(allChildItems.Count),
Status = "就绪",
Items = allChildItems,
Metadata = new Dictionary<string, object>
{
["AttributeName"] = layerInfo.AttributeName,
["AttributeValue"] = layerInfo.AttributeValue,
["CategoryName"] = layerInfo.CategoryName,
["Priority"] = layerInfo.Priority,
["RootNodeName"] = rootNode.DisplayName
}
};
}
private void CollectAllDescendants(ModelItem rootNode, ModelItemCollection collection)
{
// 添加根节点本身
collection.Add(rootNode);
// 递归添加所有后代节点
if (rootNode.Children != null)
{
foreach (ModelItem child in rootNode.Children)
{
CollectAllDescendants(child, collection);
}
}
}
配置和UI适配
1. 分层策略配置
新的策略类型枚举:
public enum SmartSplitStrategy
{
SmartLayerDetection, // 智能检测
CustomFloorAttribute, // 自定义楼层属性
CustomZoneAttribute, // 自定义分区属性
CustomSystemAttribute, // 自定义系统属性
CustomAttribute // 完全自定义属性
}
2. UI配置选项
智能检测配置:
- 候选属性优先级设置
- 属性类别选择
- 值处理规则配置
自定义查找配置:
- 属性名称输入
- 属性类别选择(默认"分层信息")
- 值过滤规则
兼容性考虑
1. 向后兼容
保留现有接口:
- 现有的
IGroupingStrategy接口和实现类保持不变 - 在
SimplifiedModelSplitterManager中增加新的智能遍历方法 - UI层提供策略选择开关
渐进式迁移:
public List<SplitPreviewResult> PreviewSplit(SplitConfiguration config)
{
// 根据配置选择使用新的智能遍历还是传统方式
if (config.UseSmartTraversal)
{
return PreviewSplitWithSmartTraversal(config, CreateSmartStrategy(config));
}
else
{
// 保留原有的实现逻辑
return PreviewSplitTraditional(config);
}
}
2. 性能考虑
优化策略:
- 属性检查缓存机制
- 早期终止优化(找到高优先级属性立即停止)
- 内存管理优化(避免大量节点同时加载)
实施复杂度评估
高复杂度任务
- 核心遍历算法重写:需要完全重新设计遍历逻辑
- 属性检查机制实现:涉及Navisworks API的深度使用
- 测试验证:需要大量的模型测试和边界情况验证
中等复杂度任务
- 新策略接口和实现类:相对标准的面向对象设计
- UI适配:在现有界面基础上增加配置选项
低复杂度任务
- 配置管理:基于现有的配置系统扩展
- 日志和错误处理:基于现有的LogManager扩展
结论
现有架构评估:
- 不满足新需求:当前的"先收集后分组"模式无法实现智能停止遍历
- 需要重大改造:核心算法、策略接口、属性检查机制都需要重新设计
- 改造工作量大:预计需要重写30%以上的核心代码
建议实施策略:
- 并行开发:新旧算法并存,确保系统稳定性
- 分阶段验证:先实现基础功能,再逐步完善高级特性
- 充分测试:准备多种类型的测试模型,验证各种边界情况
- 性能监控:关注新算法的性能表现,必要时进行优化
预期收益:
- 更精确的分层:基于实际属性内容而非固定深度
- 更高的效率:避免不必要的深度遍历
- 更灵活的配置:支持多种属性检查策略
- 更好的用户体验:提供智能化的分层建议