Autodesk Forge+Google Map中Polyline绕ModelOrigin旋转偏移问题
问题:Autodesk Forge Geolocation扩展旋转Polyline时偏移过大
我正在使用Autodesk Forge的Geolocation扩展处理3D模型,并通过@react-google-maps/api在Google Map上展示。目前拥有3D世界坐标格式的polygon、经纬度格式的polyline,以及3D模型中心点modelOrigin。尝试让polyline与polygon以相同方式绕modelOrigin旋转,但polygon旋转正常,polyline旋转时偏移距离过大,会远离modelOrigin。
我使用Autodesk Forge Geolocation扩展的LL842LmvPoint方法将polyline的经纬度(lat和lng)转换为3D世界坐标,通过lmv2LL84Point方法转换回经纬度格式。
获取polygon(buildingProfile)坐标与modelOrigin的代码
const [yAxisLineLatLng, setYAxisLineLatLng] = useState<any>([ { "lat": 40.733288742831924, "lng": -74.15844074123018 }, { "lat": 40.73363656398297, "lng": -74.15844074123018 } ]); const [initialBuildingProfile, setInitialBuildingProfile] = useState<any>([]); const [initialBuildingProfileLatLng, setInitialBuildingProfileLatLng] = useState<any>([]); useEffect(() => { if (!model) return; const modelBoundingBox = model.getBoundingBox(); const { min, max } = modelBoundingBox; const profilePolygon = [ { x: min.x, y: min.y, }, { x: max.x, y: min.y, }, { x: max.x, y: max.y, }, { x: min.x, y: max.y, }, ]; const center = modelBoundingBox.center(); const origin = new (Autodesk.Viewing.Private as any).LmvVector3(...defaultLocation); localCS.current = new (Autodesk.Extensions as any).Geolocation.LocalCS( origin, model.getData().refPointTransform, model.getUnitScale(), model.getData().placementWithOffset, ); setInitialBuildingProfile(profilePolygon); setModelOrigin(center); }, [model, defaultLocation]);
转换buildingProfile为经纬度的代码
useEffect(() => { updateInitialBuildingProfile(); }, [buildingProfile, isLoaded]); function updateInitialBuildingProfile() { const buildingProfileLatLng = buildingProfile.map(function (point: any) { const thePoint = new (Autodesk.Viewing.Private as any).LmvVector3( point.x, point.y, 0, ); const geoLoc = localCS.current.lmv2LL84Point(thePoint); return { lat: geoLoc.y, lng: geoLoc.x }; }); setInitialBuildingProfileLatLng(buildingProfileLatLng); }
地图渲染代码
<GoogleMap id="buildingOrientation" zoom={18} onLoad={googleMapLoaded} center={{ lat: defaultLocation[1], lng: defaultLocation[0] }} mapContainerStyle={{ height: "440px", width: "100%", }} options={{ rotateControl: false, draggable: false, mapTypeControl: false, streetViewControl: false, fullscreenControl: false, tilt: 0, }} > <PolygonF paths={initialBuildingProfileLatLng} options={{ strokeColor: "#26282A", strokeOpacity: 1, strokeWeight: 2, fillColor: "#5B5C5E", fillOpacity: 1, }} /> <Polyline options={{ strokeColor: "red", strokeOpacity: 1.0, strokeWeight: 2, }} path={yAxisLineLatLng} /> </GoogleMap>;
初始渲染结果正常,但旋转后出现问题。
旋转polygon的代码
// function to rotate the squire polygon on a map. function rotatePolygon(angle) { const coords = initialBuildingProfile.map((point: any) => { const rotatedPoint = rotatePoint(point, modelOrigin, angle); return { x: rotatedPoint.x, y: rotatedPoint.y }; }); return coords; } function rotatePoint(point: any, origin: any, angle: any) { const angleRad = -(angle * Math.PI) / 180.0; return { x: Math.cos(angleRad) * (point.x - origin.x) - Math.sin(angleRad) * (point.y - origin.y) + origin.x, y: Math.sin(angleRad) * (point.x - origin.x) + Math.cos(angleRad) * (point.y - origin.y) + origin.y, }; }
旋转polyline的代码
function rotatePolyline(polyline: any, angle: any) { if (!modelOrigin) return; const polyline = yAxisLineLatLng; const polyline3D = polyline.map((point: any) => { const point3D = localCS.current.LL842LmvPoint({ x: point.lng, y: point.lat }); return { x: point3D.x, y: point3D.y }; }); const rotatedPolyline3D = polyline3D.map((point: any) => rotatePoint(point, modelOrigin, angle), ); const rotatedPolylineLatLng = rotatedPolyline3D.map((point: any) => { const pointLatLng = localCS.current.lmv2LL84Point( new (Autodesk.Viewing.Private as any).LmvVector3(point.x, point.y, point.z), ); return { lat: pointLatLng.y, lng: pointLatLng.x }; }); return rotatedPolylineLatLng; }
触发旋转的代码
const newCoords = rotatePolygon(15); setBuildingProfile(newCoords); const newAxis = rotatePolyline(15); setYAxisLineLatLng(newAxis);
旋转15度后,polygon显示正常,但polyline远离modelOrigin,与预期结果不符。
解决方案
问题出在旋转Polyline时的坐标转换逻辑以及rotatePolyline函数的参数覆盖错误,具体修正如下:
1. 修复参数覆盖问题
rotatePolyline函数内重新声明const polyline = yAxisLineLatLng;覆盖了传入参数,导致每次旋转都使用初始坐标而非最新值,删除这行代码:
function rotatePolyline(polyline: any, angle: any) { if (!modelOrigin) return; // 移除该行:const polyline = yAxisLineLatLng; // ... 后续代码保留 }
2. 确保3D坐标Z轴一致性
转换Polyline到3D坐标时,显式设置Z值(默认0),避免后续转换偏差:
const polyline3D = polyline.map((point: any) => { const point3D = localCS.current.LL842LmvPoint({ x: point.lng, y: point.lat }); return { x: point3D.x, y: point3D.y, z: point3D.z || 0 }; });
3. 修正经纬度转换的Z值传递
转回经纬度时,确保LmvVector3使用正确的Z值:
const rotatedPolylineLatLng = rotatedPolyline3D.map((point: any) => { const pointLatLng = localCS.current.lmv2LL84Point( new (Autodesk.Viewing.Private as any).LmvVector3(point.x, point.y, point.z || 0), ); return { lat: pointLatLng.y, lng: pointLatLng.x }; });
最终修正后的rotatePolyline函数
function rotatePolyline(polyline: any, angle: any) { if (!modelOrigin || !polyline) return; const polyline3D = polyline.map((point: any) => { const point3D = localCS.current.LL842LmvPoint({ x: point.lng, y: point.lat }); return { x: point3D.x, y: point3D.y, z: point3D.z || 0 }; }); const rotatedPolyline3D = polyline3D.map((point: any) => rotatePoint(point, modelOrigin, angle), ); const rotatedPolylineLatLng = rotatedPolyline3D.map((point: any) => { const pointLatLng = localCS.current.lmv2LL84Point( new (Autodesk.Viewing.Private as any).LmvVector3(point.x, point.y, point.z), ); return { lat: pointLatLng.y, lng: pointLatLng.x }; }); return rotatedPolylineLatLng; }
完成以上修正后,Polyline会和Polygon保持一致的旋转行为,不会出现偏移。
内容的提问来源于stack exchange,提问作者norbekoff
相关产品推荐
相关产品推荐

