我写的每一篇文章,都不成体系,简直就是一个杂烩,什么都有,用到什么就写什么,用到什么就学什么,我也觉得这样不好,但是还是无法避免出现这样的情况,因为每天都会遇到新的问题,但是脑子又很难记住,于是只能先找一个地方记录下来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var initialPosition = new Cesium .Cartesian3 .fromDegrees (120.35295 ,30.3362 ,100.0 );var initialOrientation = new Cesium .HeadingPitchRoll .fromDegrees (7.1077496389876024807 , -31.987223091598949054 , 0.025883251314954971306 );var homeCameraView = { destination : initialPosition, orientation : { heading : initialOrientation.heading , pitch : initialOrientation.pitch , roll : initialOrientation.roll } }; viewer.scene .camera .setView (homeCameraView); homeCameraView.duration = 2.0 ; homeCameraView.maximumHeight = 2000 ; homeCameraView.pitchAdjustHeight = 2000 ; homeCameraView.endTransform = Cesium .Matrix4 .IDENTITY ; viewer.homeButton .viewModel .command .beforeExecute .addEventListener (function (e ) { e.cancel = true ; viewer.scene .camera .flyTo (homeCameraView); });
修改homebutton的点击事件,除了修改源码,还有别的方法吗?
参考文章: 1.Cesium设置位置和视角 2.Cesium如何改变HomeButton(首页)的默认位置? (这里通过聚焦点击事件,然后覆盖了homebutton的默认点击事件) 3.new Cesium.HomeButton(container, scene, duration) 4.Ceisum官方教程2 – 项目实例(workshop) (在这篇文章的最后,有对设置相机的位置以及修改homebutton按钮的说明,这篇文章其实也是一篇入门文章,里面东西还是挺多的。)
2.增加导航栏 要增加导航栏,也有几个插件可以使用。最后我使用的是cesium-navigation,官方仓库中没有提供viewerCesiumNavigationMixin.min.js,需要自己下载源码,然后使用node build.js进行编译生成viewerCesiumNavigationMixin.min.js文件,然后才能独立使用。
1 2 3 4 5 6 7 8 9 10 <script src="./Build/Cesium/viewerCesiumNavigationMixin.min.js" ></script> var viewer = new Cesium .Map ('cesiumContainer' , { shouldAnimate : true , selectionIndicator :true , infoBox :false , homeButton :true , }); viewer.extend (Cesium .viewerCesiumNavigationMixin , {});
简单的一句话,最后的效果就会有一个漂亮的导航条。
还可以修改css样式
1 2 3 4 5 6 7 8 9 10 .compass { position : absolute; right : 10px ; top :50px ; } .navigation-controls { position : absolute; right : 40px ; top :150px ; }
参考文章: 1.cesium-navigation-es6 (这是cesium-navigation-es6 1.1.6仓库,可以结合vue使用) 2.cesium-navigation (这是cesium-navigation的仓库,需要从这里下载源码然后执行cnpm install和node build.js命令编译生成viewerCesiumNavigationMixin.min.js文件) 3.Cesium导航指针放大缩小定位平移详解 (这里改了cesium-navigation-es6 1.1.6源码,介绍了如何使用cesium-navigation-es6 1.1.6) 4.cesium导航 (这里讲了如何使用cesium-navigation但是没有说这个min.js如何来的) 5.cesiumjs学习笔记之三——cesium-navigation插件 【转】
5.加载WFS服务 (1) 加载WFS服务,主要就是获取数据,然后使用GeoJsonDataSource进行渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var datasource=Cesium .GeoJsonDataSource .load (data);var entities = dataSource.entities .values ;for (var i = 0 ; i < entities.length ; i++) { var entity = entities[i]; entity.billboard = undefined ; entity.point = new Cesium .PointGraphics ({ color : Cesium .Color .FORESTGREEN , pixelSize : 10 }); } viewer.dataSources .add (datasource);
默认的样式就是一个蓝色的图钉
参考文章: 1.cesium加载WFS服务(GeoServer发布) 2.Cesium 查询加载 geoserver的wfs 数据 (这篇文章主要其实是写的如何获取geojson数据,而不是如今加载) 3.Cesium加载OGC服务 (这篇文章写的较为详细,包括修改默认的样式) 4.Cesium:获取某个entity的位置属性 Cartesian3 (获取entity的位置)
(2) 加载Geoserver发布的WFS服务,并进行颜色的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 getFactoryLayer ().then (data => { if (data&&data.status &&data.status ==500 ){ return } let viewer=window .cesiumViewer ; Cesium .GeoJsonDataSource .load (data).then (datasource => { let dataSource=viewer.dataSources ; dataSource.add (datasource); var entities = datasource.entities .values ; for (var i = 0 ; i < entities.length ; i++) { var entity = entities[i]; let polygon=entity.polygon ; polygon.material =new Cesium .Color (0.12 , 0.45 , 0.77 ,0.7 ); } }); });
参考文章: 1.Cesium调用Geoserver发布的 WMS、WFS服务
6.获取鼠标点击位置 1.获取鼠标点的对应椭球面位置:世界坐标(Cartesian3)。 2.获取加载地形后对应的经纬度和高程:地标坐标; 3.获取倾斜摄影或模型点击处的坐标:场景坐标; 4.获取点击处屏幕坐标 :屏幕坐标(鼠标点击位置距离canvas左上角的像素值);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const ray = viewer.camera .getPickRay (e.position )const cartesian = viewer.scene .globe .pick (ray, viewer.scene )if (Cesium .defined (cartesian)) { const cartographic = Cesium .Cartographic .fromCartesian (cartesian) const longitudeString = Cesium .Math .toDegrees (cartographic.longitude ) const latitudeString = Cesium .Math .toDegrees (cartographic.latitude ) const heightString = cartographic.height console .log (longitudeString, latitudeString, heightString) }
参考文章: 1.Cesium4种获取鼠标点击位置 2.cesium拾取屏幕上指定点的真实坐标 3.Cesium 拾取 API 完全总结 1.仅拾取椭球体表面坐标;2.拾取带地形高度的地表坐标;3.拾取三维物体的坐标; 4.Cesium的坐标拾取详解 Scene.prototype.pickPosition、Scene.prototype.pick 和 Globe.prototype.pickRay 的准确性受深度缓存影响,所以,在深度检测不开启时,拾取的坐标会不准确。
7.鼠标移动 基本思想:在左键按下的时候,记录鼠标开始位置,和 entity 位置,在鼠标移动的时候,用鼠标当前位置减去鼠标开始位置,得到一个坐标差值,然后将全部的 entity 坐标加上这一个坐标差,得到了最终的坐标位置。 问题:目前存在的问题就是,当鼠标移动距离过大的时候,这个差值计算就会出现偏差,变得越来越大了,导致 entity 虽然跟着鼠标移动,但是位置和鼠标没有相对位置不动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 let pick : any = null ;let leftDownFlag = false ;let startPosition; let topEntityPosition; let bottomEntityPosition; let polylinePreviousCoordinates; const EventListener_MouseLeftDown = (hanlder: any ) => { hanlder.setInputAction ((evt: any ) => { pick = this .viewer .scene .pick (evt.position ); if (!pick?.id ?.properties ?.id ?._value ) return ; console .log (pick, 'pick' ); if (Cesium .defined (pick) && pick.id .id && this .waylineStore .selectedPoint == pick.id .properties .id ._value ) { const ray = this .viewer .camera .getPickRay (evt.position ); startPosition = this .viewer .scene .globe .pick (ray!, this .viewer .scene ); leftDownFlag = true ; this .viewer .scene .screenSpaceCameraController .enableRotate = false ; this .viewer .scene .screenSpaceCameraController .enableZoom = false ; const positionIndex = pick.id .properties .id ._value ; let position = this .wayPoint [positionIndex].topEntity .position ; const time = Cesium .JulianDate .now (); topEntityPosition = position.getValue (time); position = this .wayPoint [positionIndex].bottomEntity .position ; bottomEntityPosition = position.getValue (time); polylinePreviousCoordinates = this .wayPoint [positionIndex].lineEntity .polyline .positions .getValue (); } }, Cesium .ScreenSpaceEventType .LEFT_DOWN ); }; const EventListener_MouseMove = (handler: any ) => { handler.setInputAction ((e: any ) => { if (Cesium .defined (pick) && leftDownFlag) { const ray = this .viewer .camera .getPickRay (e.endPosition ); const endPosition = this .viewer .scene .globe .pick (ray!, this .viewer .scene ); if (startPosition && endPosition) { const changed_x = endPosition.x - startPosition.x ; const changed_y = endPosition.y - startPosition.y ; const changed_z = endPosition.z - startPosition.z ; topEntityPosition.x = topEntityPosition.x + changed_x; topEntityPosition.y = topEntityPosition.y + changed_y; topEntityPosition.z = topEntityPosition.z + changed_z; bottomEntityPosition.x = bottomEntityPosition.x + changed_x; bottomEntityPosition.y = bottomEntityPosition.y + changed_y; bottomEntityPosition.z = bottomEntityPosition.z + changed_z; const positionIndex = pick.id .properties .id ._value ; if (!positionIndex) return ; this .wayPoint [positionIndex].topEntity .position = topEntityPosition; this .wayPoint [positionIndex].bottomEntity .position = bottomEntityPosition; const currentsPoint : any[] = []; for (let i = 0 ; i < polylinePreviousCoordinates.length ; i++) { polylinePreviousCoordinates[i].x = polylinePreviousCoordinates[i].x + changed_x; polylinePreviousCoordinates[i].y = polylinePreviousCoordinates[i].y + changed_y; polylinePreviousCoordinates[i].z = polylinePreviousCoordinates[i].z + changed_z; currentsPoint.push (polylinePreviousCoordinates[i]); } this .wayPoint [positionIndex].lineEntity .polyline .positions = new Cesium .CallbackProperty (function ( ) { return currentsPoint; }, false ); startPosition = endPosition; } } }, Cesium .ScreenSpaceEventType .MOUSE_MOVE ); }; const EventListener_MouseLeftUp = (handler: any ) => { handler.setInputAction ((evt: any ) => { if (leftDownFlag && pick) { leftDownFlag = false ; this .viewer .scene .screenSpaceCameraController .enableRotate = true ; this .viewer .scene .screenSpaceCameraController .enableZoom = true ; } }, Cesium .ScreenSpaceEventType .LEFT_UP ); }; const EventListener_MouseLeftClick = (handler: any ) => { handler.setInputAction ((evt: any ) => { pick = this .viewer .scene .pick (evt.position ); if (!pick?.id ?.properties ?.id ?._value ) return ; const positionIndex = pick.id .properties .id ._value ; this .waylineStore .selectedPoint = positionIndex; }, Cesium .ScreenSpaceEventType .LEFT_CLICK ); }; this .handlerDrag = new ScreenSpaceEventHandler (this .viewer .scene .canvas );EventListener _MouseLeftDown(this .handlerDrag );EventListener _MouseMove(this .handlerDrag );EventListener _MouseLeftUp(this .handlerDrag );EventListener _MouseLeftClick(this .handlerDrag );
参考文章: 【1】.Cesium实现Entity的拖拽功能 这里有多个图形的移动,就是计算差值,然后进行移动 【2】.Cesium 实现拖动点或模型 移动的是选中的模型,需要先点选一下模型,然后再鼠标拖动。如果你想要直接拖动,就需要你再修改一下代码了。 【3】.cesium基础 1.cesium中的几种坐标和相互转换。2.关于贴地;3.Cesium鼠标事件。4.Cesium 中的pick,scene中:pick、drillPick、pickPosition,pick与drillPick的区别:pick只可获取一个entity对象(如该位置存在多个entity,哪怕面点线不在同一高度,面entity 都可能会盖住点线entity),但drillPick可获取当前坐标下的多个对象。5.Cesium的坐标拾取。6.Cesium中的Entity。7.Cesium中Primitive。8.Transforms对象。9.Cesium的Property机制。10.cesium轨迹回放,按路径飞行。 【4】.Scene.globe.pick delivers undefined 【5】.Cesium获取鼠标点击位置(PickPosition)解决viewer.scene.pickPosition(e.position)不准的问题 【6】.屏幕坐标、固定坐标、惯性坐标转换 entity.position = new Cesium.ConstantPositionProperty(position, Cesium.ReferenceFrame.INERTIAL) 【7】.Cesium 拖拽3D模型 1、鼠标按下事件,如果有模型的话,可以给模型设置一个颜色,知道按下选中的是哪个模型。2、然后再监听鼠标拖拽事件,获取鼠标拖拽的位置,赋值给模型。3、鼠标抬起事件,结束鼠标移动事件,然后把颜色改回去。