如何在2D地图中基于DBID获取对象的(x,y,z)坐标?
基于DBID在2D地图中获取对象几何信息的解决方案
问题回顾
需要通过DBID在2D地图场景中获取对象的精准几何信息,但现有尝试的方法均存在问题:
- Bounding Box估算坐标:3D场景效果良好,但2D下精度极低
- 参考过的旧方案:因涉及无法访问的命名空间/函数,无法落地使用
- 对象属性中未存储坐标信息
可行解决思路
1. 提取原始几何数据转换为2D坐标
如果使用的是Forge Viewer这类平台,直接从模型中提取原始顶点数据,再通过相机投影矩阵转换为2D屏幕坐标,精度完全匹配原始模型:
function get2DCoordsByDbid(viewer, dbid) { const fragList = viewer.model.getFragmentList(); const fragIds = viewer.model.getFragmentList().fragments.dbId2fragId[dbid]; const screenPoints = []; fragIds.forEach(fragId => { const mesh = fragList.getVizmesh(fragId); const worldMatrix = fragList.getWorldMatrix(fragId); const positionAttr = mesh.geometry.attributes.position; for (let i = 0; i < positionAttr.count; i++) { const point3d = new THREE.Vector3( positionAttr.getX(i), positionAttr.getY(i), positionAttr.getZ(i) ); point3d.applyMatrix4(worldMatrix); // 转换为2D屏幕坐标 const point2d = point3d.clone().project(viewer.camera); screenPoints.push({ x: (point2d.x + 1) * viewer.canvas.width / 2, y: (-point2d.y + 1) * viewer.canvas.height / 2 }); } }); // 可根据需求处理点集,比如取中心坐标、生成轮廓 return screenPoints; }
2. 交互拾取获取精准2D坐标
如果是交互场景下需要坐标,直接监听鼠标点击事件,拾取目标DBID对象时获取当前2D坐标:
viewer.screenSpaceEventHandler.addEventListener( Autodesk.Viewing.SCREENSPACE_EVENT.MOUSE_CLICK, (event) => { const hitResult = viewer.clientToWorld(event.canvasX, event.canvasY); if (hitResult && hitResult.dbId === 你的目标DBID) { const precise2dCoord = { x: event.canvasX, y: event.canvasY }; // 此处使用坐标做后续业务处理 } } );
3. 预生成映射表提升高频查询效率
若项目中需要频繁查询,可在模型加载完成后,批量将所有DBID对应的2D几何信息(如顶点集合、中心坐标)存储到本地映射表中,后续直接通过DBID查表即可,大幅提升查询速度。
注意事项
- 务必在2D视图模式下执行坐标转换,避免3D/2D视图切换导致的矩阵计算错误
- 针对复杂模型,可使用凸包算法对提取的顶点集做简化处理,减少数据量
内容的提问来源于stack exchange,提问作者Brytista
相关产品推荐
相关产品推荐

