美文网首页程序员
cesium基础属性,获取当前高度,三维范围,重写geoCode

cesium基础属性,获取当前高度,三维范围,重写geoCode

作者: 天上月丶 | 来源:发表于2017-10-20 15:42 被阅读914次
    • 首先,基本了解一下各个属性代表的含义,

    var viewer = new Cesium.Viewer( 'cesiumContainer', {
    animation : false,//是否创建动画小器件,左下角仪表
    baseLayerPicker : false,//是否显示图层选择器
    fullscreenButton : false,//是否显示全屏按钮
    geocoder : false,//是否显示geocoder小器件,右上角查询按钮
    homeButton : false,//是否显示Home按钮
    infoBox : false,//是否显示信息框
    sceneModePicker : false,//是否显示3D/2D选择器
    selectionIndicator : false,//是否显示选取指示器组件
    timeline : false,//是否显示时间轴
    navigationHelpButton : false,//是否显示右上角的帮助按钮
    scene3DOnly : true,//如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
    clock : new Cesium.Clock(),//用于控制当前时间的时钟对象
    selectedImageryProviderViewModel : undefined,//当前图像图层的显示模型,仅baseLayerPicker设为true有意义
    imageryProviderViewModels : Cesium.createDefaultImageryProviderViewModels(),//可供BaseLayerPicker选择的图像图层ProviderViewModel数组
    selectedTerrainProviderViewModel : undefined,//当前地形图层的显示模型,仅baseLayerPicker设为true有意义
    terrainProviderViewModels : Cesium.createDefaultTerrainProviderViewModels(),//可供BaseLayerPicker选择的地形图层ProviderViewModel数组
    imageryProvider : new Cesium.OpenStreetMapImageryProvider( {
    credit :'',
    url : '//192.168.0.89:5539/planet-satellite/'
    } ),//图像图层提供者,仅baseLayerPicker设为false有意义
    terrainProvider : new Cesium.EllipsoidTerrainProvider(),//地形图层提供者,仅baseLayerPicker设为false有意义
    skyBox : new Cesium.SkyBox({
    sources : {
    positiveX : 'Cesium-1.7.1/Skybox/px.jpg',
    negativeX : 'Cesium-1.7.1/Skybox/mx.jpg',
    positiveY : 'Cesium-1.7.1/Skybox/py.jpg',
    negativeY : 'Cesium-1.7.1/Skybox/my.jpg',
    positiveZ : 'Cesium-1.7.1/Skybox/pz.jpg',
    negativeZ : 'Cesium-1.7.1/Skybox/mz.jpg'
    }
    }),//用于渲染星空的SkyBox对象 ,换句话说,就是地球后面的大背景。这个地方为6张图片,但图片必须为正方形,就好像正六面体的六个面一样,更换图片要保证6张图片之前过渡流畅,否则会很尴尬,实际试一下就知道了。
    fullscreenElement : document.body,//全屏时渲染的HTML元素,
    useDefaultRenderLoop : true,//如果需要控制渲染循环,则设为true
    targetFrameRate : undefined,//使用默认render loop时的帧率
    showRenderLoopErrors : false,//如果设为true,将在一个HTML面板中显示错误信息
    automaticallyTrackDataSourceClocks : true,//自动追踪最近添加的数据源的时钟设置
    contextOptions : undefined,//传递给Scene对象的上下文参数(scene.options)
    sceneMode : Cesium.SceneMode.SCENE3D,//初始场景模式
    mapProjection : new Cesium.WebMercatorProjection(),//地图投影体系
    dataSources : new Cesium.DataSourceCollection()
    //需要进行可视化的数据源的集合
    } );
    var scene = viewer.scene;
    var canvas = viewer.canvas;
    var clock = viewer.clock;
    var camera = viewer.scene.camera;
    var entities = viewer.entities;

    • 添加一个图层
    var layers = CesMap.viewer.scene.imageryLayers;
    var baseLayer = layers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({//图层的类型
               url: '图层的url,arcgis可使用公开发布的地图'
    }));
    

    这里的url为不同种类地图的的路径,我使用的是arcgis的地图,这里,贴上arcgis官方提供的地图:http://services.arcgisonline.com/arcgis/rest/services
    图层可设置显示,隐藏,透明度等等,可以去官网看文档,讲的还是比较详细的,就不在这赘述了。

    • 地球的camera转动监听事件
    CesMap.viewer.camera.changed.addEventListener(function (percentage) {
            转动之后的触发事件
     });
    
    • 获取camera高度(类似地图的getZoom(),getLayer()函数)
      使用平面地图的朋友,都有获取地图的zoom或者layer的参数,在cesium中,有时也会有这种需求,但在cesium中,并没有找到类似getZoom或者getLayer的函数,但好在可以获取camera当前的高度,根据高度,也可以像判断zoom或layer一样,进行自己的操作,附上以下代码:
    function getHeight() {
            if (viewer) {
                var scene = viewer.scene;
                var ellipsoid = scene.globe.ellipsoid;
                var height = ellipsoid.cartesianToCartographic(viewer.camera.position).height;
                return height;
            }
        }
    
    • 得到当前视图的三维范围,类似于平面地图的getExtent(),这个就不详细解释了,以下代码可直接复用
     function getCurrentExtent() {
            // 范围对象
            var extent = {};
    
            // 得到当前三维场景
            var scene = viewer.scene;
    
            // 得到当前三维场景的椭球体
            var ellipsoid = scene.globe.ellipsoid;
            var canvas = scene.canvas;
    
            // canvas左上角
            var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);
    
            // canvas右下角
            var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);
    
            // 当canvas左上角和右下角全部在椭球体上
            if (car3_lt && car3_rb) {
                var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
                var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
                extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
                extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
                extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
                extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
            }
    
            // 当canvas左上角不在但右下角在椭球体上
            else if (!car3_lt && car3_rb) {
                var car3_lt2 = null;
                var yIndex = 0;
                do {
                    // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
                    yIndex <= canvas.height ? yIndex += 10 : canvas.height;
                    car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);
                } while (!car3_lt2);
                var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
                var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
                extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
                extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
                extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
                extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
            }
    
            // 获取高度
            extent.height = Math.ceil(viewer.camera.positionCartographic.height);
            return extent;
        }
    
    • 得到地图中心点坐标,有时候是一定用的上的,比如我们公司苦逼的要求,给出地图中心点的天气(这个题外啦,题外啦…………)
    function getCenterPosition() {
            var result = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2));
            var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
            var lon = curPosition.longitude * 180 / Math.PI;
            var lat = curPosition.latitude * 180 / Math.PI;
            var height = CesMap.getHeight();
            return {
                lon: lon,
                lat: lat,
                height: height
            };
        }
    
    • 还有比较重要的一点,复写geoCoder的搜索函数,就是地图右上角的默认搜索。
      这个官方没有给出解决方案,不过经过多方查找,还是可以复写的。
      我们可以先打印出viewer.geocoder.viewModel,如下图所示:
    geoCoder

    geoCoder._searchCommand就是默认的搜索函数,geoCoder._complete是搜索完成的函数,如果我们想保留默认的搜索函数,则可以看到在geoCoder._searchCommand内,有两个函数,geoCoder._searchCommand.beforeExecute和geoCoder._searchCommand.afterExecute,顾名思义,就是在搜索开始之前和搜索之后进行的操作,由于一般我们不会完全复写geoCoder._searchCommand函数,不然自己写一个输入框就好了,为嘛还要这么麻烦呢,我们还是想保留它原本的搜索能力,在之前或之后进行一些操作的,所以,类似如下代码即可完成需求:

    geoCoder._complete._listeners.push(function () {
            搜索完全结束后你的操作
    });
    
     geoCoder._searchCommand.beforeExecute._listeners.push(function () {
            开始搜索之前你的操作
     });
    
    geoCoder._searchCommand.afterExecute._listeners.push(function () {
           搜索执行之后你的操作
     });
    

    七七八八感觉也就这么多了,目前也是刚接触cesium,用的不是很深…………

    相关文章

      网友评论

        本文标题:cesium基础属性,获取当前高度,三维范围,重写geoCode

        本文链接:https://www.haomeiwen.com/subject/kkdvuxtx.html