您的位置:首页 > 其它

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

2018-03-17 10:39 1136 查看
首先,基本了解一下各个属性代表的含义,
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,如下图所示:



eoCoder._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,用的不是很深…………

作者:天上月丶

链接:https://www.jianshu.com/p/04412e351d8a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐