Cesium隐藏地球
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cesium隐藏地球相关的知识,希望对你有一定的参考价值。
参考技术A 最近需要做三维看板页面,ui给的设计是需要在给定的背景图片下自由操作模型。一开始以为单纯操作地球透明度就可以实现,但只改变透明度会留下黑色地球,发现实际还是需要设置不少参数的。开源三维地球GIS引擎Cesium常用功能的开发
Cesium是一个非常优秀的三维地球GIS引擎(开源且免费)。能够加载各种符合标准的地图图层,瓦片图、矢量图等都支持。支持3DMax等建模软件生成的obj文件,支持通用的GIS计算;支持DEM高程图。测试中的3D-Tiles分支还支持倾斜摄影生成的城市三维建筑群。国内许多三维GIS产品都基于Cesium进行封装(包括一些大厂)。因为工作关系,我对Cesium的一些基本GIS功能进行了研究,特此记录下来。
如上图,这是一个给市政GIS\\BIM管理平台做的原型,GIS部分使用Cesium,BIM部分使用第三方商业引擎。GIS控制宏观、BIM支持微观(现在还没有什么好的引擎能做到GIS\\BIM的无缝切换)。
常用功能介绍:
- 卫星\\矢量地图切换
我这里使用的是天地图提供的服务,卫星地图和矢量地图分别调用不同的接口,卫星地图显示效果如上图,矢量地图显示如下图:
- 道路及基本标注
点“道路及基本标注”后,将路名等显示并加载在原先的图层上
- 加标记点
首先在地图上点击需要加点的位置,然后在弹出框内选取颜色,设置提示文字和显示内容,点击保存;可以添加多个标记。
- 绘制线段
连续点击地图两次就可以绘制线段(可绘制折线)
- 绘制圆形
支持绘制多个圆形,每个圆形随机颜色,能够显示园的半径、面积等
- 绘制多边形
连续点击地图上的点,再右键闭合,就可以绘制多边形,能够计算多边形每一边的边长、总面积等
- 保存视角、跳转视角
保存当前的视角;输入经纬度,跳转到指定位置
- 隐藏、加载模型
可以动态加载、隐藏三维模型(为了便于演示,所有的模型均放大了几百倍);地图上的绘制功能对所有模型都有效,包含在范围内的模型会自动高亮并显示;点选模型能自动居中并提示是否跳转到BIM模型显示(BIM模型也是基于三维WebGL的)
- 搜索
可以根据输入的关键词进行搜索,使用百度或者高德的API,或者使用天地图的API,搜索后进行定位,只是百度、高德、天地图等用的是不同的坐标系,转换非常麻烦。
- 清除绘制
清除所有绘制的部分
以上功能只要再完善下,封装下就可以成为一个很不错的三维GIS项目基础平台了,附我们公司做的GIS+BIM的产品截图,使用了3D-Tiles:)
附:示例程序的js部分代码
1 var bimEngine; var msgControl; var toolbar; var fileControl; var spaceControl; var domainControl; var propertyControl; var searchControl; var markControl; 2 var storeyControl; var roamingControl; var bimevent; 3 4 var viewer = new Cesium.Viewer("cesiumContainer", { 5 animation: false, //是否显示动画控件 6 baseLayerPicker: false, //是否显示图层选择控件 7 geocoder: true, //是否显示地名查找控件 8 timeline: false, //是否显示时间线控件 9 sceneModePicker: true, //是否显示投影方式控件 10 navigationHelpButton: false, //是否显示帮助信息控件 11 infoBox: true, //是否显示点击要素之后显示的信息 12 imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ 13 url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles", 14 layer: "tdtBasicLayer", 15 style: "default", 16 format: "image/jpeg", 17 tileMatrixSetID: "GoogleMapsCompatible", 18 show: false 19 }) 20 }); 21 var scene = viewer.scene; 22 var pinBuilder = new Cesium.PinBuilder(); 23 24 var vecLayer = null, roadLayer = null, electricLayers = null; 25 26 var getEnumPropertyNames = function(obj) { 27 var props = []; 28 for (prop in obj) { 29 props.push(prop + \': \' + obj[prop]); 30 } 31 return props; 32 } 33 34 var models = new Array(); 35 models[0] = { id: \'house1\', name: \'house1\', url: \'../SampleData/house/house1.gltf\', lon: 121.41, lat: 31.22, height: 0, pid: \'4e027d42-f033-4bab-87f1-e34c8860b90e\' }; 36 models[1] = { id: \'house2\', name: \'house2\', url: \'../SampleData/house/house2.gltf\', lon: 121.42, lat: 31.21, height: 0, pid: \'918dcfaa-4568-4468-ba03-e379deaa99b7\' }; 37 models[2] = { id: \'house3\', name: \'house3\', url: \'../SampleData/house/house3.gltf\', lon: 121.43, lat: 31.20, height: 0, pid: \'2071736b-0054-4041-ad34-34f2e7a975e5\' }; 38 models[3] = { id: \'house4\', name: \'house4\', url: \'../SampleData/house/house4.gltf\', lon: 121.44, lat: 31.22, height: 0, pid: \'4e027d42-f033-4bab-87f1-e34c8860b90e\' }; 39 models[4] = { id: \'house5\', name: \'house5\', url: \'../SampleData/house/house5.gltf\', lon: 121.41, lat: 31.21, height: 0, pid: \'918dcfaa-4568-4468-ba03-e379deaa99b7\' }; 40 models[5] = { id: \'house6\', name: \'house6\', url: \'../SampleData/house/house6.gltf\', lon: 121.42, lat: 31.20, height: 0, pid: \'2071736b-0054-4041-ad34-34f2e7a975e5\' }; 41 models[6] = { id: \'house7\', name: \'house7\', url: \'../SampleData/house/house7.gltf\', lon: 121.43, lat: 31.22, height: 0, pid: \'4e027d42-f033-4bab-87f1-e34c8860b90e\' }; 42 models[7] = { id: \'house8\', name: \'house8\', url: \'../SampleData/house/house8.gltf\', lon: 121.44, lat: 31.21, height: 0, pid: \'918dcfaa-4568-4468-ba03-e379deaa99b7\' }; 43 models[8] = { id: \'house9\', name: \'house9\', url: \'../SampleData/house/house9.gltf\', lon: 121.45, lat: 31.20, height: 0, pid: \'2071736b-0054-4041-ad34-34f2e7a975e5\' }; 44 models[9] = { id: \'house10\', name: \'house10\', url: \'../SampleData/house/house10.gltf\', lon: 121.46, lat: 31.21, height: 0, pid: \'918dcfaa-4568-4468-ba03-e379deaa99b7\' }; 45 models[10] = { id: \'house11\', name: \'house11\', url: \'../SampleData/house/house11.gltf\', lon: 121.40, lat: 31.20, height: 0, pid: \'4e027d42-f033-4bab-87f1-e34c8860b90e\' }; 46 models[11] = { id: \'villa\', name: \'villa\', url: \'../SampleData/house3/house3.gltf\', lon: 121.45, lat: 31.22, height: 0, pid: \'2071736b-0054-4041-ad34-34f2e7a975e5\' }; 47 48 var loadedModels = []; 49 50 var shapes = new Array(); 51 shapes[0] = { layer: \'测试层\', author: \'liu\', date: \'2017-06-18\', ploy: [ 52 { name: \'A区\', type: \'ploy\', points: [] } 53 ]}; 54 55 var tempPoints = []; 56 var tempEntities = []; 57 var tempPinEntities = []; 58 var tempPinLon, tempPinLat; 59 60 var handler = null; 61 62 $(function() { 63 64 /**初始化**/ 65 $("input[name=\'optionsRadios\']").click(function() { 66 if ($("input[name=\'optionsRadios\']:eq(1)").prop("checked")) { 67 //viewer.imageryLayers.addImageryProvider(vecLayer); 68 vecLayer = viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({ 69 url: "http://t0.tianditu.com/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles", 70 layer: "tdtVecBasicLayer", 71 style: "default", 72 format: "image/jpeg", 73 tileMatrixSetID: "GoogleMapsCompatible", 74 show: false 75 })); 76 } else if ($("input[name=\'optionsRadios\']:eq(0)").prop("checked")) { 77 if (viewer.imageryLayers.contains(vecLayer)) { 78 viewer.imageryLayers.remove(vecLayer); 79 } 80 } 81 }); 82 //标记层 83 $("#cbxPinLayer").change(function() { 84 if ($("#cbxPinLayer").prop("checked")) { 85 for (var i = 0; i < tempPinEntities.length; i++) { 86 viewer.entities.add(tempPinEntities[i]); 87 } 88 89 } else { 90 for (var i = 0; i < tempPinEntities.length; i ++) { 91 viewer.entities.remove(tempPinEntities[i]); 92 } 93 } 94 }); 95 $("#pinColor").change(function() { 96 $(this).css("background-color", $(this).val()); 97 }); 98 99 $("#cbxRoad").click(function() { 100 if ($(this).prop("checked")) { 101 roadLayer = viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({ 102 url: "http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles", 103 layer: "tdtImgAnnoLayer", 104 style: "default", 105 format: "image/jpeg", 106 tileMatrixSetID: "GoogleMapsCompatible", 107 show: false 108 })); 109 } else { 110 viewer.imageryLayers.remove(roadLayer); 111 } 112 }); 113 $("#cbxTestArc").click(function() { 114 if ($(this).prop("checked")) { 115 electricLayers = viewer.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({ 116 url: \'https://nationalmap.gov.au/proxy/http://services.ga.gov.au/site_3/rest/services/Electricity_Infrastructure/MapServer\' 117 })); 118 viewer.camera.flyTo({ 119 destination: Cesium.Rectangle.fromDegrees(114.591, -45.837, 148.970, -5.730) 120 }); 121 } else { 122 viewer.imageryLayers.remove(electricLayers); 123 } 124 }); 125 $("#opts .btn").click(function () { 126 window.setTimeout(function() { 127 if ($("input[name=\'opt\']:eq(0)").prop("checked")) { 128 clearEffects(); 129 setTips(""); 130 } 131 else if ($("input[name=\'opt\']:eq(1)").prop("checked")) { 132 clearEffects(); 133 SetMode("addPin"); 134 setTips("首先在地图上点击需要加点的位置,然后在弹出框内选取颜色,设置提示文字和显示内容,点击保存"); 135 } 136 else if ($("input[name=\'opt\']:eq(2)").prop("checked")) { 137 tempPoints = []; 138 for (var i = 0; i < tempEntities.length; i++) { 139 viewer.entities.remove(tempEntities[i]); 140 } 141 for (var i = 0; i < loadedModels.length; i++) { 142 if (loadedModels[i].color == Cesium.Color.SPRINGGREEN) { 143 loadedModels[i].color = {red:1,green:1, blue:1, alpha:1}; 144 } 145 } 146 clearEffects(); 147 setTips("绘制的图形被清除,点选页面标记可以删除标记"); 148 SetMode("erase"); 149 } 150 else if ($("input[name=\'opt\']:eq(3)").prop("checked")) { 151 clearEffects(); 152 SetMode("drawLine"); 153 setTips("在地图上分别点击,即可绘制多个线段,点右键结束绘制"); 154 } 155 else if ($("input[name=\'opt\']:eq(4)").prop("checked")) { 156 clearEffects(); 157 SetMode("drawCircle"); 158 setTips("第一次点击绘制圆心,第二次点击根据和圆心的位置绘制半径"); 159 } 160 else if ($("input[name=\'opt\']:eq(5)").prop("checked")) { 161 clearEffects(); 162 SetMode("drawSquare"); 163 setTips("第一、二次点击绘制长方形的一个边,再次点击根据点和边的距离绘制方形"); 164 } 165 else if ($("input[name=\'opt\']:eq(6)").prop("checked")) { 166 clearEffects(); 167 SetMode("drawPloy"); 168 setTips("如果需要绘制多边形,在地图上使用左键逐个点选地点,右击闭合多边形"); 169 } 170 else if ($("input[name=\'opt\']:eq(7)").prop("checked")) { 171 clearEffects(); 172 SetMode("pickBuilding"); 173 setTips("点选建筑查看详细的三维模型"); 174 } 175 },100); 176 }); 177 178 var homeView = { 179 destination: new Cesium.Cartesian3(-2852877.756667368, 4655857.919027944, 3288673.682311567), 180 orientation: { 181 direction: new Cesium.Cartesian3(0.5437275903005284, -0.8386290220423197, -0.03258329225728158), 182 up: new Cesium.Cartesian3(0.05520718287689969, -0.00299987805272847, 0.9984704140286108) 183 }, 184 complete: function() { LoadModel(); }, 185 }; 186 187 setTimeout( 188 function() { 189 // scene.primitives.removeAll(); 190 //reset(); 191 viewer.camera.flyTo(homeView); 192 193 //viewer.zoomTo(wyoming); 194 }, 3000); 195 196 //var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( 197 //Cesium.Cartesian3.fromDegrees(121.49, 31.22, 0.0)); 198 //var model = scene.primitives.add(Cesium.Model.fromGltf({ 199 // url: \'../SampleData/house/house1.gltf\', 200 // modelMatrix: modelMatrix, 201 // scale: 20.0, 202 // name: \'SampleHouse\', 203 // color: getColor(\'Red\', 1) 204 //})); 205 206 $("#poly-show").click(function () { 207 LoadModel(); 208 }); 209 210 $("#poly-hide").click(function () { 211 HideModel(); 212 }); 213 214 //alert(getEnumPropertyNames(model).join(\'\\r\')); 215 216 }); 217 218 function LoadModel() { 219 for (var i = 0; i < models.length; i++) { 220 var hasLoaded = false; 221 for (var j = 0; j < loadedModels.length; j ++) { 222 if (models[i].id == loadedModels[j].id) { 223 hasLoaded = true; 224 } 225 } 226 if (!hasLoaded) { 227 var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( 228 Cesium.Cartesian3.fromDegrees(models[i].lon, models[i].lat, models[i].height)); 229 230 var model = scene.primitives.add( 231 Cesium.Model.fromGltf({ 232 url: models[i].url, 233 modelMatrix: modelMatrix, 234 scale: 20.0, 235 name: models[i].name, 236 id: models[i].id 237 })); 238 loadedModels.push(model); 239 } 240 } 241 //var cartesian = viewer.camera.pickEllipsoid(loadedModels[0].modelMatrix, scene.globe.ellipsoid); 242 //alert(getEnumPropertyNames(cartesian).join(\'\\r\')); 243 244 } 245 246 function HideModel() { 247 for (var i = 0; i < loadedModels.length; i++) { 248 scene.primitives.remove(loadedModels[i]); 249 } 250 loadedModels = []; 251 } 252 253 function setTips(message, close) { 254 if ("" == message) { 255 $("#message").fadeOut(); 256 } else { 257 if (close != undefined && close == true) { 258 $("#message").html(message).fadeOut(); 259 } else { 260 $("#message").html(message).fadeIn(); 261 } 262 } 263 } 264 265 function clearEffects() { 266 if (handler != null) { 267 handler.destroy(); 268 } 269 } 270 271 //设置各种操作模式 272 function SetMode(mode) { 273 if (mode == "drawPloy") 274 { 275 tempPoints = []; 276 handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); 277 handler.setInputAction(function (click) { 278 var cartesian = viewer.camera.pickEllipsoid(click.position, scene.globe.ellipsoid); 279 if (cartesian) { 280 var cartographic = Cesium.Cartographic.fromCartesian(cartesian); 281 var longitudeString = Cesium.Math.toDegrees(cartographic.longitude); 282 var latitudeString = Cesium.Math.toDegrees(cartographic.latitude); 283 tempPoints.push({ lon: longitudeString, lat: latitudeString }); 284 var tempLength = tempPoints.length; 285 drawPoint(tempPoints[tempPoints.length-1]); 286 if (tempLength > 1) { 287 drawLine(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1], true); 288 } 289 } 290 }, Cesium.ScreenSpaceEventType.LEFT_CLICK); 291 292 handler.setInputAction(function (click) { 293 var cartesian = viewer.camera.pickEllipsoid(click.position, scene.globe.ellipsoid); 294 if (cartesian) { 295 var tempLength = tempPoints.length; 296 if (tempLength < 3) { 297 alert(\'请选择3个以上的点再执行闭合操作命令\'); 298 } else { 299 drawLine(tempPoints[0], tempPoints[tempPoints.length - 1], true); 300 drawPoly(tempPoints); 301 highLightAssetsInArea(tempPoints); 302 alert(\'多边形面积\' + SphericalPolygonAreaMeters(tempPoints) + \'平方米\'); 303 tempPoints = []; 304 } 305 306 } 307 }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); 308 } 309 else if (mode == "pickBuilding") 310 { 311 handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); 312 handler.setInputAction(function(click) { 313 var pick = scene.pick(click.position); 314 if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) { 315 for (var i = 0; i < models.length; i ++) { 316 if (models[i].id == pick.node._model.id) { 317 var modelName = models[i].name; 318 var modelId = models[i].id; 319 var modelBimId = models[i].pid; 320 highLigthModel(modelId); 321 viewer.camera.flyTo({ 322 destination: Cesium.Cartesian3.fromDegrees(models[i].lon, parseFloat(models[i].lat) - 0.01, 2000.0), 323 orientation: { 324 direction: new Cesium.Cartesian3(0.5437275903005284, -0.8386290220423197, -0.03258329225728158), 325 up: new Cesium.Cartesian3(0.05520718287689969, -0.00299987805272847, 0.9984704140286108) 326 }, 327 complete: function() { 328 if (confirm("你选择的是" + modelName + ",是否查看详细模型?")) { 329 LoadBim(modelBimId); 330 } 331 unHighLightModel(modelId); 332 }, 333 }); 334 } 335 } 336 } 337 }, Cesium.ScreenSpaceEventType.LEFT_CLICK); 338 } 339 else if ("addPin" == mode) 340 { 341 handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); 342 handler.setInputAction(function (click) { 343 var cartesian = viewer.camera.pickEllipsoid(click.position, scene.globe.ellipsoid); 344 if (cartesian) { 345 var cartographic = Cesium.Cartographic.fromCartesian(cartesian); 346以上是关于Cesium隐藏地球的主要内容,如果未能解决你的问题,请参考以下文章