一、可视域分析介绍
包括地形、建筑等自然和人造物体会对视线产生遮挡,而对于部分应用场景,比如军事、城市规划等领域,需要进行可视域分析。可视域分析可以得到一个点或者某一区域的可见性,进而做到一系列的应用,比如军事作战中的掩护和微微,城市规划中的最优视觉塔及摄影点的选择等。
由于3D模型具有真实感,因此,在3D模型上进行可视域分析比在2D图像上分析更加直观,能够更好的提高分析的效果。而Cesium是一款基于WebGL的开源虚拟地球仪,能够提供浏览器端的3D模型可视化功能,因此,Cesium作为3D可视化工具之一,提供额外的API来进行3D场景下的可视域分析。
二、Cesium的可视域分析原理
Cesium的可视域分析API是基于射线追踪算法实现的,具体算法如下:
// 输入 var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 0.0); var heading = Cesium.Math.toRadians(0.0); var pitch = Cesium.Math.toRadians(0.0); var roll = Cesium.Math.toRadians(0.0); var hfov = Cesium.Math.toRadians(60.0); // 输出 var visibleWindow = camera.computeViewRectangle(scene.globe.ellipsoid); // 射线追踪算法 var ray = new Cesium.Ray(origin, camera.direction); var intersection = scene.globe.pick(ray, scene); if (intersection) { var range = Cesium.Cartesian3.distance(intersection, origin); var aspectRatio = canvas.width / canvas.height; var verticalFov = Cesium.Math.atan(Cesium.Math.tan(hfov*0.5) / aspectRatio); var horizontalFov = 2 * Cesium.Math.atan(Cesium.Math.tan(verticalFov*0.5) * aspectRatio); var fov = Math.min(hfov, horizontalFov); var angle = 2 * Cesium.Math.atan(viewHeight / (2 * range)); var radius = range * Math.sin(fov*0.5) / Math.sin(angle*0.5); visibleWindow = getCorners(origin, camera.direction, radius, aspectRatio, scene.globe.ellipsoid); }
该算法首先获取相机的位置和视角参数,然后获取以该位置和相机参数为输入的可视范围,接着根据射线追踪算法计算可视域范围。该算法根据相机位置和视角参数计算出一条射线,然后在地球模型上进行碰撞检测,获取射线与地球模型的交点,然后根据交点和相机位置计算出可视域范围。
三、Cesium可视域分析功能实现
1、显示可视域
利用Cesium内置的Primitive类型来应用的位置的范围来可视化可视域。代码如下:
var target = Cesium.Cartesian3.fromDegrees(longitude, latitude, height); var radius = Cesium.Cartesian3.distance(camera.position, target); var visibleArea = new Cesium.Primitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.CircleGeometry({ center : target, radius : radius, vertexFormat : Cesium.VertexFormat.POSITION_ONLY }) }), appearance: new Cesium.EllipsoidSurfaceAppearance({ aboveGround : false }), show : true }); scene.primitives.add(visibleArea);
2、计算可视域范围
获取可视域范围的方法是根据射线追踪算法,计算射线与地球模型的交点,也就是获取在地球模型上的可视区域。
var pickRay = camera.getPickRay(new Cesium.Cartesian2(0, 0)); var intersection = scene.globe.pick(pickRay, viewer.scene); var position = Cesium.Ellipsoid.WGS84.cartesianToCartographic(intersection);
3、计算测量高度角
根据可视域向量来确定测量高度角。
var globe = viewer.scene.globe; var ellipsoid = globe.ellipsoid; var positionCartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); var positionHeight = positionCartographic.height; var cameraCartographic = globe.ellipsoid.cartesianToCartographic(camera.position); var cameraHeight = cameraCartographic.height; var relativeHeight = positionHeight - cameraHeight; // 补偿半径高度 var offsetHeight = relativeHeight + ellipsoid.radii.x; if (offsetHeight < 0) { offsetHeight = relativeHeight - ellipsoid.radii.x; } // 计算高度角 var maxAngle = Math.atan2(offsetHeight, positionCartographic.distance(cameraCartographic));
4、计算水平范围
根据可视域向量计算水平范围。
// 计算方位角 var cameraHeading = camera.heading; if (cameraHeading < 0) cameraHeading += 2 * Math.PI; var targetPos = Cesium.Cartesian3.fromDegrees(longitude, latitude, height); var targetPosCartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(targetPos); var bearing = getBearing(cameraCartographic, targetPosCartographic); if (bearing < 0) bearing += 360.0; // 计算水平范围 var left = bearing - maxAngle; var right = bearing + maxAngle; if (left > 360.0) left -= 360.0; if (right > 360.0) right -= 360.0; if (right < left) { var tmp = left; left = right; right = tmp + 360.0; }
四、Cesium可视域分析应用场景
1、军事作战
军事作战中,敌军的可视域是非常重要的信息。因此,通过Cesium对3D模型进行可视域分析,可以更加直观地显示敌人的视野范围,从而更好地做出反应。
2、城市规划
在城市规划领域中,3D模型中的可视域分析可以帮助规划者更好地确定市区的建筑和道路的布局,找到最优的视觉塔和摄影点,使得城市布局更加合理和完美。
3、自然资源管理
在自然资源管理领域中,可视域分析可以帮助环保人员更好地解决难题。举个例子,德州市林业部门利用可视域分析方法来监测野生大熊猫栖息地的违法行为,包括非法伐木和非法盗猫情况。
结论
总的来说,Cesium的可视域分析API是基于射线追踪算法实现的,可以帮助用户更加方便地完成可视域分析,适用于军事作战、城市规划、自然资源管理等领域。