cesium中限制地图浏览范围

cesium中限制地图浏览范围

项目中有限制用户地图浏览范围的需求,经过研究以及查找相关资料,得出了一个可行方法:1、限制用户浏览视角的高度范围,然后实时监测镜头的范围,最后用实时镜头范围与限制范围的经纬度进行对比,超出就跳回初始视角,如下:

*1、限制镜头高度

限制镜头的高度使用cesium自带api就可以直接实现,如下:

viewer.scene.screenSpaceCameraController.maximumZoomDistance =200000;
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10;

*2、实时监测镜头范围

想要实时监测镜头范围,通过查找相关的文章学习到到了两个cesium的方法:

//实时监测方法,该方法会不停的调用,频率相当高
viewer.scene.preRender.addEventListener();
//计算镜头范围方法,该方法会计算当前镜头地理坐标(弧度)范围并返回west,east,north,south 4个范围参数
viewer.camera.computeViewRectangle();

将两者组合就可以实时监测镜头地理坐标(弧度)范围了:

viewer.scene.preRender.addEventListener(function() {
  let rectangle = viewer.camera.computeViewRectangle();
  //rectangle 为当前镜头的实时范围
  }

*3、将获取的rectangle由地理坐标(弧度)转为经纬度坐标

通过查找相关资料找到了地理坐标(弧度)转经纬度坐标的方法,如下:

// 将弧度转为经纬度,west为左(西)侧边界的经度,以下类推
let west =rectangle.west / Math.PI * 180;
let north = rectangle.north / Math.PI * 180;
let east = rectangle.east / Math.PI * 180;
let south = rectangle.south / Math.PI * 180;

*4、设置可浏览的经纬度范围,判断镜头是否超出,超出则跳回

设置可浏览的经纬度范围:

//按需求设置可浏览的经纬度边界
let Range = {west:100.111111,north:25.11111,east:105.11111,south:28.111111};

判断超出跳回:

//如果视角超出设置经纬度范围则跳转视角
if(west < Range.west || north < Range.north || east > Range.east || south > Range.south){
            console.log("跳转视角");
            viewer.scene.camera.setView({
                destination: new Cesium.Cartesian3(-1264160.070654434, 5665789.912013389, 2654915.919083717),
                orientation: {
                    heading: 0.16290833989833153,
                    pitch: -0.43768116366765275,
                    roll: 6.283129299301802
                }
            });
        }
//可以选择flyto方法,飞行更流畅

*5、完整代码

//限制地图浏览范围
    //限制镜头高度
    viewer.scene.screenSpaceCameraController.maximumZoomDistance =200000;
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10;
    //实时监测镜头范围(该方法会一直调用)
    viewer.scene.preRender.addEventListener(function() {
    	//计算镜头范围方法,该方法会计算当前镜头地理坐标(弧度)范围并返回west,east,north,south 4个范围参数
        let rectangle = viewer.camera.computeViewRectangle();
        // console.log(rectangle,'rectangle');
        //设置可浏览经纬度范围
        let Range = {west:100.111111,north:25.11111,east:105.11111,south:28.111111};
        //地理坐标(弧度)转经纬度坐标
        // 弧度转为经纬度,west为左(西)侧边界的经度,以下类推
        let west =rectangle.west / Math.PI * 180;
        let north = rectangle.north / Math.PI * 180;
        let east = rectangle.east / Math.PI * 180;
        let south = rectangle.south / Math.PI * 180;
        //如果视角超出设置范围则跳转视角
        if(west < Range.west || north < Range.north || east > Range.east || south > Range.south){
            //console.log("跳转视角");
            viewer.scene.camera.setView({
                destination: new Cesium.Cartesian3(-1264160.070654434, 5665789.912013389, 2654915.919083717),
                orientation: {
                    heading: 0.16290833989833153,
                    pitch: -0.43768116366765275,
                    roll: 6.283129299301802
                }
            });
        }
     )};
//可以选择flyto方法,飞行更流畅

*6、方法缺陷与更好的实现方式

该方式实现浏览范围限制,有两个弊端:
1、preRender.addEventListener()方法会一直调用,频率很高,不利于前端性能优化,尤其是加载大型地图后,本来就卡顿的界面,可能会更加卡顿,且如果初始范围小于设置的浏览范围,就会一直触发视角跳转,导致死循环,无法操作。
2、拉到地图边界跳转视角,不利于用户体验,到范围边界后禁止往更外面拖动与放大,才是更优秀的方法,但笔者未找到相关实现方式,有知道的大佬可以评论区留言。
更好的实现方式
因以上两个弊端,因此笔者项目中弃用了此方法,改为按需加载相应图层,这样既可减少图层加载数量,也不会有以上两个弊端,更利于前端性能优化。建议大家最好也使用此种方式实现范围限制。

参考大佬传送门:
https://www.cnblogs.com/xt112233/p/14044460.html
https://blog.csdn.net/u011495292/article/details/81207144
https://blog.csdn.net/pyx6119822/article/details/81208151
https://blog.csdn.net/zhengshaofeng1/article/details/113613138
https://blog.csdn.net/qq_42036616/article/details/90140636

上一篇:Cesium快速上手10-Viewer Entities组合


下一篇:cesium 偏航(yaw)/俯仰(pitch)/滚动(roll)