修复分层预览功能中深度遍历逻辑不统一的问题

## 主要修复内容:

### 1. 创建统一的深度遍历核心函数
- 新增 GetItemsByDepthUnified() 方法实现精确的深度控制
- 确保所有策略使用相同的深度遍历逻辑
- 消除不同策略间深度处理的差异

### 2. 重构分层策略架构
- 引入 IGroupingStrategy 接口统一所有分层策略
- 创建 FloorDetectionStrategy、FloorAttributeStrategy、ZoneAttributeStrategy、SubSystemAttributeStrategy
- 所有策略现在接收完全相同的模型项集合

### 3. 修复智能楼层检测策略
- 新增 FloorDetector.DetectFloorsFromGivenItems() 方法
- FloorDetectionStrategy 不再依赖 FloorDetector 内部的深度逻辑
- 确保智能楼层检测使用与属性策略相同的模型项集合

### 4. 统一缓存和进度处理
- 更新缓存键生成使用统一的深度遍历函数
- 为所有策略添加详细的调试日志
- 标记所有分组项使用了统一深度遍历

## 解决的问题:
- 深度1级:现在所有策略基于相同的第一级节点集合
- 深度2级:现在所有策略基于相同的第一+二级节点集合
- 深度3级:现在所有策略基于相同的第一+二+三级节点集合
- 全部深度:现在所有策略基于相同的完整节点集合

## 预期结果:
当用户在二级节点设置3个不同属性值时,所有深度设置下的分层结果将完全一致。

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tian 2025-08-27 13:28:43 +08:00
parent 0de9de617f
commit ad86c2ab76
3 changed files with 422 additions and 134 deletions

View File

@ -24,8 +24,231 @@ namespace NavisworksTransport
/// </summary>
public enum SplitStrategy
{
ByFloor, // 智能检测楼层
ByCustomFloor // 按自定义分层
BySmartFloorDetection, // 智能检测楼层原ByFloor
ByFloorAttribute, // 按楼层属性原ByCustomFloor
ByZoneAttribute, // 按区域属性
BySubSystemAttribute // 按子系统属性
}
/// <summary>
/// 分层分组策略接口
/// </summary>
private interface IGroupingStrategy
{
string GroupTypeName { get; }
string UnclassifiedLabel { get; }
Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config);
}
/// <summary>
/// 分组项信息
/// </summary>
private class GroupItem
{
public string GroupName { get; set; }
public string OriginalName { get; set; }
public List<ModelItem> Items { get; set; } = new List<ModelItem>();
public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
}
/// <summary>
/// 楼层检测分组策略 - 使用统一的深度遍历结果
/// </summary>
private class FloorDetectionStrategy : IGroupingStrategy
{
private readonly FloorDetector _floorDetector;
public string GroupTypeName => "楼层";
public string UnclassifiedLabel => "未检测到楼层";
public FloorDetectionStrategy(FloorDetector floorDetector)
{
_floorDetector = floorDetector;
}
public Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config)
{
var result = new Dictionary<string, GroupItem>();
try
{
LogManager.Info($"[FloorDetectionStrategy] 开始智能楼层检测,输入模型项数={items?.Count ?? 0}");
if (items == null || items.Count == 0)
{
LogManager.Warning("[FloorDetectionStrategy] 输入模型项集合为空");
return result;
}
// 关键修复直接使用传入的items不再让FloorDetector重新获取深度项
// 调用 FloorDetector但传入 maxDepth = 0 来强制使用传入的items
var floors = _floorDetector.DetectFloorsFromGivenItems(items, null);
LogManager.Info($"[FloorDetectionStrategy] FloorDetector检测完成发现 {floors?.Count ?? 0} 个楼层");
if (floors != null && floors.Count > 0)
{
foreach (var floor in floors)
{
result[floor.FloorName] = new GroupItem
{
GroupName = floor.FloorName,
OriginalName = floor.FloorName,
Items = floor.Items?.ToList() ?? new List<ModelItem>(),
Metadata = new Dictionary<string, object>
{
["OriginalFloorName"] = floor.FloorName,
["FloorName"] = floor.FloorName,
["Elevation"] = floor.Elevation,
["DetectionMethod"] = "Floor",
["ItemsFromUnifiedDepth"] = true // 标记使用了统一深度遍历
}
};
LogManager.Info($"[FloorDetectionStrategy] 楼层 '{floor.FloorName}' 包含 {floor.Items?.Count ?? 0} 个模型项");
}
}
else
{
LogManager.Warning("[FloorDetectionStrategy] 未检测到任何楼层信息");
}
}
catch (Exception ex)
{
LogManager.Error($"[FloorDetectionStrategy] 楼层检测异常: {ex.Message}");
}
LogManager.Info($"[FloorDetectionStrategy] 楼层检测完成,返回 {result.Count} 个楼层分组");
return result;
}
}
/// <summary>
/// 属性分组策略基类
/// </summary>
private abstract class AttributeGroupingStrategy : IGroupingStrategy
{
protected readonly FloorAttributeManager _floorManager;
public abstract string GroupTypeName { get; }
public abstract string UnclassifiedLabel { get; }
protected AttributeGroupingStrategy()
{
_floorManager = new FloorAttributeManager();
}
protected abstract string GetAttributeValue(ModelItem item);
public Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config)
{
var result = new Dictionary<string, GroupItem>();
try
{
LogManager.Info($"[{GroupTypeName}AttributeStrategy] 开始属性分组,输入模型项数={items?.Count ?? 0},深度={config?.MaxDepth ?? -1}");
if (items == null || items.Count == 0)
{
LogManager.Warning($"[{GroupTypeName}AttributeStrategy] 输入模型项集合为空");
return result;
}
int processedCount = 0;
var attributeValueCounts = new Dictionary<string, int>();
foreach (var item in items)
{
try
{
processedCount++;
string attributeValue = GetAttributeValue(item);
string groupKey = string.IsNullOrEmpty(attributeValue) ? UnclassifiedLabel : attributeValue;
// 统计属性值分布
if (!attributeValueCounts.ContainsKey(groupKey))
attributeValueCounts[groupKey] = 0;
attributeValueCounts[groupKey]++;
if (!result.ContainsKey(groupKey))
{
result[groupKey] = new GroupItem
{
GroupName = groupKey,
OriginalName = attributeValue ?? UnclassifiedLabel,
Metadata = new Dictionary<string, object>
{
["DetectionMethod"] = GroupTypeName + "Attribute",
["ItemsFromUnifiedDepth"] = true, // 标记使用了统一深度遍历
["MaxDepth"] = config?.MaxDepth ?? -1
}
};
}
result[groupKey].Items.Add(item);
}
catch (Exception ex)
{
LogManager.Error($"[{GroupTypeName}AttributeStrategy] 处理单个模型项时出错: {ex.Message}");
}
}
// 记录属性值分布
LogManager.Info($"[{GroupTypeName}AttributeStrategy] 处理完成,共处理{processedCount}个模型项,发现{result.Count}个{GroupTypeName}分组");
foreach (var kvp in attributeValueCounts.OrderByDescending(x => x.Value))
{
LogManager.Info($"[{GroupTypeName}AttributeStrategy] {GroupTypeName}分组 '{kvp.Key}': {kvp.Value} 个模型项");
}
}
catch (Exception ex)
{
LogManager.Error($"[{GroupTypeName}AttributeStrategy] 属性分组异常: {ex.Message}");
}
return result;
}
}
/// <summary>
/// 楼层属性分组策略
/// </summary>
private class FloorAttributeStrategy : AttributeGroupingStrategy
{
public override string GroupTypeName => "楼层";
public override string UnclassifiedLabel => "未设置楼层";
protected override string GetAttributeValue(ModelItem item)
{
return _floorManager.GetFloorLevel(item, true);
}
}
/// <summary>
/// 区域属性分组策略
/// </summary>
private class ZoneAttributeStrategy : AttributeGroupingStrategy
{
public override string GroupTypeName => "区域";
public override string UnclassifiedLabel => "未设置区域";
protected override string GetAttributeValue(ModelItem item)
{
return _floorManager.GetZoneAttribute(item, true); // 启用继承查询
}
}
/// <summary>
/// 子系统属性分组策略
/// </summary>
private class SubSystemAttributeStrategy : AttributeGroupingStrategy
{
public override string GroupTypeName => "子系统";
public override string UnclassifiedLabel => "未设置子系统";
protected override string GetAttributeValue(ModelItem item)
{
return _floorManager.GetSubSystemAttribute(item, true); // 启用继承查询
}
}
/// <summary>
@ -36,7 +259,7 @@ namespace NavisworksTransport
/// <summary>
/// 分层策略
/// </summary>
public SplitStrategy Strategy { get; set; } = SplitStrategy.ByFloor;
public SplitStrategy Strategy { get; set; } = SplitStrategy.BySmartFloorDetection;
/// <summary>
/// 属性名称(用于自定义分层时使用)
@ -261,11 +484,17 @@ namespace NavisworksTransport
switch (config.Strategy)
{
case SplitStrategy.ByFloor:
previewResults = PreviewSplitByFloor(allItems, config);
case SplitStrategy.BySmartFloorDetection:
previewResults = PreviewSplitByAttribute(allItems, config, new FloorDetectionStrategy(_floorDetector));
break;
case SplitStrategy.ByCustomFloor:
previewResults = PreviewSplitByCustomFloor(allItems, config);
case SplitStrategy.ByFloorAttribute:
previewResults = PreviewSplitByAttribute(allItems, config, new FloorAttributeStrategy());
break;
case SplitStrategy.ByZoneAttribute:
previewResults = PreviewSplitByAttribute(allItems, config, new ZoneAttributeStrategy());
break;
case SplitStrategy.BySubSystemAttribute:
previewResults = PreviewSplitByAttribute(allItems, config, new SubSystemAttributeStrategy());
break;
default:
throw new NotSupportedException($"不支持的分层策略: {config.Strategy}");
@ -298,12 +527,12 @@ namespace NavisworksTransport
}
/// <summary>
/// 生成缓存键
/// 生成缓存键 - 使用统一的深度遍历
/// </summary>
private string GenerateCacheKey(SplitConfiguration config)
{
return $"{config.Strategy}_{config.MaxDepth}_{config.AttributeName ?? "Floor"}_" +
$"{GetAllModelItems(config.MaxDepth).Count}";
$"{GetItemsByDepthUnified(config.MaxDepth).Count}";
}
/// <summary>
@ -526,189 +755,172 @@ namespace NavisworksTransport
#region
/// <summary>
/// 获取所有模型元素(支持深度限制)
/// 统一的深度遍历核心函数 - 精确控制深度逻辑
/// </summary>
private ModelItemCollection GetAllModelItems(int maxDepth = 1)
/// <param name="maxDepth">最大深度1=仅第一级2=到第二级3=到第三级0=所有级别</param>
/// <returns>按深度筛选的模型项集合</returns>
private ModelItemCollection GetItemsByDepthUnified(int maxDepth)
{
var document = NavisApplication.ActiveDocument;
if (document?.Models?.Count == 0)
{
return new ModelItemCollection();
}
ModelItemCollection allItems;
if (maxDepth <= 0)
{
// 如果maxDepth为0或负数获取所有项
allItems = new ModelItemCollection();
allItems.AddRange(document.Models.RootItemDescendantsAndSelf);
LogManager.Info($"[SimplifiedModelSplitter] 获取到 {allItems.Count} 个模型元素(所有级别)");
}
else
{
// 直接使用FloorDetector的高效深度遍历不需要先获取所有元素
var floorDetector = new FloorDetector();
allItems = floorDetector.GetItemsByDepth(null, maxDepth); // 传null方法内部会直接从document获取
LogManager.Info($"[SimplifiedModelSplitter] 获取到 {allItems.Count} 个模型元素(深度限制:{maxDepth}级)");
}
return allItems;
}
/// <summary>
/// 按楼层预览分层(带进度报告)
/// </summary>
private List<SplitPreviewResult> PreviewSplitByFloor(ModelItemCollection items, SplitConfiguration config)
{
var results = new List<SplitPreviewResult>();
try
{
// 楼层检测阶段 (35-70%)
OnProgressChanged(new ProgressChangedEventArgs(40, $"正在检测 {items.Count} 个模型元素的楼层信息"));
LogManager.Info($"[SimplifiedModelSplitter] ===== GetItemsByDepthUnified开始 ===== maxDepth={maxDepth}");
var floors = _floorDetector.DetectFloors(items, null, config.MaxDepth);
LogManager.Info($"[SimplifiedModelSplitter] 按楼层检测完成,使用深度: {config.MaxDepth},发现 {floors?.Count ?? 0} 个楼层");
OnProgressChanged(new ProgressChangedEventArgs(70, $"楼层检测完成,发现 {floors?.Count ?? 0} 个楼层"));
if (floors != null && floors.Count > 0)
var document = NavisApplication.ActiveDocument;
if (document?.Models?.Count == 0)
{
// 生成预览结果阶段 (70-85%)
OnProgressChanged(new ProgressChangedEventArgs(75, "正在生成楼层预览结果"));
int processedFloors = 0;
foreach (var floor in floors)
LogManager.Warning("[SimplifiedModelSplitter] 当前文档没有模型");
return new ModelItemCollection();
}
var result = new ModelItemCollection();
if (maxDepth <= 0)
{
// 深度为0表示包含所有级别
result.AddRange(document.Models.RootItemDescendantsAndSelf);
LogManager.Info($"[SimplifiedModelSplitter] maxDepth=0返回所有级别的项共{result.Count}个");
return result;
}
// 从文档的根模型开始精确的深度遍历
foreach (Model model in document.Models)
{
if (model.RootItem != null)
{
var previewResult = new SplitPreviewResult
// 添加第一级节点(模型根的直接子节点)
if (maxDepth >= 1)
{
LayerName = SanitizeLayerName(floor.FloorName),
ItemCount = floor.ItemCount,
EstimatedFileSize = EstimateFileSize(floor.ItemCount),
Status = "就绪",
Items = new ModelItemCollection()
};
// 复制ModelItem集合
if (floor.Items != null && floor.Items.Count > 0)
{
previewResult.Items.AddRange(floor.Items);
LogManager.Info($"[SimplifiedModelSplitter] 楼层预览结果已缓存模型项: 楼层='{previewResult.LayerName}', 原始名称='{floor.FloorName}', 模型项数量={previewResult.Items.Count}");
foreach (ModelItem firstLevelItem in model.RootItem.Children)
{
result.Add(firstLevelItem);
// 递归添加更深层次的节点
AddChildrenToDepth(firstLevelItem, result, 2, maxDepth);
}
}
else
{
LogManager.Warning($"[SimplifiedModelSplitter] 楼层预览结果没有模型项: 楼层='{previewResult.LayerName}', 原始名称='{floor.FloorName}'");
}
// 添加元数据 - 保存原始名称用于后续匹配
previewResult.Metadata["OriginalFloorName"] = floor.FloorName; // 保存原始楼层名称
previewResult.Metadata["FloorName"] = floor.FloorName;
previewResult.Metadata["Elevation"] = floor.Elevation;
previewResult.Metadata["DetectionMethod"] = "Floor";
previewResult.Metadata["MaxDepth"] = config.MaxDepth;
results.Add(previewResult);
// 更新进度
processedFloors++;
int progressPercent = 75 + (processedFloors * 10 / floors.Count);
OnProgressChanged(new ProgressChangedEventArgs(progressPercent,
$"已处理 {processedFloors}/{floors.Count} 个楼层"));
}
OnProgressChanged(new ProgressChangedEventArgs(85, $"楼层预览结果生成完成,共 {results.Count} 个分层"));
}
else
{
OnProgressChanged(new ProgressChangedEventArgs(85, "未检测到楼层信息"));
LogManager.Warning("[SimplifiedModelSplitter] 未检测到任何楼层信息");
}
LogManager.Info($"[SimplifiedModelSplitter] ===== GetItemsByDepthUnified完成 ===== 返回{result.Count}个模型项(深度:{maxDepth}级)");
return result;
}
catch (Exception ex)
{
LogManager.Error($"[SimplifiedModelSplitter] 按楼层预览失败: {ex.Message}");
OnProgressChanged(new ProgressChangedEventArgs(35, $"楼层分析失败: {ex.Message}"));
throw;
LogManager.Error($"[SimplifiedModelSplitter] GetItemsByDepthUnified异常: {ex.Message}");
return new ModelItemCollection();
}
return results;
}
/// <summary>
/// 按自定义楼层预览分层基于FloorAttributeManager
/// 递归添加子节点到指定深度
/// </summary>
private List<SplitPreviewResult> PreviewSplitByCustomFloor(ModelItemCollection items, SplitConfiguration config)
/// <param name="parentItem">父节点</param>
/// <param name="result">结果集合</param>
/// <param name="currentDepth">当前深度</param>
/// <param name="maxDepth">最大深度</param>
private void AddChildrenToDepth(ModelItem parentItem, ModelItemCollection result, int currentDepth, int maxDepth)
{
if (currentDepth > maxDepth || parentItem?.Children == null)
return;
foreach (ModelItem child in parentItem.Children)
{
result.Add(child);
// 如果还没有达到最大深度,继续遍历子项
if (currentDepth < maxDepth)
{
AddChildrenToDepth(child, result, currentDepth + 1, maxDepth);
}
}
}
/// <summary>
/// 获取所有模型元素(支持深度限制)- 使用统一的深度遍历函数
/// </summary>
private ModelItemCollection GetAllModelItems(int maxDepth = 1)
{
return GetItemsByDepthUnified(maxDepth);
}
/// <summary>
/// 通用属性预览分层方法(基于分组策略模式)
/// </summary>
private List<SplitPreviewResult> PreviewSplitByAttribute(ModelItemCollection items, SplitConfiguration config, IGroupingStrategy strategy)
{
var results = new List<SplitPreviewResult>();
try
{
// 初始化FloorAttributeManager
OnProgressChanged(new ProgressChangedEventArgs(40, $"正在分析 {items.Count} 个模型元素的自定义楼层信息"));
// 属性分组阶段 (35-70%)
OnProgressChanged(new ProgressChangedEventArgs(40, $"正在分析 {items.Count} 个模型元素的{strategy.GroupTypeName}信息"));
var floorManager = new FloorAttributeManager();
var floorGroups = floorManager.GetFloorGroups();
var groups = strategy.GroupItems(items, config);
LogManager.Info($"[SimplifiedModelSplitter] {strategy.GroupTypeName}属性检测完成,发现 {groups?.Count ?? 0} 个{strategy.GroupTypeName}分组");
LogManager.Info($"[SimplifiedModelSplitter] 自定义楼层检测完成,发现 {floorGroups?.Count ?? 0} 个楼层分组");
OnProgressChanged(new ProgressChangedEventArgs(70, $"{strategy.GroupTypeName}分组完成,发现 {groups?.Count ?? 0} 个{strategy.GroupTypeName}"));
OnProgressChanged(new ProgressChangedEventArgs(70, $"楼层分组完成,发现 {floorGroups?.Count ?? 0} 个楼层"));
if (floorGroups != null && floorGroups.Count > 0)
if (groups != null && groups.Count > 0)
{
// 生成预览结果阶段 (70-85%)
OnProgressChanged(new ProgressChangedEventArgs(75, "正在生成自定义楼层预览结果"));
OnProgressChanged(new ProgressChangedEventArgs(75, $"正在生成{strategy.GroupTypeName}预览结果"));
int processedGroups = 0;
foreach (var floorGroup in floorGroups)
foreach (var group in groups.Values)
{
var previewResult = new SplitPreviewResult
{
LayerName = SanitizeLayerName(floorGroup.Key),
ItemCount = floorGroup.Value.Count,
EstimatedFileSize = EstimateFileSize(floorGroup.Value.Count),
LayerName = SanitizeLayerName(group.GroupName),
ItemCount = group.Items.Count,
EstimatedFileSize = EstimateFileSize(group.Items.Count),
Status = "就绪",
Items = new ModelItemCollection()
};
// 添加模型项到集合中
if (floorGroup.Value != null && floorGroup.Value.Count > 0)
if (group.Items != null && group.Items.Count > 0)
{
previewResult.Items.AddRange(floorGroup.Value);
LogManager.Info($"[SimplifiedModelSplitter] 自定义楼层预览结果已缓存模型项: 楼层='{previewResult.LayerName}', 模型项数量={previewResult.Items.Count}");
previewResult.Items.AddRange(group.Items);
LogManager.Info($"[SimplifiedModelSplitter] {strategy.GroupTypeName}预览结果已缓存模型项: {strategy.GroupTypeName}='{previewResult.LayerName}', 模型项数量={previewResult.Items.Count}");
}
else
{
LogManager.Warning($"[SimplifiedModelSplitter] 自定义楼层预览结果没有模型项: 楼层='{previewResult.LayerName}'");
LogManager.Warning($"[SimplifiedModelSplitter] {strategy.GroupTypeName}预览结果没有模型项: {strategy.GroupTypeName}='{previewResult.LayerName}'");
}
// 添加元数据
previewResult.Metadata["OriginalFloorName"] = floorGroup.Key;
previewResult.Metadata["FloorName"] = floorGroup.Key;
previewResult.Metadata["DetectionMethod"] = "CustomFloor";
previewResult.Metadata["Original" + strategy.GroupTypeName + "Name"] = group.OriginalName;
previewResult.Metadata[strategy.GroupTypeName + "Name"] = group.GroupName;
previewResult.Metadata["MaxDepth"] = config.MaxDepth;
// 复制分组的自定义元数据
foreach (var meta in group.Metadata)
{
previewResult.Metadata[meta.Key] = meta.Value;
}
results.Add(previewResult);
// 更新进度
processedGroups++;
int progressPercent = 75 + (processedGroups * 10 / floorGroups.Count);
int progressPercent = 75 + (processedGroups * 10 / groups.Count);
OnProgressChanged(new ProgressChangedEventArgs(progressPercent,
$"已处理 {processedGroups}/{floorGroups.Count} 个楼层分组"));
$"已处理 {processedGroups}/{groups.Count} 个{strategy.GroupTypeName}分组"));
}
OnProgressChanged(new ProgressChangedEventArgs(85, $"自定义楼层预览结果生成完成,共 {results.Count} 个分层"));
OnProgressChanged(new ProgressChangedEventArgs(85, $"{strategy.GroupTypeName}预览结果生成完成,共 {results.Count} 个分层"));
}
else
{
OnProgressChanged(new ProgressChangedEventArgs(85, "未检测到自定义楼层信息"));
LogManager.Warning("[SimplifiedModelSplitter] 未检测到任何自定义楼层信息");
OnProgressChanged(new ProgressChangedEventArgs(85, $"未检测到{strategy.GroupTypeName}信息"));
LogManager.Warning($"[SimplifiedModelSplitter] 未检测到任何{strategy.GroupTypeName}信息");
}
}
catch (Exception ex)
{
LogManager.Error($"[SimplifiedModelSplitter] 按自定义楼层预览失败: {ex.Message}", ex);
OnProgressChanged(new ProgressChangedEventArgs(35, $"自定义楼层分析失败: {ex.Message}"));
LogManager.Error($"[SimplifiedModelSplitter] 按{strategy.GroupTypeName}属性预览失败: {ex.Message}", ex);
OnProgressChanged(new ProgressChangedEventArgs(35, $"{strategy.GroupTypeName}分析失败: {ex.Message}"));
throw;
}
@ -716,6 +928,9 @@ namespace NavisworksTransport
}
/// <summary>
/// 处理单个分层(异步版本)
/// </summary>
@ -1873,7 +2088,7 @@ namespace NavisworksTransport
// 创建测试配置
var testConfig = new SplitConfiguration
{
Strategy = SplitStrategy.ByFloor,
Strategy = SplitStrategy.BySmartFloorDetection,
OutputDirectory = directory,
ExportOptions = new NwdExportUserOptions() // 使用默认选项
};
@ -1912,10 +2127,14 @@ namespace NavisworksTransport
{
switch (strategy)
{
case SplitStrategy.ByFloor:
case SplitStrategy.BySmartFloorDetection:
return "智能楼层检测分析";
case SplitStrategy.ByCustomFloor:
return "自定义分层分析";
case SplitStrategy.ByFloorAttribute:
return "按楼层属性分析";
case SplitStrategy.ByZoneAttribute:
return "按区域属性分析";
case SplitStrategy.BySubSystemAttribute:
return "按子系统属性分析";
default:
return "分层分析";
}

View File

@ -200,6 +200,75 @@ namespace NavisworksTransport
Math.Abs(f.Elevation - elevation) <= DEFAULT_ELEVATION_TOLERANCE);
}
/// <summary>
/// 从给定的模型项集合中检测楼层信息 - 不进行深度遍历
/// </summary>
/// <param name="items">预先过滤的模型项集合</param>
/// <param name="attributeName">指定的楼层属性名称,为空时自动检测</param>
/// <returns>检测到的楼层信息列表</returns>
public List<ModelSplitterManager.FloorInfo> DetectFloorsFromGivenItems(ModelItemCollection items, string attributeName = null)
{
try
{
LogManager.Info($"[FloorDetector] ===== DetectFloorsFromGivenItems开始 =====");
LogManager.Info($"[FloorDetector] 输入参数: items.Count={items?.Count ?? -1}, attributeName='{attributeName ?? "null"}'");
if (items == null || items.Count == 0)
{
LogManager.Warning("[FloorDetector] 输入的模型元素集合为空");
return new List<ModelSplitterManager.FloorInfo>();
}
LogManager.Info($"[FloorDetector] 直接使用传入的模型项集合进行楼层检测,元素数量: {items.Count}");
List<ModelSplitterManager.FloorInfo> floors;
if (!string.IsNullOrEmpty(attributeName))
{
LogManager.Info($"[FloorDetector] 使用指定属性检测楼层: {attributeName}");
// 使用指定属性检测楼层
floors = DetectFloorsByAttribute(items, attributeName);
LogManager.Info($"[FloorDetector] 使用属性 '{attributeName}' 检测到 {floors.Count} 个楼层");
}
else
{
LogManager.Info($"[FloorDetector] 开始自动检测最佳楼层属性");
// 自动检测最佳楼层属性
string bestAttribute = FindBestFloorAttribute(items);
LogManager.Info($"[FloorDetector] FindBestFloorAttribute返回: '{bestAttribute ?? "null"}'");
if (!string.IsNullOrEmpty(bestAttribute))
{
LogManager.Info($"[FloorDetector] 使用自动选择的属性: {bestAttribute}");
floors = DetectFloorsByAttribute(items, bestAttribute);
LogManager.Info($"[FloorDetector] 自动选择属性 '{bestAttribute}' 检测到 {floors.Count} 个楼层");
}
else
{
LogManager.Info($"[FloorDetector] 未找到合适属性,使用高程检测");
// 使用高程检测
floors = DetectFloorsByElevation(items);
LogManager.Info($"[FloorDetector] 使用高程检测到 {floors.Count} 个楼层");
}
}
LogManager.Info($"[FloorDetector] 开始验证和优化楼层结果");
// 验证和优化检测结果
floors = ValidateAndOptimizeFloors(floors);
LogManager.Info($"[FloorDetector] 验证优化完成,最终楼层数: {floors?.Count ?? -1}");
LogManager.Info($"[FloorDetector] ===== DetectFloorsFromGivenItems完成 ===== 最终识别 {floors.Count} 个楼层");
return floors;
}
catch (Exception ex)
{
LogManager.Error($"[FloorDetector] ===== DetectFloorsFromGivenItems异常 =====");
LogManager.Error($"[FloorDetector] 楼层检测失败: {ex.Message}");
LogManager.Error($"[FloorDetector] 异常堆栈: {ex.StackTrace}");
throw;
}
}
#endregion
#region -