diff --git a/src/PathPlanning/ChannelBasedGridBuilder.cs b/src/PathPlanning/ChannelBasedGridBuilder.cs
index a89f53c..aea6ad7 100644
--- a/src/PathPlanning/ChannelBasedGridBuilder.cs
+++ b/src/PathPlanning/ChannelBasedGridBuilder.cs
@@ -96,14 +96,67 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[通道网格构建器] 成功投影 {processedChannels.Count}/{channelItems.Count} 个通道");
+ // 5. 计算可通行网格的Z值范围
+ var (walkableMinZ, walkableMaxZ, walkableCount) = CalculateWalkableGridZRange(gridMap);
+
return new ChannelCoverage
{
GridMap = gridMap,
ChannelItems = processedChannels,
- TotalBounds = totalBounds
+ TotalBounds = totalBounds,
+ WalkableMinZ = walkableMinZ,
+ WalkableMaxZ = walkableMaxZ,
+ WalkableGridCount = walkableCount
};
}
+ ///
+ /// 计算可通行网格的Z值范围
+ /// 遍历所有可通行网格,基于实际WorldPosition.Z坐标计算最小值和最大值
+ ///
+ /// 网格地图
+ /// 包含最小Z值、最大Z值和可通行网格数量的元组
+ private (double minZ, double maxZ, int walkableCount) CalculateWalkableGridZRange(GridMap gridMap)
+ {
+ double minZ = double.MaxValue;
+ double maxZ = double.MinValue;
+ int walkableCount = 0;
+
+ LogManager.Info("[通道Z值计算] 开始计算可通行网格Z值范围");
+
+ for (int x = 0; x < gridMap.Width; x++)
+ {
+ for (int y = 0; y < gridMap.Height; y++)
+ {
+ var cell = gridMap.Cells[x, y];
+
+ // 只计算可通行的网格
+ if (cell.IsWalkable)
+ {
+ walkableCount++;
+ double cellZ = cell.WorldPosition.Z;
+
+ if (cellZ < minZ)
+ minZ = cellZ;
+ if (cellZ > maxZ)
+ maxZ = cellZ;
+ }
+ }
+ }
+
+ // 如果没有可通行网格,返回默认值
+ if (walkableCount == 0)
+ {
+ LogManager.Warning("[通道Z值计算] 未找到可通行网格,使用默认Z值范围");
+ minZ = 0.0;
+ maxZ = 0.0;
+ }
+
+ LogManager.Info($"[通道Z值计算] 计算完成 - 可通行网格: {walkableCount}个, Z范围: [{minZ:F2}, {maxZ:F2}], 高度差: {maxZ - minZ:F2}");
+
+ return (minZ, maxZ, walkableCount);
+ }
+
///
/// 将通道投影到网格
diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs
index 32105ee..fefd986 100644
--- a/src/PathPlanning/GridMap.cs
+++ b/src/PathPlanning/GridMap.cs
@@ -788,6 +788,21 @@ namespace NavisworksTransport.PathPlanning
///
public BoundingBox3D TotalBounds { get; set; }
+ ///
+ /// 可通行网格的最小Z坐标(基于实际网格位置)
+ ///
+ public double WalkableMinZ { get; set; } = double.MaxValue;
+
+ ///
+ /// 可通行网格的最大Z坐标(基于实际网格位置)
+ ///
+ public double WalkableMaxZ { get; set; } = double.MinValue;
+
+ ///
+ /// 可通行网格数量
+ ///
+ public int WalkableGridCount { get; set; } = 0;
+
///
/// 获取统计信息
///
@@ -809,8 +824,12 @@ namespace NavisworksTransport.PathPlanning
}
}
+ var zRangeInfo = WalkableGridCount > 0
+ ? $", Z范围: [{WalkableMinZ:F2}, {WalkableMaxZ:F2}], 可通行网格: {WalkableGridCount}个"
+ : ", Z范围: 未计算";
+
return $"通道覆盖统计: {ChannelItems.Count} 个通道物品, {channelCellCount} 个通道网格单元, " +
- $"网格大小: {GridMap?.Width}x{GridMap?.Height}";
+ $"网格大小: {GridMap?.Width}x{GridMap?.Height}{zRangeInfo}";
}
}
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 30178bb..1bfa7c9 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -57,8 +57,25 @@ namespace NavisworksTransport.PathPlanning
{
try
{
- // 生成缓存键
- var cacheKey = GridMapCacheKey.CreateFrom(bounds, cellSize, vehicleRadius, safetyMargin, vehicleHeight);
+ // 第一步:统一转换所有米制参数为模型单位
+ double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
+ double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
+ double vehicleRadiusInModelUnits = vehicleRadius * metersToModelUnitsConversionFactor;
+ double safetyMarginInModelUnits = safetyMargin * metersToModelUnitsConversionFactor;
+ double vehicleHeightInModelUnits = vehicleHeight * metersToModelUnitsConversionFactor;
+ double scanHeightInModelUnits = vehicleHeightInModelUnits + safetyMarginInModelUnits; // 扫描高度 = 车辆高度 + 安全间隙
+ double totalInflationRadiusInModelUnits = vehicleRadiusInModelUnits + safetyMarginInModelUnits; // 膨胀半径 = 车辆半径 + 安全间隙
+
+ LogManager.Info($"【生成网格地图】参数单位转换完成 (转换系数: {metersToModelUnitsConversionFactor:F2}):");
+ LogManager.Info($" 网格大小: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位");
+ LogManager.Info($" 车辆半径: {vehicleRadius}米 → {vehicleRadiusInModelUnits:F2}模型单位");
+ LogManager.Info($" 安全间隙: {safetyMargin}米 → {safetyMarginInModelUnits:F2}模型单位");
+ LogManager.Info($" 车辆高度: {vehicleHeight}米 → {vehicleHeightInModelUnits:F2}模型单位");
+ LogManager.Info($" 扫描高度: {scanHeightInModelUnits:F2}模型单位");
+ LogManager.Info($" 膨胀半径: {totalInflationRadiusInModelUnits:F2}模型单位");
+
+ // 生成缓存键(使用转换后的模型单位参数确保一致性)
+ var cacheKey = GridMapCacheKey.CreateFrom(bounds, cellSizeInModelUnits, vehicleRadiusInModelUnits, safetyMarginInModelUnits, vehicleHeightInModelUnits);
// 尝试从缓存获取
var cachedGridMap = GlobalGridMapCache.Instance.Get(cacheKey, 5000); // 预估生成需要5秒
@@ -83,23 +100,6 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"【生成网格地图】缓存键: {cacheKey}");
var startTime = DateTime.Now;
- // 第一步:统一转换所有米制参数为模型单位
- double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
- double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
- double vehicleRadiusInModelUnits = vehicleRadius * metersToModelUnitsConversionFactor;
- double safetyMarginInModelUnits = safetyMargin * metersToModelUnitsConversionFactor;
- double vehicleHeightInModelUnits = vehicleHeight * metersToModelUnitsConversionFactor;
- double scanHeightInModelUnits = vehicleHeightInModelUnits + safetyMarginInModelUnits; // 扫描高度 = 车辆高度 + 安全间隙
- double totalInflationRadiusInModelUnits = vehicleRadiusInModelUnits + safetyMarginInModelUnits; // 膨胀半径 = 车辆半径 + 安全间隙
-
- LogManager.Info($"【生成网格地图】参数单位转换完成 (转换系数: {metersToModelUnitsConversionFactor:F2}):");
- LogManager.Info($" 网格大小: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位");
- LogManager.Info($" 车辆半径: {vehicleRadius}米 → {vehicleRadiusInModelUnits:F2}模型单位");
- LogManager.Info($" 安全间隙: {safetyMargin}米 → {safetyMarginInModelUnits:F2}模型单位");
- LogManager.Info($" 车辆高度: {vehicleHeight}米 → {vehicleHeightInModelUnits:F2}模型单位");
- LogManager.Info($" 扫描高度: {scanHeightInModelUnits:F2}模型单位");
- LogManager.Info($" 膨胀半径: {totalInflationRadiusInModelUnits:F2}模型单位");
-
// 1. 使用通道构建器构建基础通道覆盖网格
LogManager.Info("【生成网格地图】步骤1: 构建通道覆盖网格");
var channelCoverage = _channelBuilder.BuildChannelCoverage(cellSizeInModelUnits);
@@ -1069,13 +1069,14 @@ namespace NavisworksTransport.PathPlanning
{
try
{
- var properties = new ItemProperties();
-
- // 已知条件:HasGeometry = true(Search API保证)
- properties.HasGeometry = true;
-
- // 快速筛除1:通道相关项目(HashSet查找,极快)
- properties.IsChannelItem = channelItemsSet.Contains(item);
+ var properties = new ItemProperties
+ {
+ // 已知条件:HasGeometry = true(Search API保证)
+ HasGeometry = true,
+
+ // 快速筛除1:通道相关项目(HashSet查找,极快)
+ IsChannelItem = channelItemsSet.Contains(item)
+ };
if (properties.IsChannelItem)
{
skippedByChannel++;
@@ -1168,13 +1169,13 @@ namespace NavisworksTransport.PathPlanning
var filterElapsed = (DateTime.Now - filterStart).TotalMilliseconds;
LogManager.Info($"[高性能障碍物处理] 阶段3完成: 从缓存中筛选出 {validItems.Count} 个有效项,耗时: {filterElapsed:F1}ms");
- // 获取通道高度范围信息
- var channelBounds = channelCoverage.TotalBounds;
- var channelMinZ = channelBounds.Min.Z;
- var channelMaxZ = channelBounds.Max.Z;
- var channelHeightRange = channelMaxZ - channelMinZ;
- LogManager.Info($"[高性能障碍物处理] 通道高度信息 - 最低点: {channelMinZ:F2}, 最高点: {channelMaxZ:F2}");
- LogManager.Info($"[高性能障碍物处理] 通道高度范围: {channelHeightRange:F2}, 加车辆高度后扫描范围: [{channelMinZ:F2}, {channelMaxZ + scanHeightInModelUnits:F2}]");
+ // 获取可通行网格的实际高度范围信息
+ var walkableMinZ = channelCoverage.WalkableMinZ;
+ var walkableMaxZ = channelCoverage.WalkableMaxZ;
+ var walkableGridCount = channelCoverage.WalkableGridCount;
+ var walkableHeightRange = walkableMaxZ - walkableMinZ;
+ LogManager.Info($"[高性能障碍物处理] 可通行网格高度信息 - 最低点: {walkableMinZ:F2}, 最高点: {walkableMaxZ:F2}");
+ LogManager.Info($"[高性能障碍物处理] 可通行网格数量: {walkableGridCount}, 高度范围: {walkableHeightRange:F2}, 加车辆高度后扫描范围: [{walkableMinZ:F2}, {walkableMaxZ + scanHeightInModelUnits:F2}]");
// 阶段4:网格覆盖计算(并行几何计算)- 使用50%CPU核心优化 + 基于通道的精确高度检查
LogManager.Info("[高性能障碍物处理] 阶段4: 并行网格覆盖计算 + 基于通道高度的精确高度检查");
@@ -1197,10 +1198,10 @@ namespace NavisworksTransport.PathPlanning
var centerCell = gridMap.Cells[centerGridPos.X, centerGridPos.Y];
- // 使用通道高度范围计算扫描范围
- // 扫描范围:从通道最低点开始,到通道最高点+车辆高度+安全间隙
- var scanMin = channelMinZ;
- var scanMax = channelMaxZ + scanHeightInModelUnits;
+ // 使用可通行网格高度范围计算扫描范围
+ // 扫描范围:从可通行网格最低点开始,到可通行网格最高点+车辆高度+安全间隙
+ var scanMin = walkableMinZ;
+ var scanMax = walkableMaxZ + scanHeightInModelUnits;
// 只有与该网格高度范围重叠的几何体才进入处理
bool isInRange = !(bbox.Max.Z <= scanMin || bbox.Min.Z > scanMax);